# MCP servers

Build MCP servers as small, explicit adapters around a domain or external API.
Default to stdio for local agent use; choose Streamable HTTP only when the server
needs networked clients or deployment behind an HTTP boundary.

## Shape

- Keep transport/config setup separate from tool handlers.
- Keep API clients or domain logic outside the MCP layer.
- Prefer typed parameter/result structures when the language supports them.
- If the wrapped API has sharp edges, add a `usage`/instructions tool documenting
  them.

## Tools

- Add tool annotations: read-only/destructive/idempotent/open-world hints.
- Make descriptions operational: what the tool does, when to use it, and any
  required prerequisite tool.
- Return structured errors for real failures. Use tool-level errors for domain
  failures the model should see and potentially recover from.
- Clamp or validate bounds at the boundary and document whether clamping is
  silent or an error.

## Config and release

- Required connection info comes from env vars and/or explicit flags.
- Validate URLs and auth shape before starting the server.
- Allow separate auth layers when real deployments need them, but document how
  headers/cookies interact.
- Treat MCP servers as installable command-line binaries unless the deployment
  model clearly says otherwise; read [cli.md](cli.md) and [packaging.md](packaging.md)
  when building release artifacts.

## Go path

For Go MCP servers, read [golang/index.md](golang/index.md) first and follow its
MCP chain. That route intentionally loads Go baseline, CLI, mise, and preferred
library context before `golang/mcp.md`.
