Documentation
¶
Overview ¶
Package mcpclient implements an MCP client that connects to external MCP servers over stdio. This allows odek to use tools from any MCP server (e.g., Claude Code's MCP servers for web scraping, databases, APIs, etc.) alongside its built-in tools.
Protocol: JSON-RPC 2.0 over stdin/stdout
- initialize — protocol handshake
- tools/list — discover available tools
- tools/call — invoke a tool
- ping — health check
Usage:
client, err := mcpclient.New("some-server", "node", []string{"server.js"})
tools, err := client.Discover(ctx)
result, err := client.CallTool(ctx, "tool_name", `{"arg":"val"}`)
client.Close()
Config in odek.json:
{
"mcp_servers": {
"my-server": {
"command": "node",
"args": ["/path/to/server.js"]
}
}
}
Extension contract constants for the odek generic extension surface.
This file is purely additive: it introduces the versioned contract under which third-party MCP servers can interoperate with odek, without changing any existing client behavior. The full normative specification lives in docs/EXTENSIONS.md.
Compatibility rule: all schemas below are additive. Producers may add new fields in future contract versions; consumers MUST ignore fields they do not recognize rather than failing.
Index ¶
Constants ¶
const ( ProtocolVersion = "2025-03-26" // MaxResponseBytesCeiling is the absolute ceiling for // ServerConfig.MaxResponseBytes. No configuration may raise the response // cap above this value; attempting to do so is an error. MaxResponseBytesCeiling = 64 << 20 // 64 MiB // MaxTimeoutSeconds is the hard cap for ServerConfig.TimeoutSeconds. // Values above it are clamped to this cap with a warning. MaxTimeoutSeconds = 3600 // DefaultMaxResultChars is the default cap on tool result text forwarded // to the model. Oversized (but valid) results receive a structured // truncation notice instead of being silently cut. DefaultMaxResultChars = 200000 // MaxResultCharsCap is the hard cap for ServerConfig.MaxResultChars. // Values above it are clamped to this cap with a warning. MaxResultCharsCap = 1000000 )
const ( // SchemaToolResult names the odek tool-result envelope. An MCP tool may // return this envelope (as a JSON text content item) to attach // out-of-band artifact references to an otherwise compact text result. SchemaToolResult = artifact.SchemaToolResult // SchemaArtifactRef names a single artifact reference inside a // tool-result envelope. An artifact ref points at a file produced by the // tool (e.g. a full log-analysis report) that is intentionally NOT // inlined into the model context. SchemaArtifactRef = artifact.SchemaArtifactRef // SchemaEvent names one structured runtime event, emitted as a single // JSON object per line on an event stream (JSONL). SchemaEvent = "odek.event/v1" )
Schema names carried in the "schema" field of structured payloads so consumers can detect and version-check them. The tool-result envelope and artifact-ref schema names are aliased from internal/artifact (the canonical definition and parser/validator live there) so the contract has a single source of truth.
const ExtensionContractVersion = "odek-extension/v1"
ExtensionContractVersion identifies the version of the odek extension contract implemented by this package. Extension servers and odek itself use this string to negotiate/document which schema set they speak.
Variables ¶
var DefaultTimeout = 30 * time.Second
DefaultTimeout bounds each MCP request when neither the caller nor the server config supplies a deadline. It is a var so tests can temporarily lower it. Per-server config never mutates this global; it is only read as the default value source.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client manages a connection to an external MCP server over stdio.
func New ¶
func New(name string, cfg ServerConfig) (*Client, error)
New spawns an MCP server process and returns a client connected to it. The server process is started immediately and cleaned up on Close().
func (*Client) ArtifactRoots ¶ added in v1.24.0
ArtifactRoots returns the configured artifact roots for this server. Empty means every artifact ref from this server must be rejected (fail closed). Validation against these roots is performed by the artifact subsystem.
func (*Client) CallTool ¶
CallTool invokes a tool on the MCP server with the given JSON arguments and returns the text content of the result.
func (*Client) Close ¶
Close terminates the MCP server process and cleans up resources. Safe to call multiple times.
type ServerConfig ¶
type ServerConfig struct {
// Command is the executable to run (e.g., "node", "python3", "uvx").
Command string `json:"command"`
// Args are the command-line arguments.
Args []string `json:"args,omitempty"`
// Env overrides environment variables for the subprocess.
// Empty strings remove the variable from the environment.
Env map[string]string `json:"env,omitempty"`
// TimeoutSeconds bounds each request to this server when the caller does
// not supply a deadline. Zero uses DefaultTimeout (30s). Values above
// MaxTimeoutSeconds (3600) are clamped to the cap with a warning.
TimeoutSeconds int `json:"timeout_seconds,omitempty"`
// MaxResponseBytes caps the size of a single JSON-RPC response line from
// this server. Zero uses the 10 MiB default. The absolute ceiling is
// MaxResponseBytesCeiling (64 MiB); exceeding it is an error.
MaxResponseBytes int64 `json:"max_response_bytes,omitempty"`
// MaxResultChars caps the tool result text forwarded to the model. Zero
// uses DefaultMaxResultChars (200000). Values above MaxResultCharsCap
// (1000000) are clamped to the cap with a warning. Valid-but-oversized
// results get a structured truncation notice (artifact refs retained),
// never a silent cut.
MaxResultChars int `json:"max_result_chars,omitempty"`
// ArtifactRoots lists directories under which file:// artifact refs from
// this server are accepted. Empty means every artifact ref is rejected
// (fail closed). Refs in odek.tool-result/v1 envelopes are validated
// against these roots by the artifact subsystem (internal/artifact)
// before the result is rendered for the model.
ArtifactRoots []string `json:"artifact_roots,omitempty"`
// AutoApprove marks the server as trusted by the operator: it skips the
// project-server approval prompt and the per-tool registration prompts
// (schema guard scans still apply). TRUST RULES: the flag is honored
// only when it comes from the operator-owned global config
// (~/.odek/config.json) — either on a global server entry or as a
// command-less trust marker for a project-defined server name. The
// config loader strips auto_approve from project ./odek.json with a
// warning: a cloned repo must never be able to approve its own MCP
// servers. Trust metadata only — deliberately excluded from approval
// keys, which hash execution-relevant fields.
AutoApprove bool `json:"auto_approve,omitempty"`
}
ServerConfig defines an external MCP server to connect to. Matches the Claude Code MCP server config format, extended with the odek-extension/v1 timeout/limit fields (see docs/EXTENSIONS.md).
type ToolAdapter ¶
type ToolAdapter struct {
// Client is the MCP client connection.
Client *Client
// ToolName is the name of the tool on the MCP server.
ToolName string
// Desc is the tool description.
Desc string
// ParamSchema is the JSON schema for the tool's parameters.
ParamSchema any
}
ToolAdapter wraps an MCP client tool as a odek.Tool-compatible value. It implements the Name(), Description(), Schema(), and Call() methods that odek's agent loop expects, forwarding calls to the MCP server.
func (*ToolAdapter) Call ¶
func (a *ToolAdapter) Call(args string) (string, error)
Call invokes the tool on the MCP server with the given JSON arguments.
func (*ToolAdapter) Description ¶
func (a *ToolAdapter) Description() string
Description returns the tool's description.
func (*ToolAdapter) Name ¶
func (a *ToolAdapter) Name() string
Name returns the tool's name, prefixed with the server name to avoid collisions when multiple MCP servers expose tools with the same name.
func (*ToolAdapter) Schema ¶
func (a *ToolAdapter) Schema() any
Schema returns the tool's input JSON schema.