# SpotDraft MCP Server

Integrate the SpotDraft API into agentic workflows via MCP.

**npm:** [![npm version](https://img.shields.io/npm/v/@spotdraft/spotdraft-mcp.svg)](https://www.npmjs.com/package/@spotdraft/spotdraft-mcp) — release notes: [CHANGELOG.md](CHANGELOG.md).

> **Alpha Software** — not covered by any support SLA. Do not use in production.

## Tools

### Contract Management

- `get_contract_list` — List contracts (filters include **`contract_id`** with `$eq` / `$in` for one or more composite IDs)
- `get_contract_download_link` — Get a contract download link
- `get_contract_status` — Get contract status
- `get_contract_activity_log` — Get activity log (comments)
- `get_contract_approvals` — Get contract approvals
- `get_contract_key_pointers` — Get contract key pointers

### Write Tools (require write mode)

These tools are only listed and callable when write mode is enabled (see [Write capabilities](#write-capabilities)):

- `upload_contract_version` — Upload a new contract version (PDF) for an existing contract
- `send_contract_to_counterparties` — Send the contract to counterparties by email
- `create_contract_approvals` — Create and send adhoc approval requests for a contract
- `add_contract_comment` — Add a comment to the contract activity log

### Template Management

- `get_templates` — List templates
- `get_template_details` — Get template details
- `get_template_metadata` — Get template metadata

### Counter Party Management

- `get_counter_parties` — List counter parties
- `get_counter_party_details` — Get counter party details

### Facet Discovery

- `get_workspace_facets` — Retrieves available search facets for filtering and searching contracts in the workspace
- `get_workspace_facet_options` — Gets facet options for contract search filtering

### Other

- `get_key_pointers` — Retrieves key pointers
- `get_contract_types` — Retrieves available contract types

## Setup

### Prerequisites

- Node.js 20+
- SpotDraft API credentials (Client ID and Client Secret)

### Environment Variables

#### Required (Stdio Mode)

| Variable                  | Description                 |
| ------------------------- | --------------------------- |
| `SPOTDRAFT_CLIENT_ID`     | SpotDraft API Client ID     |
| `SPOTDRAFT_CLIENT_SECRET` | SpotDraft API Client Secret |

#### Required (HTTP Mode)

| Variable            | Description                                                     |
| ------------------- | --------------------------------------------------------------- |
| `SERVER_PUBLIC_URL` | Public URL of this MCP server (e.g., `https://mcp.example.com`) |

#### Optional

| Variable               | Description                                                                                                                                                              | Default                         |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------- |
| `SPOTDRAFT_BASE_URL`   | SpotDraft API base URL                                                                                                                                                   | `https://api.spotdraft.com/api` |
| `SPOTDRAFT_USER_EMAIL` | User email for scoping requests                                                                                                                                          | —                               |
| `LOG_LEVEL`            | `debug`, `info`, `warn`, or `error`                                                                                                                                      | `info`                          |
| `SD_MCP_ENABLE_WRITE`  | Enable write tools. Set to `true`, `1`, or `yes` (case-insensitive). When set, write tools (upload version, send contract, approvals, comments) are listed and callable. | —                               |

#### OAuth 2.0 (Optional — enables [OAuth support](#oauth-20-authorization))

| Variable                         | Description                           | Default             |
| -------------------------------- | ------------------------------------- | ------------------- |
| `OAUTH_AUTHORIZATION_SERVER_URL` | OAuth Authorization Server URL        | —                   |
| `OAUTH_JWKS_URI`                 | JWKS URI for JWT signature validation | —                   |
| `OAUTH_AUDIENCE`                 | Expected audience claim in tokens     | `SERVER_PUBLIC_URL` |

## Installation & Usage

### Option 1: NPX (Recommended)

```bash
npx @spotdraft/spotdraft-mcp
```

#### Claude Desktop — Stdio Mode

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "spotdraft": {
      "command": "npx",
      "args": ["@spotdraft/spotdraft-mcp"],
      "env": {
        "SPOTDRAFT_CLIENT_ID": "<YOUR_CLIENT_ID>",
        "SPOTDRAFT_CLIENT_SECRET": "<YOUR_CLIENT_SECRET>",
        "SPOTDRAFT_BASE_URL": "<SPOTDRAFT_BASE_URL>"
      }
    }
  }
}
```

#### Claude Desktop — HTTP Mode

Start the server separately with `node build/index.js --http`, then add:

```json
{
  "mcpServers": {
    "streamable-http-spotdraft": {
      "type": "streamable-http",
      "url": "http://localhost:3000/mcp?baseUrl=https%3A%2F%2Fapi.us.spotdraft.com%2Fapi"
    }
  }
}
```

To enable write tools (upload version, send contract, approvals, comments), append `&enable_write=true` to the URL or set `SD_MCP_ENABLE_WRITE=true` in the server environment.

### Option 2: Local Development

```bash
git clone https://github.com/spotdraft/spotdraft-mcp.git
cd spotdraft-mcp
npm install
npm run build
export SPOTDRAFT_CLIENT_ID="your_client_id"
export SPOTDRAFT_CLIENT_SECRET="your_client_secret"
# Required: set SERVER_PUBLIC_URL or startup fails with ZodError (server.publicUrl expected string, received undefined)
export SERVER_PUBLIC_URL="http://localhost:3000"
npm start
```

For HTTP mode, start with: `SERVER_PUBLIC_URL=http://localhost:3000 node build/index.js --http` (or set the env var before `npm start` and pass `--http`).

### Option 3: Docker

```bash
# Build
docker build -t spotdraft-mcp .

# Run — stdio mode (default)
docker run -e SPOTDRAFT_CLIENT_ID=your_client_id -e SPOTDRAFT_CLIENT_SECRET=your_client_secret spotdraft-mcp

# Run — HTTP mode
docker run -p 3000:3000 \
  -e SPOTDRAFT_CLIENT_ID=your_client_id \
  -e SPOTDRAFT_CLIENT_SECRET=your_client_secret \
  -e SPOTDRAFT_BASE_URL=https://api.us.spotdraft.com/api \
  spotdraft-mcp node build/index.js --http
```

## Server Modes

**Stdio (default)** — Used by MCP clients like Claude Desktop. Communicates over stdin/stdout. Logs go to stderr in JSON format.

**HTTP** (`--http` flag) — Exposes REST endpoints for web integrations. Logs go to stdout in human-readable format.

| Endpoint  | Method | Description    |
| --------- | ------ | -------------- |
| `/health` | GET    | Health check   |
| `/mcp`    | POST   | MCP tool calls |

## Write capabilities

Write tools (`upload_contract_version`, `send_contract_to_counterparties`, `create_contract_approvals`, `add_contract_comment`) are **disabled by default**. They are only listed in `tools/list` and only executable when write mode is on.

### Enabling write mode

- **HTTP mode** — Use either:
  - Query parameter: call the MCP URL with `enable_write=true` (e.g. `http://localhost:3000/mcp?enable_write=true` or `.../mcp?baseUrl=...&enable_write=true`), or
  - Environment variable: set `SD_MCP_ENABLE_WRITE=true` (or `1` / `yes`, case-insensitive) when starting the server.
- **Stdio mode** — Set `SD_MCP_ENABLE_WRITE=true` (or `1` / `yes`) in the environment where the server runs (e.g. in your Claude Desktop config `env`).

If a client calls a write tool while write mode is off, the server responds with `403` and error code `WRITE_DISABLED` and a message explaining how to enable write.

## OAuth 2.0 Authorization

Optional [MCP Authorization Spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) compliant OAuth 2.0 support. The server acts as an OAuth 2.0 Protected Resource (RFC 9728).

> OAuth is fully backward-compatible — existing Basic Auth integrations continue working.

### Authentication Methods

**Basic Auth** — Send `clientId:clientSecret` as the Bearer token:

```bash
curl -X POST http://localhost:3000/mcp \
  -H "Authorization: Bearer clientId:clientSecret" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
```

**OAuth Bearer Token** — Send a JWT from an Authorization Server:

```bash
curl -X POST http://localhost:3000/mcp \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
```

The server auto-detects: tokens containing `:` use Basic Auth; JWT-formatted tokens (3 dot-separated parts) use OAuth.

### Protected Resource Metadata

When `OAUTH_AUTHORIZATION_SERVER_URL` is set, the server exposes:

```
GET /.well-known/oauth-protected-resource
```

```json
{
  "resource": "https://your-mcp-server.com",
  "authorization_servers": ["https://your-auth-server.com"],
  "resource_name": "SpotDraft MCP Server"
}
```

### Example Configuration

**Production:**

```bash
SERVER_PUBLIC_URL=https://mcp.spotdraft.com
OAUTH_AUTHORIZATION_SERVER_URL=https://api.spotdraft.com
OAUTH_JWKS_URI=https://api.spotdraft.com/.well-known/jwks.json
OAUTH_AUDIENCE=https://mcp.spotdraft.com
SPOTDRAFT_BASE_URL=https://api.spotdraft.com/api
```

**Development:**

```bash
SERVER_PUBLIC_URL=http://localhost:3000
OAUTH_AUTHORIZATION_SERVER_URL=http://localhost:8000/api/v1/oauth
OAUTH_JWKS_URI=https://api.dev.spotdraft.com/.well-known/jwks.json
OAUTH_AUDIENCE=https://api.spotdraft.com
SPOTDRAFT_BASE_URL=https://api.in.dev.spotdraft.com/api
```

## Development

```bash
npm run build       # Compile TypeScript
npm run watch       # Watch mode
npm run inspector   # MCP inspector for debugging
```

### Project Structure

```
src/
├── index.ts                 # Entry point
├── handler.ts               # Shared request handlers
├── spotdraft_client.ts      # API client
├── auth/                    # Authentication
├── errors/                  # Error types
├── logging/                 # Logging
├── validation/              # Input validation
├── servers/                 # HTTP and stdio servers
└── tools/                   # Tool implementations
    ├── contracts/
    ├── contract-types/
    ├── counter-parties/
    ├── facets/
    ├── key-pointers/
    └── templates/
```

## Changelog

Version history and migration notes: [CHANGELOG.md](CHANGELOG.md).

## License

MIT — see [LICENSE](LICENSE).
