1# Go MCP servers
2
3Read [../mcp.md](../mcp.md), [baseline.md](baseline.md), [mise.md](mise.md),
4[cli.md](cli.md), and [preferred-libraries.md](preferred-libraries.md) before
5applying these Go MCP specifics.
6
7Use the official Go SDK: `github.com/modelcontextprotocol/go-sdk`. Default to
8stdio for local agent use; choose Streamable HTTP only when the server needs
9networked clients or deployment behind an HTTP boundary.
10
11MCP servers are still command-line binaries. Keep the CLI/versioning rules from
12[cli.md](cli.md) in force.
13
14## Shape
15
16```text
17cmd/<server>/main.go # CLI entrypoint
18cmd/<server>/serve.go # serve command and transport flag
19internal/config/config.go # env and flag parsing
20internal/server/server.go # MCP implementation, transports, handlers
21internal/server/tools.go # typed tool parameter structs, split into tool-per-file if it gets unwieldy
22internal/<client>/... # API client being wrapped
23```
24
25## Tools
26
27- Use typed parameter structs with JSON and jsonschema tags.
28- Add tool annotations: read-only/destructive/idempotent/open-world hints.
29- Make descriptions operational: what the tool does, when to use it, and any
30 required prerequisite tool.
31- Return structured errors for real failures; use MCP `IsError` for tool-level
32 domain errors the model should see.
33- Clamp or validate bounds at the boundary and document whether clamping is
34 silent or an error.
35
36If the wrapped API has sharp edges, add a `usage`/instructions tool documenting
37them.
38
39## Config
40
41- Required connection info comes from env vars and/or explicit flags.
42- Validate URLs and auth shape before starting the server.
43- Allow separate auth layers when real deployments need them, but document how
44 headers/cookies interact.
45
46## Release
47
48MCP servers are usually plain static binaries. Use `CGO_ENABLED=0` unless a
49dependency requires CGO. Add nFPM only when system installation, services, or
50managed config files are part of the product.
51
52Prefer the static build shape from [mise.md](mise.md): `netgo`, `osusergo`,
53optional project-specific `static_build`, `-d -s -w -buildid= -extldflags=-static`,
54and explicit version injection when the server exposes `--version` or embeds
55version metadata. Do not rely on Fang's CLI fallback alone for MCP implementation
56metadata; use the same project-owned version value anywhere the server reports
57it. Remove those static-only pieces when the wrapped API client or storage layer
58requires CGO.