Documentation
¶
Overview ¶
Package runtime provides the hand-written runtime substrate for the auto-generated MCP tool registrations under mcp/tools.
Index ¶
- Variables
- func AnyInputSchema[T any]() *jsonschema.Schema
- func AuthzMiddleware(authz *Authz) mcp.Middleware
- func BuildServer(cfg Config, registrar Registrar) *mcp.Server
- func HTTPAuditHeaders(next http.Handler) http.Handler
- func HTTPAuthContext(next http.Handler, authz *Authz) http.Handler
- func HTTPLogID(next http.Handler) http.Handler
- func InitAuditConfig(path string)
- func InitLogConfig(path string)
- func InitSpillConfig(path string)
- func InitSpillStore(ctx context.Context, dir string, ttl spillTTLConfig)
- func LogIDFromContext(ctx context.Context) string
- func LoggingMiddleware() mcp.Middleware
- func MCPHandler(cfg Config, s *mcp.Server) (http.Handler, error)
- func MaybeSpill(toolName string, raw any, structured any) (*mcp.CallToolResult, any, error)
- func NewAuthzHandler(s *mcp.Server, authz *Authz) http.Handler
- func NewOwnedSpillID() string
- func NewSpillID() string
- func NewSpillIDForOwnerTest(hostPort string) string
- func OwnerOf(id string) (hostPort string, ok bool)
- func RegisterMeta(m ToolMeta)
- func RegisterOwnerRouted(toolName, paramName string)
- func RegisterSpillResource(s *mcp.Server)
- func ResolveSpillPath(id string) (string, bool)
- func Run(ctx context.Context, cfg Config, registrar Registrar) error
- func RunShutdownHooks()
- func SetAuditHeaders(names []string)
- func SetAuditLogger(l Logger)
- func SetLogIDHeader(name string)
- func SetSpillBaseURL(base string)
- func SetSpillPeer(token string, timeoutMS int)
- func SetSpillPeerProvider(fn func() []string)
- func SetSpillPeers(hosts []string)
- func SetSpillThreshold(tokens int)
- func SpillDir() string
- func SpillDirForTest() string
- func SpillDownloadHandler() http.Handler
- func SpillDownloadURLFor(id string) string
- func SpillHandler() http.Handler
- func SpillPeerAllowed(hostPort string) bool
- func SpillPeerTimeout() time.Duration
- func SpillPeerToken() string
- func SpillResult(toolName string, out any) (*mcp.CallToolResult, error)
- func SpillSelfHostPort() string
- func ToolError(err error) *mcp.CallToolResult
- func WithAuthContext(ctx context.Context, ac AuthContext) context.Context
- func WithLogID(ctx context.Context, id string) context.Context
- func WithOwnerRouting(next http.Handler) http.Handler
- type AuditConfig
- type AuthContext
- type Authz
- type AuthzConfig
- type Capability
- type Config
- type Field
- type LogConfig
- type Logger
- type RegisterOptions
- type Registrar
- type RiskAuthorizer
- type RiskLevel
- type SpillConfig
- type SpillFormat
- type TokenCaps
- type TokenEntry
- type ToolMeta
Constants ¶
This section is empty.
Variables ¶
var ShutdownHooks []func()
ShutdownHooks 是进程优雅退出前要同步执行的钩子(如关闭会话、杀掉子进程)。 由业务包 init() 里 append;进程收到退出信号时由 gtask.BeforeShutdown 回调统一执行。
var StartupHooks []func(context.Context)
StartupHooks 是 server 启动时要执行的钩子(如启动后台 GC 协程)。 由各业务包在自己的 init() 里 append,避免 runtime 反向 import 业务包造成循环依赖。
Functions ¶
func AnyInputSchema ¶
func AnyInputSchema[T any]() *jsonschema.Schema
AnyInputSchema 反射出 T 的输入 schema,并把其中所有「无类型约束」节点 (interface{} / []any 的 items / map[string]any 的 additionalProperties 等) 放宽为 anyTypes 类型联合。生成器对含 interface{} 入参的工具用它显式设置 Tool.InputSchema,从而绕过 SDK 默认反射产生的空 schema。
func AuthzMiddleware ¶
func AuthzMiddleware(authz *Authz) mcp.Middleware
AuthzMiddleware 在 tools/call 做 token + 按人的鉴权,tools/list 只按 token 过滤。
func BuildServer ¶
BuildServer 构造并配置好一个 MCP server(注册工具、spill 资源、日志中间件), 供 HTTP 挂载(MCPHandler)或独立启动(Run)复用。
func HTTPAuditHeaders ¶
HTTPAuditHeaders 是一个纯审计用的 HTTP 中间件:按配置的 header 名单从请求头取值, 注入 ctx,供 LoggingMiddleware 写入 MCP 审计日志。与鉴权无关,不影响放行逻辑。 名单为空时不做任何事,零开销透传。
func HTTPAuthContext ¶
HTTPAuthContext 包一层 http.Handler:解析 Authorization(能力 token)与 X-MCP-User(人身份),注入请求 ctx。token 缺失/无效直接 401。
func HTTPLogID ¶
HTTPLogID 解析或生成本次请求的 logid:优先取配置头(默认 X-Log-Id),缺失则生成; 注入 ctx(供审计/access 日志读取),并回写同名响应头供上游网关串联。
func InitAuditConfig ¶
func InitAuditConfig(path string)
InitAuditConfig 从 mcp.toml 加载 [audit] 段并设置审计 header 名单。 path 为空或文件不存在(stdio / 单测场景)静默置空;其他 stat / 解析失败则告警后置空—— 审计 header 配置不正确不应导致服务起不来。
func InitLogConfig ¶
func InitLogConfig(path string)
InitLogConfig 从 mcp.toml 加载 log 段并设置 logid 头名。 path 为空 / 文件不存在 / 解析失败时静默或告警后回退默认头名——不影响启动。
func InitSpillConfig ¶
func InitSpillConfig(path string)
InitSpillConfig 从 mcp.toml 加载 spill 配置并设置阈值。 文件不存在(stdio / 单测场景)静默用默认值;其他 stat 失败或解析失败则告警后用默认值—— 阈值不正确不应导致服务起不来。
func InitSpillStore ¶
InitSpillStore 幂等初始化磁盘 store:建目录 + reconcile + 启动 GC。 dir 为空时用 <os.TempDir>/mcp-toolify/spill。TTL 各项为 0 时使用默认值。
func LogIDFromContext ¶
LogIDFromContext 取出 ctx 中的 logid,缺失返回 ""。
func LoggingMiddleware ¶
func LoggingMiddleware() mcp.Middleware
LoggingMiddleware 返回一个 receiving middleware,记录每次 MCP RPC。
若已通过 SetAuditLogger 注入 logger,则以结构化字段写入审计日志,字段包含:
- logid:本次请求的日志 ID(由 HTTPLogID 注入),与 access 日志共享,用于串联同一请求
- user:执行人(HTTP 头 X-MCP-User 透传)
- token_name:本次调用所用 token 的用途名(配置 [[tokens]].name),用于审计追溯接入通道
- tool / args:调用的工具名与入参 JSON
- result:返回结果 JSON(截断)
- cost:耗时;err / tool_error:错误信息
- 由 [audit] headers 配置指定的请求头:每个 header 一个独立字段(字段名为 header 名小写)
未注入 logger 时回退到标准 log(stdio 场景)。
func MCPHandler ¶
MCPHandler 返回处理 MCP 协议(Streamable HTTP)的 http.Handler,用于挂载到既有 HTTP server。该 handler 不依赖具体请求路径,可挂在任意子路径。
cfg.AuthzEnabled 为 true 时叠加连接级能力 + 调用级风险鉴权,鉴权配置读取 cfg.ConfigPath。
func MaybeSpill ¶
MaybeSpill 按结果体积决定返回形态:估算 token 数超过配置阈值时落盘为 spill 资源, 否则原样返回 structuredContent。
raw 是原始返回值(用于 json/jsonl 格式推导与体积测量),structured 是打包后的 structuredContent(形如 map[string]any{"result": raw})。序列化失败时记日志后 退回内联路径交给 SDK 处理,保持与旧行为一致;落盘失败时同样降级为内联返回, 不影响工具调用成功——spill 只是上下文体积优化,不该把成功的调用变成失败。
因此第三个返回值目前恒为 nil,仅保留签名位以便将来扩展(生成的 handler 依赖 这个三返回值形状)。生成的 handler 以 `return MaybeSpill(...)` 形式调用它, 工具函数本身不受影响。
func NewAuthzHandler ¶
NewAuthzHandler 构造启用连接级鉴权的 stateless HTTP handler。 Stateless:每个请求独立成会话,逐次重读 Authorization / X-MCP-User, 实现调用级身份透传(多人共用一条 agent 连接的场景)。供 runHTTP 与测试复用。
func NewOwnedSpillID ¶ added in v0.4.0
func NewOwnedSpillID() string
NewOwnedSpillID 生成带本实例归属(host:port)的 spill id,供 sysprobe 等外部包 为自管的 spill 文件命名。多副本部署下,spill_explore 及外部工具据此把「本地未命中 但归属为兄弟副本」的请求单跳代理到属主实例(见 spill_id.go / spill_peer.go)。 未设置对外地址(stdio/未 SetSpillBaseURL)时退回纯随机 id,行为与单机一致。
func NewSpillIDForOwnerTest ¶ added in v0.2.0
NewSpillIDForOwnerTest 供其它包测试构造指定归属的 spill id。
func OwnerOf ¶ added in v0.4.0
OwnerOf 解出 owned spill id 内嵌的属主 host:port(见 spill_id.go)。 ok=false 表示旧式/无归属 id。中性命名,供通用 owner 路由复用。
func RegisterOwnerRouted ¶ added in v0.4.0
func RegisterOwnerRouted(toolName, paramName string)
RegisterOwnerRouted 声明「工具 toolName 按参数 paramName(owned id)路由」。 应在 init/启动期调用,早于开始处理请求。
func RegisterSpillResource ¶
RegisterSpillResource 注册 spill://{id} 资源模板,使客户端可以 resources/read 读取此前 SpillResult 落盘的内容。由 runtime.Run 在 server 启动时调用。
func ResolveSpillPath ¶
ResolveSpillPath 供外部工具包(如 spill_explore)按 id 定位 spill 文件路径。
func Run ¶
Run starts the MCP server with the given registrar.
启动后会向标准日志(log 包)打印监听信息:
- stdio:打印 "MCP server running on stdio"
- http:打印 "MCP server listening on http://<addr>" (含实际端口)
func SetAuditHeaders ¶
func SetAuditHeaders(names []string)
SetAuditHeaders 设置需要进审计日志的 header 名单(去空白、去空项,按小写保序去重)。
func SetAuditLogger ¶
func SetAuditLogger(l Logger)
SetAuditLogger 注入 MCP 审计日志 logger。应在 server 启动前调用。
func SetSpillBaseURL ¶
func SetSpillBaseURL(base string)
SetSpillBaseURL 设置 spill 下载端点的对外基础地址。跨机部署时应传入 agent 可直连的地址;传空串表示当前传输不提供 HTTP 下载(如 stdio)。
func SetSpillPeer ¶ added in v0.2.0
SetSpillPeer 设置副本间代理的共享密钥与超时。timeoutMS<=0 归一化为默认 5000ms。 转发白名单不在此设置——见 SetSpillPeerProvider / SetSpillPeers。
func SetSpillPeerProvider ¶ added in v0.2.0
func SetSpillPeerProvider(fn func() []string)
SetSpillPeerProvider 注册动态兄弟副本发现函数:每次代理白名单校验时实时调用它,返回当前 可达的兄弟副本 host:port 列表。用它对接任意服务发现,无需静态配置。传 nil 清除(回退到 无兄弟副本,即拒绝一切远端转发)。与 SetSpillPeers 互为覆盖,后调用者生效。
func SetSpillPeers ¶ added in v0.2.0
func SetSpillPeers(hosts []string)
SetSpillPeers 设置静态兄弟副本列表(通常来自配置),内部包装成返回该快照的 provider。 与 SetSpillPeerProvider 互为覆盖:后调用者生效。空列表等价于无兄弟副本。
func SetSpillThreshold ¶
func SetSpillThreshold(tokens int)
SetSpillThreshold 设置自动 spill 的 token 阈值。 配置语义:传 0(含配置缺省)归一化为 defaultMaxResultTokens; 负数关闭自动 spill,规范写法为 -1,小于 -1 的值视为配置疑似有误,归一化为 -1 并告警。
func SpillDir ¶ added in v0.4.0
func SpillDir() string
SpillDir 返回框架 spill 文件的落盘目录。外部工具包(如 sysprobe)应把自管的 spill 文件写到该目录,以便与框架共用同一套 GC、下载端点与 spill_explore 解析。
func SpillDirForTest ¶ added in v0.2.0
func SpillDirForTest() string
SpillDirForTest 返回当前全局 spill store 目录,供跨包测试落文件。
func SpillDownloadHandler ¶
SpillDownloadHandler 返回一个 http.Handler,按 /spill/<id> 路径把此前 SpillResult 落盘的文件直接作为可下载内容返回。挂到 MCP server 同一个 HTTP 端口上,供跨机 agent 直连下载。未命中/过期返回 404。
func SpillDownloadURLFor ¶
SpillDownloadURLFor 返回该 id 可选的直连下载 URL;未配置对外地址时为空串。
func SpillHandler ¶
SpillHandler 返回 /spill/<id> 大结果下载端点的 http.Handler。 与 MCPHandler 挂在同一个 HTTP server 上即可供 agent 直连下载。
func SpillPeerAllowed ¶ added in v0.2.0
SpillPeerAllowed 返回 hostPort 是否为当前已知的兄弟副本之一(仅这些地址允许被代理)。 provider 未注册或返回空时返回 false(默认拒绝一切远端转发,防 SSRF/密钥外泄的安全默认)。
func SpillPeerTimeout ¶ added in v0.2.0
SpillPeerTimeout 返回代理调用超时。
func SpillPeerToken ¶ added in v0.2.0
func SpillPeerToken() string
SpillPeerToken 返回共享密钥;空串表示跨副本代理关闭。
func SpillResult ¶
func SpillResult(toolName string, out any) (*mcp.CallToolResult, error)
SpillResult 把工具返回值按推导出的格式(json/jsonl)序列化并落到磁盘文件, 返回一个只含摘要 + ResourceLink 的 CallToolResult。toolName 用于文件名与摘要文案。
无条件落盘,供手写工具(sysprobe / terminal_* 等)在明确知道结果很大时直接调用。 生成的 handler 走 MaybeSpill,按体积自动判定。
func SpillSelfHostPort ¶ added in v0.2.0
func SpillSelfHostPort() string
SpillSelfHostPort 返回本实例对外 host:port(无对外地址时为空)。
func ToolError ¶
func ToolError(err error) *mcp.CallToolResult
ToolError converts a Go error into an IsError CallToolResult so callers can distinguish tool failures from protocol-level errors.
func WithAuthContext ¶
func WithAuthContext(ctx context.Context, ac AuthContext) context.Context
WithAuthContext 把鉴权上下文注入 ctx。
Types ¶
type AuditConfig ¶
type AuditConfig struct {
// Headers 是需要额外写入 MCP 审计日志的请求头名称列表。
// 每个 header 会以独立字段落在审计日志里,字段名为该 header 名的小写形式
// (如 X-Tenant-Id -> x-tenant-id)。缺失或空值记为 "-"。
Headers []string `toml:"headers"`
}
AuditConfig 是审计相关配置(对应 mcp.toml 的 [audit] 段)。
func LoadAuditConfig ¶
func LoadAuditConfig(path string) (AuditConfig, error)
LoadAuditConfig 从指定 TOML 文件读取 [audit] 段。
type AuthContext ¶
type AuthContext struct {
Caps TokenCaps // 由 Authorization token 决定的读/写风险上限
Identity string // 调用人身份,取配置身份头列表(默认 [X-MCP-User])中第一个非空值;可能为空
TokenName string // token 用途名(配置里的 name),用于审计日志
}
AuthContext 是从 HTTP header 解析出的连接/调用鉴权上下文。
func AuthFromContext ¶
func AuthFromContext(ctx context.Context) (AuthContext, bool)
AuthFromContext 取出鉴权上下文。
type Authz ¶
type Authz struct {
RiskAuthorizer
// contains filtered or unexported fields
}
Authz 聚合 token->读写风险上限 映射与按人风险判定。
func (*Authz) IdentityHeaders ¶
IdentityHeaders 返回取调用人身份的有序请求头名;未配置时回退 [X-MCP-User]。
type AuthzConfig ¶
type AuthzConfig struct {
Tokens []TokenEntry `toml:"tokens"`
RiskAllowlist map[string][]string `toml:"risk_allowlist"` // level -> 身份列表
// IdentityHeaders 指定取调用人身份的请求头名(有序):按从前到后的顺序,取第一个
// 在请求中非空的头值作为身份,用于按人鉴权与审计(user 字段)。缺省/为空时用
// defaultIdentityHeader(X-MCP-User)。由可信网关注入,服务端直接信任其值。
IdentityHeaders []string `toml:"identity_headers"`
}
AuthzConfig 是 HTTP 鉴权的配置(对应 conf/mcp/mcp.toml)。
func LoadAuthzConfig ¶
func LoadAuthzConfig(path string) (AuthzConfig, error)
LoadAuthzConfig 从指定 TOML 文件加载鉴权配置。
func (AuthzConfig) Validate ¶
func (c AuthzConfig) Validate() error
Validate 校验 token 配置的基本合法性与审计元信息完整性: token 为空、token 重复、缺 name、缺 applicant 均返回 error, 启动阶段应据此失败,避免上线不可用或无法追溯来源的 token。
错误信息用配置里的序号定位条目,绝不回显 token 值(错误会进日志/终端)。 存在多个问题时只报第一个。
type Capability ¶
type Capability int
Capability 表示一个工具的读/写类别(由其 mcp:tags 是否含 write 派生)。
const ( ReadOnly Capability = iota ReadWrite )
type Config ¶
type Config struct {
Transport string // "stdio" | "http"
Addr string // http listen addr,例如 ":8080";为空时由系统分配端口
Enable []string // package-name whitelist
Tags []string // tag whitelist
// PublicBaseURL 是 agent 侧可直连的对外基础地址(如 http://host:8011)。
// 跨机部署时必须设置,spill 下载 URL 会基于它拼接;为空时回退到实际监听地址
// (仅适用于同机/本地场景)。
PublicBaseURL string
// ConfigPath 指向包含 [spill] 与 [[tokens]]/[risk_allowlist] 段的 TOML 文件。
// 为空时:spill 阈值用默认值;若 AuthzEnabled=true 则启动报错(鉴权必须有配置)。
ConfigPath string
// SpillDir 是大返回结果落盘目录。为空时用 <os.TempDir>/mcp-toolify/spill。
SpillDir string
// AuthzEnabled 为 true 时(仅 http 生效)启用连接级能力 + 调用级风险鉴权,
// 配置来自 ConfigPath。默认关闭。
AuthzEnabled bool
}
Config controls server startup behavior.
type LogConfig ¶
type LogConfig struct {
// LogIDHeader 是读取入站 logid 的请求头名,同时作为回写响应头名。
// 缺省用 defaultLogIDHeader(X-Log-Id)。
LogIDHeader string `toml:"logid_header"`
}
LogConfig 是日志相关配置(对应 mcp.toml 的 log 段)。
type Logger ¶
Logger is the audit sink for MCP tool calls. Implementations receive a short message tag (always "mcp_call") plus structured fields (user, tool, args, result, cost, ...). Notice is used for successful calls, Warning for calls that returned an error or an IsError tool result.
Injecting a Logger is optional: when none is set (see SetAuditLogger), the runtime falls back to the standard library log package. This keeps the framework free of any specific logging dependency.
type RegisterOptions ¶
type RegisterOptions struct {
Enable []string // package-name whitelist
Tags []string // tag whitelist
}
RegisterOptions controls which generated tools get registered with the server. Empty Enable / Tags means "no filter".
type Registrar ¶
type Registrar func(s *mcp.Server, opts RegisterOptions)
Registrar is the function generated tools expose (typically tools.RegisterAll).
type RiskAuthorizer ¶
RiskAuthorizer 判定某身份是否可执行到指定风险等级。
本期由 staticAuthorizer(读配置白名单)实现;未来可替换为按邮件组成员 每 20min 刷新的实现——仅需实现该接口,其余代码不动。
type RiskLevel ¶
type RiskLevel int
RiskLevel 表示单个工具的风险等级;缺省为 RiskNone。
type SpillConfig ¶
type SpillConfig struct {
// MaxResultTokens 为工具返回值的 token 阈值:超过则自动落盘为 spill 资源。
// 0 或缺省表示用 defaultMaxResultTokens;负数关闭自动 spill,规范写法为 -1。
MaxResultTokens int `toml:"max_result_tokens"`
// PeerToken 为副本间内部 /spill-explore 端点的共享密钥;为空表示关闭跨副本代理(安全默认)。
PeerToken string `toml:"peer_token"`
// PeerTimeoutMS 为代理调用超时(毫秒);0 表示用默认 5000。
PeerTimeoutMS int `toml:"peer_timeout_ms"`
// PeerHosts 为可选的静态代理白名单(host:port);多副本部署通常改用 SetSpillPeerProvider
// 经服务发现动态提供,无需在此配置。为空且未注册 provider 时不允许任何远端转发(安全默认)。
PeerHosts []string `toml:"peer_hosts"`
}
SpillConfig 是 spill 行为配置(对应 conf/mcp/mcp.toml 的 [spill] 段)。
func LoadSpillConfig ¶
func LoadSpillConfig(path string) (SpillConfig, error)
LoadSpillConfig 从指定 TOML 文件读取 [spill] 段。
type SpillFormat ¶
type SpillFormat string
SpillFormat 是 spill 文件声明的内容格式。
const ( FormatJSON SpillFormat = "json" // .json FormatJSONL SpillFormat = "jsonl" // .jsonl FormatText SpillFormat = "text" // .txt )
type TokenCaps ¶
type TokenCaps struct {
ReadOK bool
Read RiskLevel
WriteOK bool
Write RiskLevel
// Name 是 token 的用途标识,仅用于审计日志,不参与权限判定。
Name string
}
TokenCaps 是一个 token 解析后的读/写风险上限。 ReadOK/WriteOK 为 false 表示该类操作完全不允许。
type TokenEntry ¶
type TokenEntry struct {
Token string `toml:"token"`
// Name 是 token 的用途标识(如 readonly-agent),会写入审计日志的 token_name 字段,
// 用于定位一次调用走的是哪条接入通道。必填。
Name string `toml:"name"`
// Applicant 是申请人标识(requester id),仅留在配置里用于审计追溯(按 token_name 反查),不进日志。必填。
Applicant string `toml:"applicant"`
Read string `toml:"read"` // 读操作最高风险;空 => 不允许读
Write string `toml:"write"` // 写操作最高风险;空 => 不允许写
}
TokenEntry 是单个 token 的配置:审计元信息 + 分别设置读/写允许的最高风险等级。 read/write 取 none|low|medium|high;省略某字段表示该类操作完全不允许。
type ToolMeta ¶
type ToolMeta struct {
Name string
Capability Capability
Risk RiskLevel
}
ToolMeta 记录单个工具的鉴权相关元数据,由生成代码在注册时登记。
func LookupMeta ¶
LookupMeta 查询工具元数据。未登记的工具(如内置 spill resource)返回 false。