andygeiss/mcp
GitHub: andygeiss/mcp
一个零依赖的 Go 语言 MCP 服务器模板,通过标准 I/O 与 JSON-RPC 2.0 提供可审计的轻量级进程间模型上下文协议支持。
Stars: 0 | Forks: 0
# mcp
[](https://github.com/andygeiss/mcp/releases)
[](https://pkg.go.dev/github.com/andygeiss/mcp)
[](https://scorecard.dev/viewer/?uri=github.com/andygeiss/mcp)
[](https://github.com/andygeiss/mcp/actions/workflows/codeql.yml)
[](https://codecov.io/gh/andygeiss/mcp)
[](LICENSE)
一个无依赖的 Go 语言实现的 [模型上下文协议](https://modelcontextprotocol.io) (MCP)。
单一二进制文件。通过标准输入/输出传输。使用 JSON-RPC 2.0。仅此而已。
## 为什么
MCP 服务器不需要 HTTP 框架、路由器或依赖树。此项目是一个生产就绪的 MCP 服务器,纯 Go 语言实现,覆盖工具、资源、提示、日志记录和进度,并通过反射自动派生模式,且仅依赖标准库完成三阶段初始化握手。
直接使用它,或使用 `make init` **构建你自己的版本**。
## 功能特性
- **MCP 2025-11-25** — 工具、资源(列/读)、提示、日志记录、进度
- **基于标准输入/输出的 JSON-RPC 2.0** — 换行分隔的 JSON 对象,无 LSP 帧封装
- **自动派生的模式** — 结构体标签通过反射驱动工具和提示的输入模式
- **双向传输** — 通用服务器到客户端请求原语(无内置的采样/提示/根处理程序)
- **安全默认** — 每消息上限(4 MB)、处理器超时(30 秒)、恐慌恢复
- **结构化诊断** — 通过 `slog.JSONHandler` 输出到标准错误;标准输出仅保留协议内容
- **零外部依赖** — 仅使用标准库
- **供应链就绪** — cosign 签名发布、SBOM、SLSA L3 可追溯性、OSS-Fuzz
## 系统要求
- Go 1.26+
- 在 macOS、Linux、Windows 上通过 CI 测试。发布的二进制文件适用于 macOS 和 Linux(amd64、arm64)。
## 安装
```
go install github.com/andygeiss/mcp/cmd/mcp@latest
```
或者从 [Releases](https://github.com/andygeiss/mcp/releases) 下载已签名的发布包并验证(参见[验证发布](#verify-a-release))。
## 与 MCP 客户端配合使用
将任意 MCP 客户端(如 Claude Desktop、VS Code)指向已安装的二进制文件:
```
{
"mcpServers": {
"mcp": {
"command": "/absolute/path/to/mcp"
}
}
}
```
在客户端环境中设置 `MCP_TRACE=1` 以将每个请求与响应记录到标准错误。如果处理器可能接收凭证或 PII,请勿在生产环境中启用跟踪输出。
## 构建你自己的版本
Fork 或克隆此仓库,然后重写模块路径:
```
make init MODULE=github.com/yourorg/yourproject
```
打开 `internal/tools/echo.go` — 这是你的第一个工具,已连接并可重命名。
此操作会重写所有导入、更新徽章 URL(shields.io、codecov、Actions)指向你的仓库,运行 `go mod tidy`,并移除 `cmd/scaffold/`。二进制文件目录仍为 `cmd/mcp/`,因此每个构建的项目都会生成名为 `mcp` 的二进制文件;使用 `go install github.com/yourorg/yourproject/cmd/mcp@latest` 安装。如果两个 MCP 服务器共享 `$GOBIN`,请使用 `go build -o ` 或重命名 `cmd/mcp/` 以作区分。
如果工作区存在未提交的更改,重写器将拒绝运行 — `resetGitHistory` 是破坏性操作,会抹除未提交的修改。请先提交或暂存更改,或使用 `--force` 参数覆盖:`go run ./cmd/scaffold --force github.com/yourorg/yourproject`。
## 你的第一个工具
`make init` 成功后,欢迎横幅会列出三个步骤。以下是每个步骤的示例:
### 编辑 — `internal/tools/echo.go`
打开起始工具。第一行是你的锚点:
```
// START HERE — your first tool. Edit, copy, rename. It's yours.
// Package tools holds the registered MCP tools and the registry primitives
// that wire them into the server.
package tools
import "context"
type EchoInput struct {
Message string `json:"message" description:"The message to echo back"`
}
func Echo(_ context.Context, input EchoInput) Result {
return TextResult(input.Message)
}
```
替换 `Echo` 主体,重命名输入结构体,并编辑 `description` 标签 — 该标签内容即为智能体在决定是否调用你的工具时读取的文本。
### 连接 — `cmd/mcp/main.go`
使用一行代码注册它:
```
if err := tools.Register(registry, "echo", "Echoes the input message", tools.Echo); err != nil {
return fmt.Errorf("register echo: %w", err)
}
```
需要第二个工具的干净副本?打开 `internal/tools/_TOOL_TEMPLATE.go` — 结构相同,无实际逻辑,可直接重命名。
### 验证 — `make smoke`
```
make smoke
```
成功时输出如下内容:
```
Your server works. It exposes N tool(s).
```
失败时,目标程序会打印两条诊断提示(是否忘记注册?是否无法编译?),随后输出捕获的标准错误 — 通常足以在不解闭终端的情况下解决问题。
## 添加工具
定义输入结构体,编写处理函数并注册它。
```
// internal/tools/greet.go
package tools
import "context"
type GreetInput struct {
Name string `json:"name" description:"Name to greet"`
}
func Greet(_ context.Context, input GreetInput) Result {
return TextResult("Hello, " + input.Name + "!")
}
```
```
// cmd/mcp/main.go
if err := tools.Register(registry, "greet", "Greets someone by name", tools.Greet); err != nil {
return fmt.Errorf("register greet: %w", err)
}
```
输入模式(`{"type":"object","properties":{"name":{"type":"string","description":"Name to greet"}},"required":["name"]}`)由结构体标签自动派生,无需手动定义模式。
## 验证发布版本
发布包使用 cosign 进行无密钥签名,并附带由 `slsa-framework/slsa-github-generator` 生成的 SLSA L3 可追溯性信息。每个归档文件包含 `.sigstore.json` 捆绑包;SHA-256 摘要记录在 `checksums.txt` 中;SBOM 作为 `*.sbom.json` 附件提供。
```
# 将 、、 替换为目标值,例如 0.1.0、Linux、x86_64
cosign verify-blob \
--bundle mcp___.tar.gz.sigstore.json \
--certificate-identity-regexp "^https://github.com/andygeiss/mcp/" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
mcp___.tar.gz
```
## 协议兼容性
MCP 版本 `2025-11-25`。JSON-RPC 2.0 的具体实现如下:
| 行为 | 实现 |
|---|---|
| 帧封装 | 换行分隔的 JSON 对象 |
| 批量请求 | 以 `-32700` 拒绝 |
| 缺少 `params` | 规范化为 `{}` |
| 请求 `id` | 保留为 `json.RawMessage`,原样回显 |
| 通知 | 永不响应 |
| 未知通知 | 静默忽略 |
| 错误消息 | 上下文相关(如 `"unknown tool: foo"`) |
传输依据与替代方案考量:[docs/adr/ADR-001](docs/adr/ADR-001-stdio-ndjson-transport.md)。
### 覆盖范围
实现了 `tools/list`、`tools/call`、`resources/list`、`resources/read`、`prompts/list`、`prompts/get`、`logging/setLevel`,以及 `notifications/initialized`、`notifications/cancelled`、`notifications/progress`、`notifications/message` 和一个通用的服务器到客户端请求原语。
未实现的功能(调用将以 `-32601` 拒绝):`resources/subscribe`、`resources/unsubscribe`、`completion/complete`、`roots/list`、`sampling/*`、`elicitation/*` 以及 `*/list_changed` 通知。
## 架构
```
cmd/mcp/ main.go -- wiring only: flags, I/O injection, os.Exit
cmd/scaffold/ template rewriter -- not part of normal builds
internal/
assert/ test assertion helpers
prompts/ prompt registry, argument derivation
protocol/ JSON-RPC 2.0 codec, types, constants
resources/ resource registry, static resources, URI templates
schema/ shared JSON Schema derivation via reflection
server/ lifecycle, dispatch, notifications, bidirectional transport
tools/ tool registry, schema derivation, tool handlers
```
**依赖方向:** `cmd/mcp/ -> server/ -> protocol/`;`server/` 导入 `tools/`、`resources/`、`prompts/`。`protocol/` 和 `schema/` 对内部无依赖。
**传输规则:**
- **标准输出** 仅传输协议内容 — 每个字节均为有效的 JSON-RPC 消息。
- **标准错误** 仅用于诊断,通过 `slog.JSONHandler` 输出。
- 构造函数接受 `io.Reader`/`io.Writer`,以便测试中注入缓冲区。
## 开发
```
make check # build + test + lint
make test # go test -race ./...
make fuzz # fuzz the JSON decoder (FUZZTIME=5m to extend)
make coverage # enforce 90% threshold
make bench # benchstat against testdata/benchmarks/baseline.txt
```
编写指南、测试约定和完整工作流矩阵位于 [`docs/development-guide.md`](docs/development-guide.md)。
## 文档
- [项目概述](docs/project-overview.md)
- [架构](docs/architecture.md)
- [源代码结构分析](docs/source-tree-analysis.md)
- [开发指南](docs/development-guide.md)
- [部署指南](docs/deployment-guide.md)
## 许可证
[MIT](LICENSE) — Andreas Geiß
标签:EVTX分析, Go, JSON-RPC, MCP, Model Context Protocol, Ruby工具, SEO: Go MCP 实现, SEO: Model Context Protocol Go, SEO: zero-dependency MCP server, SLSA, stdin, stdout, 协议实现, 单二进制, 安全编码, 工具, 提示, 日志, 日志审计, 标准库, 模板, 生产就绪, 签名发布, 脚手架, 自动生成Schema, 覆盖率, 诊断, 资源, 进度, 零依赖