kit-one-tool-mcp

Clone-and-rename template for a single-tool MCP server: one tool with a described input schema, plus 15 offline tests covering the failure paths (missing key, 401, 403, 429, 503, DNS failure, non-JSON body, empty result). Runs with no API key and no network.

Documentation

kit-one-tool-mcp

license MIT tests 15 offline api key not needed listed on glama 8 more servers wired $49

Most MCP examples show you the happy path and then fail on somebody's laptop at 401. This one is the opposite: one tool, a described schema, and 15 tests that are mostly the unhappy paths — missing key, 401, 403, 429, 503, DNS failure, non-JSON body, empty result.

Clone it, rename THING, and you have the shape of a working MCP server. It is a sample of what an MCP Basic build from Kit looks like when it is handed over.

If you came here looking for a one tool MCP sample, an MCP server example in TypeScript, or a way to test an MCP tool with no API key and no network, this is that.

It is deliberately one tool. A second tool, or a Cloudflare Worker, is a Build Packet, not a bigger version of this.

Want your repo set up for Claude Code first?

This repo is MIT and complete — take it and go. If you want a CLAUDE.md, a tool allowlist and one skill wired for your repo:

Buy Setup Lite — $29 · ~24h, handed back as a PR.

Details: kit.sdvsignal.com/#setup-lite · the same shape as this repo built against your API is MCP Basic $199.

60-second start — no API key, no network, no Claude

git clone https://github.com/sdvsignal/kit-one-tool-mcp
cd kit-one-tool-mcp && npm install && npm test

No git? The same tracked tree ships as one archive on every release: latest release. Unzip it, then the same npm install && npm test.

15 tests, all offline. Three of them stand up a real MCP client against the real server over an in-memory transport and call the tool, so the wiring is tested, not just the function. If those pass, the server works — you have not needed a key yet.

Add it to Claude Code

Today, this is the one that works. Clone it first, then point Claude Code at the local file:

git clone https://github.com/sdvsignal/kit-one-tool-mcp
cd kit-one-tool-mcp && npm install
export THING_API_KEY=...
claude mcp add kit-one-tool -- node "$PWD/src/index.js"

Or by hand in .mcp.json, using the absolute path to where you cloned it:

{
  "mcpServers": {
    "kit-one-tool": {
      "command": "node",
      "args": ["/absolute/path/to/kit-one-tool-mcp/src/index.js"],
      "env": { "THING_API_KEY": "..." }
    }
  }
}

Once it is on npm

@sdvsignal/kit-one-tool-mcp is not published yet, so the two commands below will fail with a 404 if you try them today. They are here so you know what the install becomes, not so you can run it now:

claude mcp add kit-one-tool-mcp -- npx -y @sdvsignal/kit-one-tool-mcp
{ "mcpServers": { "kit-one-tool-mcp": { "command": "npx", "args": ["-y", "@sdvsignal/kit-one-tool-mcp"] } } }

Registry name: io.github.sdvsignal/kit-one-tool-mcp (see server.json).

Claude Desktop instead: add this to the config file and restart the app.

{
  "mcpServers": {
    "one-tool": {
      "command": "node",
      "args": ["/absolute/path/to/one-tool-mcp/src/index.js"],
      "env": { "THING_API_KEY": "..." }
    }
  }
}

Your key lives in your environment. It is not in this repo, and there is no default value that quietly works.

Run it in a container

Same one tool, same stdio, nothing listening on a port:

docker build -t one-tool-mcp .
docker run --rm -i -e THING_API_KEY=... one-tool-mcp

-i matters — the server talks over stdin/stdout, so without it there is nothing to talk to. To point Claude Desktop at the image instead of at node, use "command": "docker" with "args": ["run", "--rm", "-i", "-e", "THING_API_KEY", "one-tool-mcp"].

Smoke prompt

Type this to Claude. This is the test that it is really wired up:

Search THING for "onboarding" and show me the top 3.

You should get up to 3 results with names and ids. If nothing matches you get No THINGs matched "onboarding", which is correct and not a failure. Telling the model that an empty result is empty is most of why it stops retrying.

What is in here

FileWhat it is
src/search-things.jsThe one tool. Takes its dependencies as an argument, which is why it is testable without a key.
src/server.jsServer wiring. Registers exactly one tool.
src/index.jsThe entrypoint. Connects stdio and nothing else.
test/The 15 tests above.
DockerfileBuilds the image above. Copies the lockfile and src/, runs npm ci --omit=dev.

Errors you may see

MessageMeans
THING_API_KEY is not setenv var missing, or Claude was not restarted after you set it
THING rejected the key (401/403)wrong or revoked key
THING rate limit hit (429)wait, then retry
THING returned 503their side, not yours
Could not reach https://...network, or THING_BASE_URL is wrong
THING returned something that was not JSONusually an HTML error page from a proxy

None of them return a stack trace. A tool that throws raw errors at the model makes it guess.

Remove it

claude mcp remove one-tool

Claude Desktop: delete the one-tool block and restart. The server keeps no state, so nothing is left behind.

Making it yours

  1. Rename search_things for what it actually does, from the caller's point of view.
  2. Write the input schema before the implementation. Every field described, required vs optional explicit.
  3. Keep the description aimed at the model: say when to reach for the tool, not only what it is.
  4. Point THING_BASE_URL and the auth header at the real API.
  5. Run npm test, then run the smoke prompt in Claude. A passing test is not proof the tool works against the real API.

You did not want to build one, you wanted eight wired

Half the people who land here from an MCP directory are not building a server — they want the common ones connected, and they hit the same wall every time, which is the JSON rather than the server.

MCP Config Pack — $49 is eight ready configs (filesystem, GitHub, Postgres, context7 and four more), each with the smoke prompt and the pass condition that tells you it is actually connected rather than merely listed. Offline, no telemetry, instant download. Two of the eight need no token at all, so you can prove the wiring before you go near a credential.

Details and the full list: kit.sdvsignal.com/#mcp-config-pack. If you would rather have them wired into your repo alongside hooks and skills, that is Setup Sprint $99, not this.

Free here vs. paid

This repo is MIT and complete — the tool, the tests, the error table, the removal path. Nothing is held back. If you are building your own MCP server, take it and go.

Paid is the same shape built against your API and tested against it before delivery, which is the part the offline tests above deliberately cannot do: MCP Basic $199 — one tool, the schema, handoff notes, a smoke prompt and the enable/disable path. Need more than one tool, or a Worker? Build Packet $399. Just want the repo itself set up for Claude Code first? Setup Lite $29 (back as a PR in 24h) or Setup Sprint $99 (48h). Just want other people's servers connected? MCP Config Pack $49, above.

Shipping an iOS app on top of it? Preview Pack $149 is one App Store preview video to Apple's spec, 5 stills and 2 revision rounds, in 72 hours.

→ Scope and order: kit.sdvsignal.com

We use AI tools including Claude; a person reviews every deliverable before it ships. Independent project, not affiliated with Anthropic.

Questions

Writing your first tool description, or want a second read of one? Paste it in Discussions. Real answers, no signup.

Related

License

MIT licensed. Use it for your own work, no attribution needed.