mcp

package
v0.0.0-...-99cc010 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package mcp implements a Model Context Protocol server that exposes Locorum's daemon as a curated set of tools to local AI agents.

Locorum's MCP server is a thin shim: every tool call is forwarded to the daemon over the IPC socket. The daemon enforces the security boundary (per-site mutex, profile gating, scope checks). This package owns the protocol surface and the tool catalogue.

MCP (https://spec.modelcontextprotocol.io) is JSON-RPC 2.0 over either stdio (one frame per line) or Streamable HTTP. Locorum ships stdio first; HTTP is a follow-on (see AGENTS-SUPPORT.md P2).

Index

Constants

View Source
const MCPProtocolVersion = "2024-11-05"

MCPProtocolVersion is the version we declare in the initialize response. Negotiated against the client's claimed version; we accept any version for now and just echo back our own.

View Source
const ServerName = "locorum"

ServerName is the user-visible name reported in initialize. Pinned so MCP clients (Claude Code, Cursor, Continue) can recognise the server in their config UIs.

View Source
const TokenByteLen = 32

TokenByteLen is the size of the random source for an MCP HTTP auth token, before base64-encoding. 32 bytes (256 bits) gives a 43-char URL-safe string — well above the brute-force horizon for any local-network attacker.

View Source
const TokenFilename = "mcp_token"

TokenFilename is the basename of the auth token file under ~/.locorum/state/. The full path is built by TokenPath.

Variables

This section is empty.

Functions

func CompareTokens

func CompareTokens(a, b string) bool

CompareTokens performs a constant-time comparison so a length-leak or timing-leak doesn't reveal token characters to an attacker. The strings package's == would be timing-leaky.

func LoadOrCreateToken

func LoadOrCreateToken(homeDir string) (string, error)

LoadOrCreateToken returns the auth token, creating a new random one on first use. The file is written 0600 so peer users on the host cannot lift the token from disk. Idempotent across processes — the HTTP server reads the same value the user pastes into their MCP client.

func RotateToken

func RotateToken(homeDir string) (string, error)

RotateToken regenerates the token, replacing whatever was there. The old token stops working immediately; existing MCP clients must pick up the new value from disk (or be re-pasted into the IDE config).

func TokenPath

func TokenPath(homeDir string) string

TokenPath returns the absolute path to the MCP token file under homeDir. Sits next to owner.lock + locorum.sock in ~/.locorum/state/, which is already 0700 owner-only.

Types

type HTTPOptions

type HTTPOptions struct {
	Bind   string
	Token  string
	Server *Server // typically constructed via NewServer with stdio I/O wired to nil
	Logger *slog.Logger
}

HTTPOptions configures the HTTP server. Bind is the listen address (e.g. "127.0.0.1:2484"); Token is the bearer secret clients send in `Authorization: Bearer <token>`.

type HTTPServer

type HTTPServer struct {
	// contains filtered or unexported fields
}

HTTPServer is the HTTP frontend for an existing daemon client. One goroutine handles the listen + accept loop; per-request dispatch is stateless so the http.Handler is goroutine-safe by construction.

func NewHTTPServer

func NewHTTPServer(opts HTTPOptions) (*HTTPServer, error)

NewHTTPServer wires an HTTP listener around the existing dispatch engine. The caller must have already initialised opts.Server with a daemon Client; we don't second-guess the trust profile.

Refuses non-loopback binds unless the caller explicitly asks for one by passing a pre-resolved IP — we only check the literal Bind string against a safe-list. The CLI shows a clear error before reaching this point so the message reads naturally.

func (*HTTPServer) Addr

func (h *HTTPServer) Addr() string

Addr returns the bound listen address. Useful in tests that pass :0 to pick a free port.

func (*HTTPServer) Serve

func (h *HTTPServer) Serve(ctx context.Context) error

Serve binds the listener and serves requests until ctx cancels or Shutdown is called.

func (*HTTPServer) ServeHTTP

func (h *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP is the http.Handler entry point — delegates to the mux. Defined explicitly so the type satisfies http.Handler with a custom error / log path.

func (*HTTPServer) Shutdown

func (h *HTTPServer) Shutdown() error

Shutdown stops accepting new connections and waits up to 5s for in-flight requests to finish.

type Options

type Options struct {
	In      io.Reader // defaults to os.Stdin
	Out     io.Writer // defaults to os.Stdout
	Client  *daemon.Client
	Logger  *slog.Logger
	Scope   string // optional MCP scope (LOCORUM_MCP_SCOPE)
	Profile string // "full" or "readonly"
	Version string // locorum binary version
}

Options configures a new MCP server.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the MCP stdio server. Constructed once per process; the caller wires stdin/stdout and a daemon client, then calls Serve.

Server is safe to use from a single goroutine only. MCP stdio is one-frame-at-a-time, no pipelining required by the spec.

func NewServer

func NewServer(opts Options) *Server

NewServer constructs a Server. The caller is responsible for opening the daemon client and passing it in: this package never auto-spawns a daemon (the parent process — `locorum mcp serve` — does that before instantiating us).

func (*Server) Serve

func (s *Server) Serve(ctx context.Context) error

Serve runs the read/dispatch loop until stdin closes or ctx cancels. Returns nil on a clean stdin close; other errors are propagated.

func (*Server) SetCoreInOut

func (s *Server) SetCoreInOut(in io.Reader, out io.Writer)

SetCoreInOut lets the HTTP harness swap the underlying server's streams in tests. Unused outside the test binary; defined here so the test file doesn't need to reach into unexported fields.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL