The mcp command tree¶
gitlab.com/phpboyscout/go/mcp/cli builds the mcp command a Cobra application
mounts to serve itself. The spellings are ophis's, so scripts and editor entries
written for it keep working.
root.AddCommand(mcpcli.Command(
mcpcli.WithBinding(mcpcobra.WithExposure(isExposed)),
mcpcli.WithServer(server.WithIdentity("my-tool", version)),
mcpcli.WithLogLevel(levelVar),
))
The tree is stamped cobra.Omit, so it never publishes itself. A serving
command binds the completed root when it runs, which is after every command is
registered.
Commands¶
| Command | Does |
|---|---|
mcp start [--log-level L] |
Serves on stdin/stdout. Logs go to stderr. Exits when stdin closes. |
mcp stream [--host H] [--port P] [--origin O]... [--log-level L] |
Serves Streamable HTTP on H:P (default all interfaces, 8080) under a controls controller tied to the command context. |
mcp tools [--output F] [--log-level L] |
Writes the full authorised catalogue to F (default mcp-tools.json in the working directory). |
mcp claude enable\|disable\|list |
Manages the entry in Claude Desktop's claude_desktop_config.json (mcpServers). |
mcp cursor enable\|disable\|list [--workspace] |
Manages ~/.cursor/mcp.json, or .cursor/mcp.json with --workspace (mcpServers, typed stdio). |
mcp vscode enable\|disable\|list [--workspace] |
Manages VS Code's user mcp.json, or .vscode/mcp.json with --workspace (servers, typed stdio). |
On Linux, XDG_CONFIG_HOME overrides the configuration directory these paths
start from; macOS and Windows ignore it and use their own conventions.
Every helper takes --config-path to name the file and --server-name to name
the entry (default: the root command's name, or WithServerName). enable
also takes --log-level, appended to the entry's arguments, and --env
KEY=value (repeatable).
What enable writes¶
{
"servers": {
"my-tool": {
"type": "stdio",
"command": "/absolute/path/to/my-tool",
"args": ["mcp", "start", "--log-level", "debug"],
"env": {"A": "1"}
}
}
}
The executable is this binary's absolute path and the arguments are the mcp
command's real path in the tree followed by start. Every other key in the file
is preserved as JSON (the file is re-indented); running enable again replaces
this entry only; disable removes it and is not an error when it is absent. A
file that is not a JSON object, or whose servers key is not an object, is
refused untouched rather than repaired. Writes are atomic.
The export¶
mcp tools reads the binding's operations directly and writes every one of
them: the set an AllowRegistered registry publishes, which is the policy the
command tree uses. It does not run the registry's search or inspection, and it
does not consult any other policy, so a tool that mounts the binding under a
stricter policy of its own exports more than that policy would show a client.
Each entry carries name, title, description, inputSchema,
outputSchema and annotations in the shape ophis's export used. It is an
offline export: the compact wire mode still publishes the three discovery tools.
stream¶
The HTTP host is the transport module's server registered with a controls
controller, and the MCP server and binding are registered beside it with a
StopErr and a Status, so one shutdown budget covers the protocol drain and
the subprocess cleanup and unresolved cleanup stays visible. When either half
fails to release within the budget, both errors are reported together. Interrupt or
terminate the process (the CLI owns its signals; the controller installs none)
and it stops within the budget. The write timeout is disabled because SSE
responses stay open for the life of a call.
MCP's Origin rule is applied by the server's cross-origin protection: a request
with no Origin header (a non-browser client) passes; a browser origin passes
only when it is the server's own or listed with --origin (or
WithTrustedOrigins); anything else is refused with 403 before the protocol
sees it.
Options¶
| Option | Purpose |
|---|---|
WithBinding(opts...) |
Options for the Cobra binding: exposure, flag filter, codecs, limits, group. |
WithServer(opts...) |
Options for the protocol server: mode, identity, resources, Apps. |
WithLogLevel(*slog.LevelVar) |
The variable --log-level sets, so a host's own logging follows. |
WithLogger(*slog.Logger) |
Replaces the default stderr text logger. Never stdout on the stdio transport. |
WithShutdownBudget(d) |
Drain and cleanup budget on exit (default 10s). |
WithServerName(name) |
The entry name the editor helpers write. |
WithTrustedOrigins(origins...) |
Browser origins stream trusts in addition to --origin. |