Stash for assistants

Connect Claude or any MCP client, and what a token lets it do.

An MCP server, so Claude and other assistants can work with a Stash account: see the projects in it, create one, and get the details needed to connect an application to its database.

If you have not got Stash running yet, start with Setting up Stash.

It is a local process. It runs on the customer's machine, holds their own API token, and talks to the Stash HTTP API. Nothing about it is privileged: every refusal comes from the same routes the dashboard uses, and revoking the token in the dashboard is the whole of the off switch.

Install it

  1. In Stash, open API tokens and create one. Leave read-only unticked if the assistant should be able to create projects. The token is shown once.
  2. Point your client at the server. For Claude Desktop, in claude_desktop_config.json:
{
  "mcpServers": {
    "stash": {
      "command": "node",
      "args": ["/absolute/path/to/stash/apps/mcp/dist/main.js"],
      "env": {
        "STASH_TOKEN": "the token you just created",
        "STASH_URL": "http://127.0.0.1:3010"
      }
    }
  }
}

For Claude Code:

claude mcp add stash --env STASH_TOKEN=… --env STASH_URL=http://127.0.0.1:3010 -- node /absolute/path/to/stash/apps/mcp/dist/main.js

STASH_URL defaults to http://127.0.0.1:3010, which is where pnpm dev serves the dashboard. Plain http is refused for anything that is not this machine: the token is a bearer credential and sending one in the clear to another host is not a thing to do by accident.

Build it first with pnpm build from the repository root. dist/main.js is what a client runs.

What it can do

Tool What it is for
list_projects Everything in the account, with each database's status.
create_project Creates a project and starts building its Postgres. Provisions real infrastructure, and the account has a limit.
get_project One project. Once its database is ready, the host, user, password and connection string.

Three, not thirteen. Deploys, payments and email do not exist yet, and a tool for a surface that is not built is worse than no tool: a model reads the list as capabilities and will offer the customer something that cannot happen. Tools get added as the surfaces land.

What a read-only token cannot do

Two things, and both are deliberate:

  • Create a project, because that provisions a database somebody pays for.
  • Read connection details, because a Postgres connection string is not read-only by any reading of those words. It opens the database with the owner's role and can drop every table in it.

get_project still answers for a read-only token. It says why the credential is missing, so an assistant can tell "not allowed" from "not ready yet" and say the useful thing rather than guessing out loud.

If something is wrong

Diagnostics go to stderr, which clients show in their logs. Nothing is ever written to stdout, because stdout is the protocol: one stray line of anything else corrupts the JSON-RPC stream and the client disconnects with a parse error that names nothing.

  • "STASH_TOKEN is not set": the client did not pass env, or the token is blank.
  • "Stash did not accept this token": it was revoked, or it is from a different Stash. Check the API tokens screen.
  • "Could not reach Stash": nothing answered at STASH_URL. Is pnpm dev running?

How it is tested

  • src/tools.test.ts drives the tools through the SDK's own Client over its in-memory transport, with Stash faked. Real protocol, real schema validation.
  • smoke/mcp.spec.ts launches this server as a subprocess exactly as a client does, holding a token created by clicking buttons in the dashboard, and checks that a project an assistant creates shows up on the screen a person looks at.

Found something wrong? Edit this page.