Skip to content

MCP Server Checklist

Copy this into your PR or ticket. Each block maps to a step in the build guides (TypeScript / Python).

  • Checked for an existing trusted server first
  • User jobs listed; one task-shaped tool per job
  • Fewer than about 10 tools
  • Each tool classified as read-only, write, or destructive
  • Transport chosen: stdio (local) or Streamable HTTP (remote), with the reason logged
  • Created from a template
  • Builds / installs cleanly; lockfile committed
  • name and version set in the server constructor
  • Handshake works in the Inspector
  • All logging goes to stderr, nothing to stdout
  • Tools registered before connect() / run()
  • verb_noun snake_case names, consistent verbs, namespaced if collisions are likely
  • Descriptions say what, what it returns, when to use it, limits, and side effects
  • Every parameter has a description, plus constraints (enum, min/max, format)
  • Minimal required parameters, with sensible defaults
  • Output is concise and readable; capped or paginated
  • structuredContent + outputSchema where it will be parsed
  • Expected failures return isError: true with an actionable message
  • Annotations set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
  • Only added if target clients support them and they help
  • URIs and descriptions are clear
  • All configuration comes from environment variables, with safe defaults
  • Fails fast, with a clear stderr message, if required config is missing
  • No secrets in code, committed config, outputs, or logs
  • Unit tests for handler logic
  • qa/mcp-smoke.mjs passes (handshake, tool list, sample call)
  • Inspector: every tool’s happy path and error path checked
  • End-to-end eval prompts pass in each target host (right tool, right arguments, no false calls)
  • Works in Cursor (.cursor/mcp.json): green, with tools listed
  • Works in Claude Code (claude mcp add / .mcp.json)
  • Works in Claude Desktop (if targeted)
  • Remote: works as a Claude.ai custom connector (if targeted)
  • Config snippets for each host in the README, with absolute forward-slash paths
  • Threat model reviewed (security guide)
  • Destructive actions need confirmation
  • Credentials scoped to the minimum
  • Path, command, and URL inputs validated
  • Remote: HTTPS, token validation, per-user authorisation, rate limits
  • Dependencies audited
  • Versioned, CHANGELOG.md updated, distribution channel chosen
  • A colleague installed it from the README alone
  • Decision logged in your project’s decision log (for example DECISIONS.md)