> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spitshake.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server

> Let AI agents manage documents and signatures via Model Context Protocol.

# MCP Server

The DocuTrust MCP (Model Context Protocol) server enables AI agents and coding assistants to manage templates, submissions, and signers programmatically. It exposes DocuTrust operations as tools that any MCP-compatible client can call.

## Installation

Run the MCP server directly with npx (no installation required):

```bash theme={null}
npx @docutrust/mcp
```

Or install globally:

```bash theme={null}
npm install -g @docutrust/mcp
```

## Configuration

### Environment Variables

| Variable              | Required | Description                         |
| --------------------- | -------- | ----------------------------------- |
| `DOCUTRUST_API_URL`   | Yes      | Base URL of your DocuTrust instance |
| `DOCUTRUST_API_TOKEN` | Yes      | API token with appropriate scopes   |

### Claude Code

Add the following to your Claude Code MCP configuration (`.claude/mcp.json` or project settings):

```json theme={null}
{
  "mcpServers": {
    "docutrust": {
      "command": "npx",
      "args": ["@docutrust/mcp"],
      "env": {
        "DOCUTRUST_API_URL": "https://spitshake.io",
        "DOCUTRUST_API_TOKEN": "your-api-token"
      }
    }
  }
}
```

### Claude Desktop

Add to your Claude Desktop configuration file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):

```json theme={null}
{
  "mcpServers": {
    "docutrust": {
      "command": "npx",
      "args": ["@docutrust/mcp"],
      "env": {
        "DOCUTRUST_API_URL": "https://spitshake.io",
        "DOCUTRUST_API_TOKEN": "your-api-token"
      }
    }
  }
}
```

### Cursor

Add to your Cursor MCP settings (`.cursor/mcp.json`):

```json theme={null}
{
  "mcpServers": {
    "docutrust": {
      "command": "npx",
      "args": ["@docutrust/mcp"],
      "env": {
        "DOCUTRUST_API_URL": "https://spitshake.io",
        "DOCUTRUST_API_TOKEN": "your-api-token"
      }
    }
  }
}
```

***

## Available Tools

The MCP server exposes tools organized into three tiers based on their impact:

| Tier        | Tools                                                                                                                                                                  | Required Scope                                                                         |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| **READ**    | `list_templates`, `get_template`, `list_submissions`, `get_submission`, `list_submission_documents`, `get_submitter`, `get_audit_trail`, `download_completed_document` | `templates:read`, `submissions:read`                                                   |
| **PREPARE** | `create_draft_submission`, `update_draft_submission`                                                                                                                   | `submissions:draft` or `submissions:write`                                             |
| **BINDING** | `send_submission`, `send_reminder`                                                                                                                                     | `submissions:send` or `submissions:write` (stdio MCP: requires `DOCUTRUST_ALLOW_SEND`) |

### Send tool gating

By default, the binding send tools (`send_submission`, `send_reminder`) are **not registered** in the stdio MCP server. Set the `DOCUTRUST_ALLOW_SEND` environment variable to enable them:

```json theme={null}
{
  "mcpServers": {
    "docutrust": {
      "command": "npx",
      "args": ["@docutrust/mcp"],
      "env": {
        "DOCUTRUST_API_URL": "https://your-instance.com",
        "DOCUTRUST_API_TOKEN": "your-send-scoped-token",
        "DOCUTRUST_ALLOW_SEND": "1"
      }
    }
  }
}
```

Each send tool also requires `confirmed_by_user: true` as a parameter, providing a human confirmation step.

### list\_templates

List all available templates in your account.

**Parameters:**

| Parameter     | Type    | Required | Description                                                   |
| ------------- | ------- | -------- | ------------------------------------------------------------- |
| `limit`       | number  | No       | Maximum number of templates to return (default: 10, max: 100) |
| `after`       | string  | No       | Cursor for pagination                                         |
| `folder_name` | string  | No       | Filter by folder name                                         |
| `external_id` | string  | No       | Filter by external ID                                         |
| `archived`    | boolean | No       | Include archived templates (default: `false`)                 |

**Example response:**

```json theme={null}
{
  "data": [
    {
      "id": 15,
      "name": "Employment Agreement",
      "slug": "abc123def456",
      "folder_name": "HR Documents",
      "created_at": "2026-03-01T10:00:00.000Z",
      "updated_at": "2026-04-01T12:00:00.000Z",
      "external_id": null,
      "source": "native",
      "archived_at": null,
      "submitters": [
        {
          "name": "Recipient",
          "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
        },
        {
          "name": "Sender",
          "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        }
      ],
      "fields": [
        {
          "name": "Full Name",
          "type": "text",
          "required": true,
          "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
        },
        {
          "name": "Signature",
          "type": "signature",
          "required": true,
          "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
        },
        {
          "name": "Date",
          "type": "date",
          "required": true,
          "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
        }
      ]
    }
  ],
  "pagination": {
    "count": 1,
    "next": null,
    "prev": null
  }
}
```

### get\_template

Get detailed information about a specific template.

**Parameters:**

| Parameter     | Type   | Required | Description     |
| ------------- | ------ | -------- | --------------- |
| `template_id` | string | Yes      | The template ID |

**Example response:**

```json theme={null}
{
  "id": 15,
  "name": "Employment Agreement",
  "slug": "abc123def456",
  "folder_name": "HR Documents",
  "created_at": "2026-03-01T10:00:00.000Z",
  "updated_at": "2026-04-01T12:00:00.000Z",
  "external_id": null,
  "source": "native",
  "archived_at": null,
  "submitters": [
    {
      "name": "Recipient",
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    },
    {
      "name": "Sender",
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    }
  ],
  "fields": [
    {
      "name": "Full Name",
      "type": "text",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    },
    {
      "name": "Email",
      "type": "text",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    },
    {
      "name": "Signature",
      "type": "signature",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    },
    {
      "name": "Date",
      "type": "date",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    },
    {
      "name": "Sender Signature",
      "type": "signature",
      "required": true,
      "submitter_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    }
  ],
  "documents": [
    {
      "id": 42,
      "filename": "employment_agreement.pdf",
      "content_type": "application/pdf",
      "page_count": 4,
      "size": 185200
    }
  ]
}
```

### get\_audit\_trail

Get account-wide compliance audit log entries.

**Parameters:**

| Parameter    | Type   | Required | Description                    |
| ------------ | ------ | -------- | ------------------------------ |
| `event_type` | string | No       | Filter by event type           |
| `from`       | string | No       | Start date (ISO 8601)          |
| `to`         | string | No       | End date (ISO 8601)            |
| `per_page`   | number | No       | Results per page (default: 25) |

### download\_completed\_document

Download a signed PDF for a completed submission. Available in stdio MCP only.

**Parameters:**

| Parameter       | Type   | Required | Description                                       |
| --------------- | ------ | -------- | ------------------------------------------------- |
| `submission_id` | number | Yes      | The submission ID                                 |
| `document_id`   | number | No       | Specific document ID (defaults to first document) |

### list\_submission\_documents

List generated documents for a submission.

**Parameters:**

| Parameter       | Type   | Required | Description       |
| --------------- | ------ | -------- | ----------------- |
| `submission_id` | number | Yes      | The submission ID |

### create\_draft\_submission

Create a draft submission from a template. No emails are sent until the draft is explicitly sent.

**Parameters:**

| Parameter             | Type   | Required | Description                         |
| --------------------- | ------ | -------- | ----------------------------------- |
| `template_id`         | string | Yes      | The template to create a draft from |
| `submitters`          | array  | Yes      | Array of submitter objects          |
| `submitters[].email`  | string | Yes      | Submitter email address             |
| `submitters[].name`   | string | No       | Submitter name                      |
| `submitters[].role`   | string | No       | Role name matching the template     |
| `submitters[].values` | object | No       | Pre-filled field values             |
| `metadata`            | object | No       | Custom metadata for the submission  |

### update\_draft\_submission

Edit a draft submission before sending. Only works on submissions with `draft` status.

**Parameters:**

| Parameter       | Type   | Required | Description               |
| --------------- | ------ | -------- | ------------------------- |
| `submission_id` | number | Yes      | The draft submission ID   |
| `submitters`    | array  | No       | Updated submitter objects |
| `metadata`      | object | No       | Updated metadata          |
| `expire_at`     | string | No       | ISO 8601 expiration date  |

### send\_submission

Send a draft submission for signing. This is a legally binding action. Only available when `DOCUTRUST_ALLOW_SEND` is set (stdio MCP) or the token has `submissions:send` scope (remote MCP).

**Parameters:**

| Parameter           | Type    | Required | Description                               |
| ------------------- | ------- | -------- | ----------------------------------------- |
| `submission_id`     | number  | Yes      | The draft submission ID to send           |
| `confirmed_by_user` | boolean | Yes      | Must be `true` to confirm the send action |
| `message`           | object  | No       | Custom email message                      |
| `message.subject`   | string  | No       | Email subject line                        |
| `message.body`      | string  | No       | Email body                                |

### create\_submission

Create a new submission from a template and send it to recipients for signing.

**Parameters:**

| Parameter                 | Type    | Required | Description                                  |
| ------------------------- | ------- | -------- | -------------------------------------------- |
| `template_id`             | string  | Yes      | The template to create a submission from     |
| `send_email`              | boolean | No       | Send invitation emails (default: `true`)     |
| `submitters_order`        | string  | No       | `random` or `sequential` (default: `random`) |
| `submitters`              | array   | Yes      | Array of submitter objects                   |
| `submitters[].email`      | string  | Yes      | Submitter email address                      |
| `submitters[].name`       | string  | No       | Submitter name                               |
| `submitters[].role`       | string  | No       | Role name matching the template              |
| `submitters[].phone`      | string  | No       | Phone number for SMS                         |
| `submitters[].values`     | object  | No       | Pre-filled field values                      |
| `submitters[].metadata`   | object  | No       | Custom metadata                              |
| `submitters[].send_email` | boolean | No       | Send email to this submitter                 |
| `submitters[].send_sms`   | boolean | No       | Send SMS to this submitter                   |
| `message`                 | object  | No       | Custom email message                         |
| `message.subject`         | string  | No       | Email subject line                           |
| `message.body`            | string  | No       | Email body (supports merge tokens)           |
| `expire_at`               | string  | No       | ISO 8601 expiration date                     |
| `metadata`                | object  | No       | Custom metadata for the submission           |

**Example response:**

```json theme={null}
{
  "id": 90,
  "template_id": 15,
  "status": "pending",
  "source": "api",
  "submitters_order": "random",
  "created_at": "2026-04-09T16:00:00.000Z",
  "completed_at": null,
  "archived_at": null,
  "expire_at": null,
  "metadata": {},
  "submitters": [
    {
      "id": 144,
      "email": "signer@example.com",
      "name": "Jane Doe",
      "role": "Recipient",
      "status": "sent",
      "slug": "cD5eF7gHiJ",
      "signing_url": "https://spitshake.io/s/cD5eF7gHiJ",
      "sent_at": "2026-04-09T16:00:01.000Z",
      "opened_at": null,
      "completed_at": null,
      "phone": null,
      "values": {},
      "metadata": {}
    }
  ]
}
```

### create\_submissions\_from\_emails

Create multiple submissions at once from a comma-separated list of email addresses. Each email gets its own submission.

**Parameters:**

| Parameter         | Type    | Required | Description                              |
| ----------------- | ------- | -------- | ---------------------------------------- |
| `template_id`     | string  | Yes      | The template to use                      |
| `emails`          | string  | Yes      | Comma-separated email addresses          |
| `send_email`      | boolean | No       | Send invitation emails (default: `true`) |
| `message`         | object  | No       | Custom email message                     |
| `message.subject` | string  | No       | Email subject                            |
| `message.body`    | string  | No       | Email body                               |

**Example response:**

```json theme={null}
{
  "submissions": [
    {
      "id": 91,
      "template_id": 15,
      "status": "pending",
      "submitters": [
        {
          "id": 145,
          "email": "signer1@example.com",
          "role": "Recipient",
          "status": "sent",
          "slug": "kL8mN0pQrS",
          "signing_url": "https://spitshake.io/s/kL8mN0pQrS"
        }
      ]
    },
    {
      "id": 92,
      "template_id": 15,
      "status": "pending",
      "submitters": [
        {
          "id": 146,
          "email": "signer2@example.com",
          "role": "Recipient",
          "status": "sent",
          "slug": "tU2vW4xYzA",
          "signing_url": "https://spitshake.io/s/tU2vW4xYzA"
        }
      ]
    }
  ]
}
```

### get\_submission

Get detailed information about a specific submission.

**Parameters:**

| Parameter       | Type   | Required | Description       |
| --------------- | ------ | -------- | ----------------- |
| `submission_id` | number | Yes      | The submission ID |

**Example response:**

```json theme={null}
{
  "id": 89,
  "template_id": 15,
  "status": "completed",
  "source": "api",
  "submitters_order": "random",
  "created_at": "2026-04-09T09:00:00.000Z",
  "completed_at": "2026-04-09T15:45:30.000Z",
  "archived_at": null,
  "expire_at": null,
  "metadata": {
    "deal_id": "deal_291"
  },
  "template": {
    "id": 15,
    "name": "Employment Agreement"
  },
  "submitters": [
    {
      "id": 142,
      "email": "jane.doe@example.com",
      "name": "Jane Doe",
      "role": "Recipient",
      "status": "completed",
      "slug": "aB3kL9mNpQ",
      "sent_at": "2026-04-09T10:00:00.000Z",
      "opened_at": "2026-04-09T14:28:05.000Z",
      "completed_at": "2026-04-09T14:32:18.000Z",
      "phone": "+15551234567",
      "values": {
        "Full Name": "Jane Doe",
        "Email": "jane.doe@example.com",
        "Company": "Acme Inc",
        "Title": "VP of Operations",
        "Date": "2026-04-09"
      },
      "metadata": {
        "customer_id": "cust_8472"
      }
    },
    {
      "id": 143,
      "email": "hr@example.com",
      "name": "HR Department",
      "role": "Sender",
      "status": "completed",
      "slug": "bC4dE6fGhI",
      "sent_at": "2026-04-09T14:33:00.000Z",
      "opened_at": "2026-04-09T15:40:10.000Z",
      "completed_at": "2026-04-09T15:45:30.000Z",
      "phone": null,
      "values": {},
      "metadata": {}
    }
  ],
  "documents": [
    {
      "name": "Employment Agreement - Fully Executed",
      "url": "https://spitshake.io/blobs/proxy/eyJfcm...",
      "content_type": "application/pdf",
      "size": 312450
    }
  ],
  "audit_log_url": "https://spitshake.io/submissions/89/audit_log"
}
```

### list\_submissions

List submissions with optional filtering.

**Parameters:**

| Parameter         | Type   | Required | Description                                          |
| ----------------- | ------ | -------- | ---------------------------------------------------- |
| `template_id`     | string | No       | Filter by template                                   |
| `status`          | string | No       | Filter by status: `pending`, `completed`, `archived` |
| `limit`           | number | No       | Maximum results (default: 10, max: 100)              |
| `after`           | string | No       | Pagination cursor                                    |
| `template_folder` | string | No       | Filter by template folder name                       |
| `external_id`     | string | No       | Filter by external ID                                |

**Example response:**

```json theme={null}
{
  "data": [
    {
      "id": 89,
      "template_id": 15,
      "status": "completed",
      "source": "api",
      "submitters_order": "random",
      "created_at": "2026-04-09T09:00:00.000Z",
      "completed_at": "2026-04-09T15:45:30.000Z",
      "archived_at": null,
      "expire_at": null,
      "metadata": {
        "deal_id": "deal_291"
      },
      "template": {
        "id": 15,
        "name": "Employment Agreement"
      },
      "submitters": [
        {
          "id": 142,
          "email": "jane.doe@example.com",
          "name": "Jane Doe",
          "role": "Recipient",
          "status": "completed",
          "completed_at": "2026-04-09T14:32:18.000Z"
        }
      ]
    }
  ],
  "pagination": {
    "count": 1,
    "next": null,
    "prev": null
  }
}
```

### send\_reminder

Send a reminder email to a submitter who has not yet completed signing.

**Parameters:**

| Parameter      | Type   | Required | Description             |
| -------------- | ------ | -------- | ----------------------- |
| `submitter_id` | number | Yes      | The submitter to remind |

**Example response:**

```json theme={null}
{
  "success": true,
  "message": "Reminder sent to jane.doe@example.com",
  "submitter": {
    "id": 142,
    "email": "jane.doe@example.com",
    "name": "Jane Doe",
    "role": "Recipient",
    "status": "sent"
  }
}
```

### get\_submitter

Get detailed information about a specific submitter.

**Parameters:**

| Parameter      | Type   | Required | Description      |
| -------------- | ------ | -------- | ---------------- |
| `submitter_id` | number | Yes      | The submitter ID |

**Example response:**

```json theme={null}
{
  "id": 142,
  "submission_id": 89,
  "email": "jane.doe@example.com",
  "name": "Jane Doe",
  "role": "Recipient",
  "status": "completed",
  "slug": "aB3kL9mNpQ",
  "signing_url": "https://spitshake.io/s/aB3kL9mNpQ",
  "phone": "+15551234567",
  "sent_at": "2026-04-09T10:00:00.000Z",
  "opened_at": "2026-04-09T14:28:05.000Z",
  "completed_at": "2026-04-09T14:32:18.000Z",
  "declined_at": null,
  "external_id": null,
  "values": {
    "Full Name": "Jane Doe",
    "Email": "jane.doe@example.com",
    "Company": "Acme Inc",
    "Title": "VP of Operations",
    "Date": "2026-04-09",
    "Signature": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  },
  "metadata": {
    "customer_id": "cust_8472",
    "deal_id": "deal_291"
  },
  "documents": [
    {
      "name": "Employment Agreement - Signed",
      "url": "https://spitshake.io/blobs/proxy/eyJfcm...",
      "content_type": "application/pdf",
      "size": 284716
    }
  ]
}
```

***

## Usage Examples

Once the MCP server is connected, you can use natural language to interact with DocuTrust through your AI assistant.

### List templates

> "Show me all my DocuTrust templates"

The agent calls `list_templates` and presents the results.

### Send a document for signing

> "Send the Employment Agreement template to [jane@example.com](mailto:jane@example.com) for signing"

The agent calls `create_submission` with the template ID and submitter email.

### Check submission status

> "What's the status of submission 89?"

The agent calls `get_submission` with the submission ID and reports back.

### Bulk send

> "Send the NDA template to [alice@example.com](mailto:alice@example.com), [bob@example.com](mailto:bob@example.com), and [carol@example.com](mailto:carol@example.com)"

The agent calls `create_submissions_from_emails` with the template ID and email list.

### Send a reminder

> "Remind submitter 142 to sign their document"

The agent calls `send_reminder` with the submitter ID.

***

## Remote MCP endpoint

For hosted AI agents that can't spawn a local process, SpitShake provides a remote MCP endpoint at `POST /mcp`.

### Authentication

Use a scoped API token or OAuth access token via `Authorization: Bearer <token>`.

### Protocol

The endpoint speaks JSON-RPC 2.0. Supported methods: `initialize`, `tools/list`, `tools/call`, `ping`.

```bash theme={null}
# List available tools
curl -X POST https://your-instance.com/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

# Call a tool
curl -X POST https://your-instance.com/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_templates","arguments":{"limit":5}}}'
```

### Scope-gated tools

Tools are only visible when the token carries the required scope. A read-only token (`templates:read`, `submissions:read`) sees 6 READ tools. Adding `submissions:draft` reveals the PREPARE tools. Adding `submissions:send` reveals the BINDING tools.

The remote MCP includes all 10 tools from the stdio MCP plus write tools that use direct model operations (create/update drafts, send submissions, send reminders).

***

## Security

* The MCP server uses your API token for authentication. All operations are scoped to the token's permissions.
* The server runs locally on your machine and communicates with DocuTrust over HTTPS.
* API tokens should be stored in environment variables, not hardcoded in configuration files that are committed to version control.
* Use tokens with the minimum required scopes for your use case.

<Warning>
  Never share your API token or commit it to a public repository. Use environment variables or a secrets manager to store tokens securely.
</Warning>
