Class: Textus::Surface::MCP::Server
- Inherits:
-
Object
- Object
- Textus::Surface::MCP::Server
- Defined in:
- lib/textus/surface/mcp/server.rb
Overview
MCP stdio server backed by the official mcp gem. The SDK owns protocol negotiation, tool dispatch, and JSON-RPC framing. This class owns the textus Session lifecycle (built lazily on first tool call) and delegates execution to Catalog.
Instance Method Summary collapse
- #dispatch(verb_name, args, _server_context) ⇒ Object
-
#initialize(store:, role: Textus::Value::Role::DEFAULT, stdin: $stdin, stdout: $stdout) ⇒ Server
constructor
A new instance of Server.
- #run ⇒ Object
Constructor Details
#initialize(store:, role: Textus::Value::Role::DEFAULT, stdin: $stdin, stdout: $stdout) ⇒ Server
Returns a new instance of Server.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/textus/surface/mcp/server.rb', line 13 def initialize(store:, role: Textus::Value::Role::DEFAULT, stdin: $stdin, stdout: $stdout) @store = store.with_role(role) @stdin = stdin @stdout = stdout @sdk = ::MCP::Server.new( name: "textus", version: Textus::VERSION, tools: Catalog.build_tools(self), resources: build_resources, server_context: { mcp_server: self }, ) @sdk.resources_read_handler { |params, server_context:| handle_resource_read(params[:uri].to_s, server_context) } end |
Instance Method Details
#dispatch(verb_name, args, _server_context) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/textus/surface/mcp/server.rb', line 41 def dispatch(verb_name, args, _server_context) str_args = deep_stringify_keys(args) @store.check_etag!(contract_etag_now) unless Catalog.read_verbs.include?(verb_name.to_s) result = Catalog.call(verb_name.to_s, store: @store, args: str_args) @store = @store.advance_cursor(@store.audit_log.latest_seq) if verb_name == :pulse @store = @store.with_role(@store.role) if verb_name == :boot ::MCP::Tool::Response.new([{ type: "text", text: JSON.dump(result) }]) rescue Textus::ContractDrift => e raise_handler_error(e., Textus::ContractDrift::JSONRPC_CODE) rescue Textus::CursorExpired => e raise_handler_error(e., Textus::CursorExpired::JSONRPC_CODE) rescue Textus::Surface::MCP::ToolError => e raise_handler_error(e., ToolError::JSONRPC_CODE) rescue StandardError => e raise_handler_error("internal: #{e.}", -32_603) end |
#run ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/textus/surface/mcp/server.rb', line 28 def run @stdin.each_line do |line| line = line.strip next if line.empty? response = @sdk.handle_json(line) next unless response @stdout.puts(response) @stdout.flush end end |