Module: Karst::Mcp::Server

Defined in:
lib/karst/mcp/server.rb

Overview

Builds and runs Karst's stdio MCP server: one tool (VerifyAccessTool), no prompts, no resources, no other transport. The host Rails application must already be booted (see Rails::Command::Karst::Boot#boot_karst_application!, used by bin/rails karst:mcp) before this is built -- the server itself never boots or reboots the application, so one process serves every tool call for its lifetime against the one already-running application.

Constant Summary collapse

INSTRUCTIONS =
<<~TEXT.strip
  Karst verifies bounded runtime access to local paths in this Rails application.

  Agent proposes: a hypothesis about who can reach a path.
  Karst proves: it executes the real application, under real existing
  identities, and reports observed evidence -- HTTP status, redirect,
  halted callback, exception, and whether a usable outcome was found.

  Call verify_access(path:, method:) to check one path. Karst does not
  infer authorization rules, explain application code, or choose which
  principal to try on your behalf -- it only reports what actually
  happened when a real request was made under the application's own
  configured identities.
TEXT

Class Method Summary collapse

Class Method Details

.buildObject



33
34
35
36
37
38
39
40
41
42
# File 'lib/karst/mcp/server.rb', line 33

def build
  MCP::Server.new(
    name: "karst",
    title: "Karst",
    version: Karst::VERSION,
    instructions: INSTRUCTIONS,
    tools: [VerifyAccessTool],
    configuration: MCP::Configuration.new(exception_reporter: method(:report_exception))
  )
end

.run!Object

Runs until the client closes stdin (or the process receives SIGINT). stdout is reserved for MCP protocol frames; anything Karst or the host application needs to say for local debugging goes to stderr instead, matching how rails server/rails console behave.



48
49
50
51
52
53
# File 'lib/karst/mcp/server.rb', line 48

def run!
  server = build
  transport = MCP::Server::Transports::StdioTransport.new(server)
  server.transport = transport
  transport.open
end