---
title: @specdiff/mcp
description: A Model Context Protocol server that lets coding agents compare schemas and explain rules.
url: https://pr-1-7abef52380a8.thally.app/specdiff-mcp
---

# @specdiff/mcp

A Model Context Protocol server that lets coding agents compare schemas and explain rules.

`@specdiff/mcp` is a stdio MCP server that exposes Specdiff to coding agents
such as Claude Code, Claude Desktop, and Cursor. It registers four tools and
shares the same `@specdiff/core` engine as the CLI and the library.

## Setup

Add the server to your project's `.mcp.json` (Claude Code, Cursor) or
`claude_desktop_config.json` (Claude Desktop):

```json
{
  "mcpServers": {
    "specdiff": {
      "command": "npx",
      "args": ["-y", "@specdiff/mcp"]
    }
  }
}
```

The server reads files relative to the directory it is launched from. Paths that
resolve outside the working directory are rejected with an error. Launch the
server from your project root (MCP clients launched from a project do this by
default).

## Tools

All results are returned as text content containing JSON (or the formatted
report for `specdiff_format`). Failures come back as `isError: true` results
with a human-readable message.

### `specdiff_compare`

Compare two documents — from files or inline text.

| Input field | Type | Description |
| --- | --- | --- |
| `beforePath` | `string` (optional) | Path to the before document, relative to the server's working directory. |
| `afterPath` | `string` (optional) | Path to the after document. |
| `before` | `string` (optional) | Inline JSON or YAML text for the before document. |
| `after` | `string` (optional) | Inline JSON or YAML text for the after document. |
| `kind` | `"auto" \| "openapi" \| "json-schema"` (optional) | Force the document kind. Default: `"auto"`. |
| `failOn` | `"breaking" \| "warning" \| "info" \| "none"` (optional) | Threshold for the `passed` flag. Default: `"breaking"`. |
| `ignoreRules` | `string[]` (optional) | Rule codes to drop from the result. |

Returns the `DiffResult` JSON plus `passed: boolean` (false when a change
reaches `failOn`) and the `failOn` value used.

### `specdiff_explain_rule`

Explain a rule by its code.

| Input field | Type | Description |
| --- | --- | --- |
| `code` | `string` | The rule code to explain. |

Returns the `RuleInfo` JSON, or an error result if the code is not found.

### `specdiff_list_rules`

No inputs. Returns the full rule catalogue as a `RuleInfo[]` JSON array.

### `specdiff_format`

Render a `DiffResult` as human-readable text or Markdown.

| Input field | Type | Description |
| --- | --- | --- |
| `result` | `DiffResult` | The result object to format. |
| `format` | `"text" \| "markdown"` | Output format. |

## Programmatic use

```ts
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { createSpecdiffServer } from "@specdiff/mcp";

const server = createSpecdiffServer({ cwd: process.cwd() });
await server.connect(new StdioServerTransport());
```

### Exported API

| Export | Description |
| --- | --- |
| `createSpecdiffServer(options?)` | Creates an un-connected MCP server with the four tools registered. |
| `resolveInsideCwd(cwd, filePath)` | Resolves a path and throws if it escapes the working directory. |
| `parseDocumentText(text, fileName?)` | Parses JSON or YAML text. |
| `TOOL_NAMES` | `{ compare: "specdiff_compare", explainRule: "specdiff_explain_rule", listRules: "specdiff_list_rules", format: "specdiff_format" }` |

`SpecdiffServerOptions` accepts an optional `cwd` string (defaults to
`process.cwd()`).