Docs

Docs / Start / AI assistants (MCP)

AI assistants (MCP)

SignSealer is a remote MCP server at https://api.signsealer.com/mcp. Connect it to Claude, ChatGPT, Codex, Claude Code, Cursor or VS Code, and ask: "send the rental agreement to Ada Lovelace", "who still hasn't signed tomorrow's waivers?", "remind them".

The Model Context Protocol is how an assistant is given tools. Ours are the API: each tool makes the same /v1 call a key would, with the same scopes, limits and answers, so an assistant can do exactly what the person who connected it allowed and nothing the API would refuse.

Connect it

Every client below signs in the same way: it opens SignSealer's sign-in, you choose the business, see what it is asking for, and press Connect. There is no key to copy. You need the permission to manage API keys in that business, which owners and admins have (Teams, roles and sign-in). You can disconnect it at any time under Integrations → Connected apps, and it stops that minute.

Claude (claude.ai and Claude Desktop)

Settings → Connectors → Add custom connector. Name it SignSealer, give the URL https://api.signsealer.com/mcp, and press Connect.

ChatGPT

Settings → Apps & Connectors. With developer mode on, create a connector with the URL https://api.signsealer.com/mcp and OAuth as its authentication.

Claude Code

claude mcp add --transport http signsealer https://api.signsealer.com/mcp

Then /mcp in a session to sign in.

Codex

In ~/.codex/config.toml:

[mcp_servers.signsealer]
url = "https://api.signsealer.com/mcp"
codex mcp login signsealer

Cursor

In ~/.cursor/mcp.json for every project, or .cursor/mcp.json in one:

{
  "mcpServers": {
    "signsealer": { "url": "https://api.signsealer.com/mcp" }
  }
}

Cursor signs in when it first connects. To add it in one step instead, open this link in a browser on the computer Cursor is on:

cursor://anysphere.cursor-deeplink/mcp/install?name=signsealer&config=eyJ1cmwiOiJodHRwczovL2FwaS5zaWduc2VhbGVyLmNvbS9tY3AifQ==

VS Code

In .vscode/mcp.json in a workspace, or in your own mcp.json (the command MCP: Open User Configuration):

{
  "servers": {
    "signsealer": { "type": "http", "url": "https://api.signsealer.com/mcp" }
  }
}

VS Code shows Start above the server, and signs in when it starts.

Anything else

A client that speaks MCP over HTTP finds the sign-in by itself from the URL:

{
  "mcpServers": {
    "signsealer": { "url": "https://api.signsealer.com/mcp" }
  }
}

One that cannot sign in can send an API key instead, from Integrations → API keys with signing:read and signing:write, as a header:

{
  "mcpServers": {
    "signsealer": {
      "url": "https://api.signsealer.com/mcp",
      "headers": { "Authorization": "Bearer ${env:SIGNSEALER_KEY}" }
    }
  }
}

Keep the key in the environment, not in a file you commit. A key that holds only signing:read gives an assistant that can look but not send.

What it can do

ToolWhat it doesKindNeeds
signsealer_get_accountWho am I connected as. The SignSealer business this connection acts for: its name, what this connection may do (its scopes), whether it is a test sandbox where nothing reaches anybody, and whether the business can text people. Call it first, and tell the user which business they are connected to.Readssigning:read
signsealer_list_templatesList templates. The business's templates (the documents it sends), newest version first, with each one's code, title and whether it is published. Pass code for one template's versions.Readssigning:read
signsealer_get_templateRead a template. One template version: its text and the values it takes (the blanks a sender fills in), which signsealer_send_document's values answers.Readssigning:read
signsealer_list_documentsList documents. Documents sent for signature, newest first. Filter by status (draft, sent, completed, declined, expired, void, or open for draft and sent) or q (part of a title or a signer's name, email or number). Paged with limit and offset; the answer says total and has_more.Readssigning:read
signsealer_get_documentRead a document and who has signed. One document: its status and its signers, each with where they are (pending, signed, declined). Use it to answer "has everyone signed?". Personal detail is left out unless asked for: the text (include_text), the signers' answers to its questions (include_answers), and the event trail with addresses and devices (include_trail).Readssigning:read
signsealer_send_documentSend a document for signature. Prepares a document from a published template, fills in its values, and sends each signer their own link by email (or by text to a number that agreed to texts). This emails or texts real people: confirm the template, the values and every recipient with the user first. Answers with the document's id and each signer's link. If a send is refused after the document was prepared, the refusal names it: correct what it says and call this again with that document_id instead of template_code, so no second copy is made.Changes somethingsigning:send
signsealer_remind_signerRemind a signer. Sends one signer who has not signed a reminder with their link. Emails or texts a real person, at most as often as the business's reminder rules allow.Changes somethingsigning:remind
signsealer_new_signing_linkMake a fresh signing link. A new signing link for one signer, to hand over yourself (in a chat, on a screen, as a QR code). The signer's previous link stops working.Changes somethingsigning:links or signing:workflows
signsealer_void_documentVoid a document. Cancels a document that is not finished: its links stop working and its signers are told. A completed document cannot be voided. Cannot be undone.Changes somethingsigning:void
signsealer_get_certificateRead a document's certificate. The certificate of completion of a signed document: who signed, when, from where, the fingerprint of what they signed, and the code anyone can check it with.Readssigning:read

The four that change something are marked as such to the client, which asks you before it runs one. The server also tells the assistant to confirm the template, the values and every recipient with you before it sends anything, and never to send to an address you did not give it.

Sending takes an idempotency_key the assistant makes up for that one send (reminding and voiding take one too, if given). An assistant whose connection drops calls again with the same key and is answered with what the first call did, so a retry never sends a document twice. Reading a document gives its status and its signers; the text, the signers' answers and the event trail, with its network addresses and devices, come only when asked for.

What you are asked to allow

An assistant asks for signing:read, signing:send, signing:remind, signing:links, signing:void. Reading documents, templates and who has signed is given when you connect it. Each of the four that reaches people or stops a link is a box on SignSealer's sign-in page, and none is ticked until you tick it:

  • Send documents for signature (signing:send)
  • Remind a signer who has not signed (signing:remind)
  • Make a fresh signing link (signing:links)
  • Void a document that is not finished (signing:void)

An assistant that only needs to tell you who has signed gets no box ticked. One asked to send a document is refused if Send documents for signature was left clear, and says so: nothing is sent. To change what it may do, connect it again and tick the boxes you want; what you tick replaces what it had, at once, even for the sign-in it already holds.

It is never given more than you hold yourself, and never the scopes that manage templates, webhooks, workflows or keys. An API key with signing:write holds all four.

The sign-in page says Not checked by SignSealer for an app that introduced itself, which every assistant does, and names where your browser goes back to afterwards: the assistant's own site, or an app on this computer for Codex and Claude Code. Connect it only when you started the connection yourself, just now.

For client builders

WhatWhere, and how
TransportStreamable HTTP, stateless: one JSON-RPC message per POST /mcp, answered with one JSON object; a notification is answered 202. No event stream (GET is 405) and no session. Protocol version 2026-07-28, with no handshake: each request names its version in _meta, and server/discover says which versions this server speaks. And, opened with initialize, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05.
Without a token401 with WWW-Authenticate: Bearer resource_metadata="https://api.signsealer.com/.well-known/oauth-protected-resource/mcp" and the scopes.
Protected resource (RFC 9728)https://api.signsealer.com/.well-known/oauth-protected-resource/mcp
Authorization server (RFC 8414)https://api.signsealer.com/.well-known/oauth-authorization-server
Identifying your appAn OAuth Client ID Metadata Document: use its https address as client_id, and we read it, check its client_id is that address, and take its name and redirect_uris. Or register (RFC 7591) at POST https://api.signsealer.com/oauth/register. Redirects are https, or the loopback (http://127.0.0.1, http://[::1], http://localhost) with any port.
The grantAuthorization code with PKCE (S256 only). Refresh tokens only for an app that asks for them: name refresh_token in grant_types, in its registration or its metadata document; left out, the grant is the code alone, as RFC 7591 reads it. A resource (RFC 8707) must be this API, https://api.signsealer.com or https://api.signsealer.com/mcp; anything else is invalid_target.
LimitsThe API's, per token: see Limits and paging. A tool's refusal is the API's own status, message and hint.

Building on the API directly instead? The quickstart and the Node client are the way in, and llms-full.txt is every page of these docs as one text file, for a coding assistant to read.

Ready to build? An API key takes a minute in the portal, and the free plan covers the first 10 agreements a month.

Get an API key