npm package: @firestitch/specify-mcp
Description: MCP server for Specify project management (stdio + HTTP)
Latest version: 1.0.16

# @firestitch/specify-mcp

MCP server for AI agents to interact with Specify's project management features.

## Prerequisites

- Node.js >= 18

## Install from npm

```bash
npm install @firestitch/specify-mcp --save-dev
```

Then point Cursor at the package binary (see below). `prepublishOnly` runs `npm run build`, so the published tarball includes `dist/`.

**Template:** copy [`mcp.json.example`](./mcp.json.example) to **`.cursor/mcp.json`** in your project (or merge the `specify` entry into your existing file). It uses **`@firestitch/specify-mcp@latest`** so `npx` targets the newest published version; set `SPECIFY_API_*` in your shell or system environment (Cursor interpolates `${env:…}`).

## Client setup (Cursor, VS Code, Claude Code CLI)

Where MCP config lives, naming rules, how to create Specify API keys, how to start or reconnect the server in each client, and how **`@latest`** plus cache clearing affects updates.

Stdio mode reads **`SPECIFY_API_URL`**, **`SPECIFY_API_KEY`**, and **`SPECIFY_API_SECRET`** from the environment the client passes to the process.

### Specify API key and secret

1. Open [Specify — Accounts](https://fs.specify.com/admin/accounts/accounts).
2. Open the appropriate **account**.
3. Open the **Keys** tab.
4. Click **Create** and copy the **API key** and **API secret** into your MCP configuration (or into secure env vars referenced by the config).

Treat these like passwords. Do not commit real keys to git.

For HTTP modes (below), generate keys from **Account > API Keys** in Specify as well.

### Cursor

**File name:** always **`mcp.json`**. Cursor expects a top-level object **`mcpServers`** ([Cursor MCP docs](https://cursor.com/docs/context/mcp)).

| Scope | Path | Notes |
|--------|------|--------|
| **Project** | **`<repo>/.cursor/mcp.json`** | Applies when that folder is the workspace root. |
| **User (all projects)** | **`~/.cursor/mcp.json`** | Same JSON shape (`mcpServers`). |

**Sample (recommended: clear npx cache + `@latest`):** Cursor cannot choose the shell per OS, so pick the block that matches your machine. The **`env`** block is the same on every platform.

**Linux and macOS** (`bash` is usually already on `PATH`):

```json
{
  "mcpServers": {
    "specify": {
      "command": "bash",
      "args": [
        "-c",
        "npx clear-npx-cache && npx -y --package @firestitch/specify-mcp@latest specify-mcp"
      ],
      "env": {
        "SPECIFY_API_URL": "https://fs.specify.com/api/",
        "SPECIFY_API_KEY": "",
        "SPECIFY_API_SECRET": ""
      }
    }
  }
}
```

**Windows** (Command Prompt / default Windows shell — `cmd` with `/c`):

```json
{
  "mcpServers": {
    "specify": {
      "command": "cmd",
      "args": [
        "/c",
        "npx clear-npx-cache >nul 2>&1 && npx -y --package @firestitch/specify-mcp@latest specify-mcp"
      ],
      "env": {
        "SPECIFY_API_URL": "https://fs.specify.com/api/",
        "SPECIFY_API_KEY": "",
        "SPECIFY_API_SECRET": ""
      }
    }
  }
}
```

- **`specify`** is the **server id** in the UI; use a short, unique name (no spaces). Multiple entries are allowed under `mcpServers`.
- On **Windows**, if **Git Bash** or **WSL** puts `bash` on your `PATH`, you can use the **Linux and macOS** sample instead of `cmd`.
- To skip cache clearing (simpler, but stale `npx` cache can affect `@latest`), use [`mcp.json.example`](./mcp.json.example): `command` **`npx`** with `args` **`["-y", "--package", "@firestitch/specify-mcp@latest", "specify-mcp"]`** — same JSON on all platforms.

**Cursor: settings and MCP**

1. Open **Settings** (**Ctrl+,** / **Cmd+,**) or **Cursor → Settings**.
2. Go to **Features → Model Context Protocol** (MCP).
3. Enable or toggle your server; after editing **`mcp.json`**, restart the MCP server or reload the window if tools do not appear.

**Logs:** **View → Output** → **MCP** / **MCP Logs**.

Secrets out of the file ([Cursor interpolation](https://cursor.com/docs/context/mcp), same pattern as [`mcp.json.example`](./mcp.json.example)):

```json
"env": {
  "SPECIFY_API_URL": "${env:SPECIFY_API_URL}",
  "SPECIFY_API_KEY": "${env:SPECIFY_API_KEY}",
  "SPECIFY_API_SECRET": "${env:SPECIFY_API_SECRET}"
}
```

Use an absolute path in `args` if the package lives outside the project. Paths like `"${workspaceFolder}/node_modules/..."` work per Cursor docs.

### VS Code (GitHub Copilot MCP)

VS Code uses **`mcp.json`** but the top-level key is **`servers`**, and stdio entries should include **`"type": "stdio"`** ([VS Code MCP reference](https://code.visualstudio.com/docs/copilot/reference/mcp-configuration)).

| Scope | How to open / path |
|--------|---------------------|
| **Workspace** | **`<repo>/.vscode/mcp.json`** or **“MCP: Open Workspace Folder MCP Configuration”**. |
| **User** | **“MCP: Open User Configuration”** (profile-specific). |

Clear npx cache + `@latest`: use **`bash`** on Linux/macOS and **`cmd`** on Windows (same idea as Cursor above).

**Linux and macOS:**

```json
{
  "servers": {
    "specify": {
      "type": "stdio",
      "command": "bash",
      "args": [
        "-c",
        "npx clear-npx-cache && npx -y --package @firestitch/specify-mcp@latest specify-mcp"
      ],
      "env": {
        "SPECIFY_API_URL": "https://fs.specify.com/api/",
        "SPECIFY_API_KEY": "",
        "SPECIFY_API_SECRET": ""
      }
    }
  }
}
```

**Windows** (`cmd`):

```json
{
  "servers": {
    "specify": {
      "type": "stdio",
      "command": "cmd",
      "args": [
        "/c",
        "npx clear-npx-cache >nul 2>&1 && npx -y --package @firestitch/specify-mcp@latest specify-mcp"
      ],
      "env": {
        "SPECIFY_API_URL": "https://fs.specify.com/api/",
        "SPECIFY_API_KEY": "",
        "SPECIFY_API_SECRET": ""
      }
    }
  }
}
```

Use **camelCase** server names, no spaces, unique per file.

**Start / stop / reconnect:** Command Palette (**Ctrl+Shift+P** / **Cmd+Shift+P**) → type **`MCP:`** → **“MCP: List Servers”** (start, stop, restart, show output). If your team says “Cloud Code,” MCP in VS Code is under **GitHub Copilot / MCP**, not the Google Cloud Code extension.

### Claude Code CLI

MCP is configured with **`claude mcp`** ([Claude Code MCP docs](https://docs.claude.com/en/docs/claude-code/mcp)). Options must come **before** the server name; **`--`** separates the name from the command.

```bash
claude mcp add --transport stdio \
  --env SPECIFY_API_URL=https://fs.specify.com/api/ \
  --env SPECIFY_API_KEY=your-key \
  --env SPECIFY_API_SECRET=your-secret \
  specify -- \
  bash -c "npx clear-npx-cache && npx -y --package @firestitch/specify-mcp@latest specify-mcp"
```

Use **`--scope user`** for all projects or **`--scope project`** for a team-shared **`.mcp.json`** (see Claude Code docs for current scope names).

```bash
claude mcp list
claude mcp get specify
claude mcp remove specify
```

Inside a session, **`/mcp`** covers MCP status and OAuth where applicable.

Local checkout instead of npx:

```bash
claude mcp add --transport stdio specify -- node /path/to/specify/mcp/dist/index.js
```

**Windows (native):** `npx`-based stdio servers may need a **`cmd /c`** wrapper. If you see connection errors, use e.g. `cmd /c npx -y --package @firestitch/specify-mcp@latest specify-mcp` with the same `--env` flags.

### Getting the latest `@firestitch/specify-mcp` version

1. **`@firestitch/specify-mcp@latest`** — `npx` resolves the **latest** dist-tag on npm.
2. **`npx clear-npx-cache`** — reduces the chance a cached copy sticks.

Each MCP **start** runs a new process, so that full command runs again; **`clear-npx-cache`** in the chain usually gives a cleaner pull than **`npx` alone**. After a new npm release, **restart the MCP server** (or the app). If it still looks stale, run **`npx clear-npx-cache`** once, or **`npm cache clean --force`** ([Cursor MCP FAQ](https://cursor.com/docs/context/mcp)).

## Monorepo / clone setup

```bash
cd mcp
npm install
npm run build
```

**Default transport is stdio** (no `SPECIFY_TRANSPORT` env). The editor runs the server on your machine; put **Specify URL + API keys in the same MCP config** as `env` (see [Client setup](#client-setup-cursor-vs-code-claude-code-cli) above). Paths resolve from the workspace `cwd`.

**After successful auth (stdio only),** the server applies a one-time workspace init: ensures `.specify/`, merges `.vscode/settings.json` (open `**/.specify/**/*.md` in markdown preview, set `markdown.mermaid.enabled` if unset), and merges `.vscode/extensions.json` with **bierner.markdown-mermaid** recommended. Set `SPECIFY_MCP_SKIP_WORKSPACE_INIT=1` to disable. Remote HTTP MCP does not run this on the developer’s laptop.

Set **`SPECIFY_TRANSPORT=http`** when you want a standalone HTTP server (local dev below, or hosting behind nginx).

### Running

**Development** — watches for changes and auto-reloads an **HTTP** server on `http://localhost:3100` (scripts set `SPECIFY_TRANSPORT=http`):

| Command | API URL |
|---------|---------|
| `npm run serve:local` | `http://specify.local.firestitch.com/api/` |
| `npm run serve:development` | `https://specify.firestitch.dev/api/` |
| `npm run serve:staging` | `https://specify.staging.firestitch.com/api/` |
| `npm run serve:production` | `https://fs.specify.com/api/` |

**Production** — builds once and runs the compiled output as **HTTP** on port 3100:

| Command | API URL |
|---------|---------|
| `npm run start:staging` | `https://specify.staging.firestitch.com/api/` |
| `npm run start:production` | `https://fs.specify.com/api/` |

For those HTTP modes, clients send credentials with `X-Api-Key` and `X-Api-Secret` on each connection. Generate keys from **Account > API Keys** in Specify (or the **Keys** tab under [Accounts](https://fs.specify.com/admin/accounts/accounts); see [Client setup](#client-setup-cursor-vs-code-claude-code-cli)).

### HTTP transport (local testing or hosted)

Point the client at the server URL and pass headers (stdio `env` is not used for HTTP):

**Cursor**

```json
{
  "mcpServers": {
    "specify": {
      "url": "http://localhost:3100",
      "headers": {
        "X-Api-Key": "your-api-key",
        "X-Api-Secret": "your-api-secret"
      }
    }
  }
}
```

**Claude Code**

```bash
claude mcp add --transport http specify http://localhost:3100 \
  --header "X-Api-Key: your-api-key" \
  --header "X-Api-Secret: your-api-secret"
```

#### Remote / hosted HTTP server

Hosted deployments must run with **`SPECIFY_TRANSPORT=http`**. Clients use the public origin (no `/api/` path in the MCP URL unless your proxy is configured that way):

```json
{
  "mcpServers": {
    "specify": {
      "url": "https://specify.staging.firestitch.com",
      "headers": {
        "X-Api-Key": "your-api-key",
        "X-Api-Secret": "your-api-secret"
      }
    }
  }
}
```

## Architecture

```
src/
  index.ts              Entry point, transport selection, tool registration
  workspace-init.ts     Local .specify/ + .vscode merge (stdio after auth)
  transport/http.ts     Express + StreamableHTTPServerTransport
  api/client.ts         HTTP client with Bearer token auth
  auth/session.ts       Authentication manager
  config/
    credentials.ts      SPECIFY_API_* env (from MCP client)
    project.ts          .specify.json auto-detection
  state/session.ts      Session state (project, plan, task)
  guides/loader.ts      Loads markdown guides for learning tools
  tools/                One module per domain + discovery, guidance, selection
  resources/            MCP Resources (browsable project data)
  prompts/              MCP Prompts (workflow templates)
  validation/           Input validation and field aliasing
guides/                 Domain documentation loaded at runtime
```

Domains, prompts, and resources are self-documented by the MCP server. Use `specify_list_domains` to discover available domains and their tools.