Skip to main content
Glama
Signable MCP server

Signable MCP server

by dragosh29

Signable MCP server

An MCP server that lets Claude, ChatGPT and other MCP clients work with a Signable e-signature account: envelopes, templates, contacts and users, and (when enabled) sending, reminding, cancelling and expiring envelopes. It is built from Signable's public API documentation and its published OpenAPI spec.

Once it's connected, someone on the account can ask things like:

  • "Which envelopes are still waiting for a signature, and who hasn't signed?"

  • "Show me the history of the 17 John Street tenancy contract."

  • "What does the Tenancy Contract template need before I can send it?"

  • "Find Sam Evans and list every document we've sent him."

  • With writes enabled: "Send the Mutual NDA template to Priya Shah at Acme, and remind the John Street signers."

Tools

Tool

What it does

API calls

list_envelopes

Envelopes with status, timestamps and party names. Filters by one status and/or a title keyword, pages by offset.

GET /envelopes

get_envelope

One envelope: parties with signing status and role, documents with fields and 24-hour download links, audit history, metadata.

GET /envelopes/{fingerprint}

list_templates

Templates with their parties and merge fields.

GET /templates

get_template

One template, so an assistant knows the party_ids and field_ids a send needs.

GET /templates/{fingerprint}

find_contacts

Search contacts by part of a name or email. The API has no search parameter, so this pages through the list (50 per call). Emails are hidden by default, but a query that matches an email fragment still confirms such an address exists on the account.

GET /contacts

get_contact_envelopes

A contact's document history. The API answers 404 for a contact that exists but has never been sent an envelope (error code 10060); the tool fetches the contact first and turns that case into an empty list.

GET /contacts/{id}, /contacts/{id}/envelopes

list_users

Team members with their role (User, Admin, Super-Admin).

GET /users

send_envelope_from_template

Creates an envelope from one template and queues it for sending, or saves it as a draft. Fetches the template first and refuses locally if a template party has no signer, a signer's party_id is not in the template, or a merge field is unknown. Only registered when writes are enabled.

GET /templates/{fingerprint}, POST /envelopes

remind_envelope

Emails a reminder to every party that has not signed. Writes only.

PUT /envelopes/{fingerprint}/remind

cancel_envelope

Cancels a sent envelope (signers are emailed). Writes only.

PUT /envelopes/{fingerprint}/cancel

expire_envelope

Expires a sent envelope (no email). Writes only.

PUT /envelopes/{fingerprint}/expire

Not covered on purpose: companies, usage, webhooks, branding, settings, embed sessions, party updates, and every delete endpoint.

Related MCP server: CanUSign MCP Server

Setup

Requires Node 18 or later.

npm install
npm run build

You need an API key for your Signable account. The API authenticates with HTTP Basic: the key is the username; the password can be anything, Signable recommends x, and that is what this server sends.

Claude Desktop: add this to claude_desktop_config.json:

{
  "mcpServers": {
    "signable": {
      "command": "node",
      "args": ["/absolute/path/to/signable-mcp/dist/index.js"],
      "env": { "SIGNABLE_API_KEY": "your-key" }
    }
  }
}

Claude Code:

claude mcp add signable -e SIGNABLE_API_KEY=your-key -- node /absolute/path/to/signable-mcp/dist/index.js

Variable

Required

Meaning

SIGNABLE_API_KEY

yes

Your API key, sent as the HTTP Basic username with password x.

SIGNABLE_ALLOW_WRITES

no

true to register send_envelope_from_template, remind_envelope, cancel_envelope and expire_envelope. Off by default.

SIGNABLE_BASE_URL

no

Defaults to https://api.signable.co.uk/v1. Used by the tests.

Safety defaults

  • Read-only unless SIGNABLE_ALLOW_WRITES=true. Read tools carry the MCP readOnlyHint annotation; cancel_envelope and expire_envelope are marked destructive.

  • Email addresses of signers, contacts and users, the last four digits of signers' mobile numbers, envelope passwords, the IP addresses and user agents in the audit history, and the download link of a file a signer uploaded into an upload field (the spec's example is a passport copy) are only returned when the assistant explicitly asks (include_contact_details). In free text (history lines, field values, field and merge-field labels, envelope and document titles, envelope metadata, redirect URLs, and signer, contact and user names) email addresses are replaced with [email redacted] and phone-number-like sequences with [phone redacted] by default. The phone match is a heuristic: it covers international numbers written with + or 00 (including the +44 (0)7700 … form), UK numbers written with a bracketed area code such as (020) 7946 0958, and UK-style 0… numbers of 9 to 11 digits with spaces, dots or hyphens between groups. Other digit strings that happen to start with 0 (an order number, say) are redacted too, while hex fingerprints, numeric IDs, timestamps and hyphenated references such as PO-0001-000123 are left alone; the raw text is available with include_contact_details. Envelope metadata nested more than 20 levels deep is replaced by a placeholder rather than returned unredacted. Template titles, template party labels and merge-field labels are always redacted (the template tools have no include_contact_details switch); names are always returned, minus any email or phone typed into them. The same redaction is applied to Signable's own error messages before they are passed on.

  • Document download links (pdf_url, signed_pdf_url and the envelope's signed PDF) are returned by default: the spec documents them as direct links that give access to the whole document for 24 hours after generation. They are passed through as stored so they keep working; the redaction is not applied to them.

  • IDs are checked before any call is made: contact IDs must be numeric (the spec types them as integers); fingerprints and party/field IDs must be short strings of letters, digits, _ and - (up to 64 characters, no slashes or spaces), because the spec does not document their format (all but one fingerprint example are 32 lowercase hex characters, one is 33; every party and field ID example is a number).

  • send_envelope_from_template compares the request with the template before posting anything. Its auto_expire_hours and auto_remind_hours have a minimum of 12: the spec documents that minimum for direct-document sends only, and it is assumed here for template sends.

  • Signable does not document a rate limit. Requests are spaced 250 ms apart (about four per second). A 429 is retried at most twice for any method, including POST /envelopes, on the assumption that a rate-limited request was not processed (see Status). The retry waits for Retry-After (whole or fractional seconds, or an HTTP-date; 2 s then 4 s when the header is absent or unreadable). Each wait is capped at 10 seconds, so one request waits at most 20 seconds in all; a tool call that makes several requests (pages, lookups) can still run past the MCP client's default 60-second request timeout. Past the cap: if Signable asks for a longer wait the call gives up at once and the message says how long to wait.

  • 502, 503 and 504 are retried the same way for GET only; when all three attempts fail the error says the service may be unavailable and to try again in a few minutes, without the gateway's HTML. A POST /envelopes or a PUT …/remind|cancel|expire is never retried after a gateway error, because the request may already have been processed and a retry could send an envelope or a reminder twice; the error tells the assistant to check with list_envelopes or get_envelope before repeating it.

  • A 200 whose body is not JSON (a proxy or a login page in the way) is reported as an error naming SIGNABLE_BASE_URL, never as an empty list or an empty envelope.

  • A rejected API key produces a message that says which variable to fix; a 400 from the API (for example cancelling an envelope that is not sent) is passed on with Signable's own message and error code.

Tests

npm test

The test suite:

  1. Validates every fixture record against the component schemas in Signable's published OpenAPI spec (EnvelopeSignedSummary, EnvelopeDetailResponse, TemplateSummary, Contact, ContactEnvelopeSummary, User). The spec is downloaded from developers.signable.app/_bundle/openapi.yaml to spec.yaml on the first run.

  2. Starts a local mock of the API under /v1 that serves those fixtures with the documented offset/limit pagination, returns Basic-auth 401s, 404s (including the spec's two contact cases: unknown contact, code 10053, and contact with no envelopes, code 10060) and 400s in the documented error shapes (the POST /envelopes 400 uses the spec's example code 10250), and answers the first GET /templates with a 429. The mock's list, detail, action and error responses are validated against the spec's response schemas, and the documented keys of each list and get response are asserted explicitly (see the note below).

  3. Starts the built server and drives it over stdio with the official MCP client: 29 checks covering every tool, tool annotations, offset pagination stopping at the documented total and continuing across pages that come back shorter than requested, the envelope_status and q filters, redaction of emails and phone numbers by default (parties, contacts, users, history, fields and merge-field labels, template titles and party labels, metadata including a 24-level nested value, redirect URL, names; the +44 (0)…, bracketed, 00-prefixed, extra-spaced and dot-separated phone forms), the upload-field link withheld by default, and their return on request, the 429 retry waiting for Retry-After in the seconds, fractional-seconds and HTTP-date forms, giving up after three attempts on a persistent 429 and at once on a Retry-After above the cap, a 429 on POST /envelopes retried once, a 502 retried for GET and never for POST /envelopes or a PUT action, a GET failing three times with 503 reported with advice and without the gateway HTML, a 200 with a non-JSON body reported as an error, the write gate with the variable unset and set to false, the POST /envelopes body validated against the spec's "Send Template Request" schema, the local refusal of mismatched parties and fields and of a copy recipient with a mobile number, the three PUT actions, the empty-list handling of the contact-with-no-envelopes 404 only on the first page at offset 0, ID validation before any call, the 401 and 404 messages, and that every request used Basic base64(key:x) and a documented method and path.

Note that the spec marks no fields as required on TemplateSummary, Contact, ContactEnvelopeSummary, User, TemplateGetResponse, ContactGetResponse, TemplatesListResponse, ContactsListResponse, ContactEnvelopesListResponse and UsersListResponse, so schema validation of those only proves the types of fields that are present. Step 2 therefore also asserts that the documented keys are present in the mock's list and get responses; the fixture records themselves are only type-checked.

Status

This is a working prototype. It has not yet been run against the live API, because it was built without a Signable account. Everything below is taken from the published spec and should be confirmed on a real account:

  • The format of envelope and template fingerprints and of party and field IDs. The spec types them as strings; the validation here is deliberately loose.

  • The sort order of GET /envelopes. The spec does not document one; its example lists newest first, and the server returns whatever order the API uses.

  • GET /envelopes/{fingerprint} on a draft or processing envelope, and whether envelope_history and document_fields are present for every status.

  • GET /contacts/{id}/envelopes for a contact with no envelopes. The spec documents a 404 with code 10060 and the message "This contact hasn't been sent any envelopes.", but the example's summary says "Unknown or wrong-account contact", so the server fetches the contact first and only treats the 404 as "no envelopes" when that succeeded and the request was for the first page at offset 0. What the API answers for an offset past the end of a list is not documented; the mock answers 200 with an empty list, and a 404 at a non-zero offset is passed on as an error rather than read as "no envelopes".

  • The wording of Signable's error messages and whether any of them echo request data such as a party's email address; the texts here are the spec's examples, and the server redacts contact details from them regardless.

  • Whether the 12-hour minimum on envelope_auto_expire_hours and envelope_auto_remind_hours applies to template sends; the spec documents it only for direct-document sends.

  • The end of pagination. The server stops at an empty page or when offset + returned reaches the documented total_* string; when no total is present a short page is taken as the end. A short page on its own is not, because LimitParam says a request for more than 50 gets 10 back: the next page is then requested from offset + returned. ContactsListResponse also documents a next URL, which is honoured when present. The list responses' limit field is ambiguous in the spec (the schema describes it as the number of items returned, the examples echo the requested limit) and the server ignores it.

  • A 429 on POST /envelopes is retried on the assumption that a rate-limited request was not processed. The spec documents no 429 at all; confirm on a live account that Signable never creates the envelope before answering 429.

  • The POST /envelopes body for a template send, in particular what party_id a copy recipient should carry (the spec marks party_id as required for every party, copy recipients included, without saying which ID a copy recipient should use) and whether document_title may differ from the template title.

  • Whether PUT .../remind, .../cancel and .../expire accept an empty body, as documented (no request body is defined for them).

  • The wording of the 400 returned when reminding, cancelling or expiring an envelope that is not sent; the messages here are the spec's examples.

  • role_id to role-name mapping (1 User, 2 Admin, 3 Super-Admin) comes from the spec's user-creation schema.

  • How many requests per second the API tolerates; the spec says nothing, so the throttle here is a guess on the polite side.

find_contacts pages through the contact list because GET /contacts has only offset and limit parameters. On large accounts, a search parameter on that endpoint would make this much cheaper.

Going to production

This version runs locally over stdio, with the account holder's own API key. For customers to connect from claude.ai or ChatGPT without handling keys, the next step is a remote server (Streamable HTTP) behind OAuth, hosted by Signable, and then a listing in the Claude and ChatGPT connector directories.

Licence

MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.

Available Tools

7 tools
find_contactsFind contactsA
Read-only

Search contacts (signers and recipients) by part of their name or email. The API has no server-side search, so this pages through the contact list (50 per call) up to max_pages. Emails are only returned with include_contact_details; note that a match on an email fragment still confirms that such an address exists on the account.

Inputs: query (required), max_pages, max_results, include_contact_details.

get_contact_envelopesEnvelopes for a contactA
Read-only

A contact's document history: every envelope they are a recipient of, with status, timestamps and signed PDF link where available. A contact that exists but has never been sent an envelope gives an empty list.

Inputs: contact_id (required), offset, max_results, include_contact_details.

get_envelopeGet envelope detailsA
Read-only

Full detail for one envelope: each party with its signing status and role, the documents with their fields and download links (valid 24 hours), the audit history and any metadata.

Inputs: envelope_fingerprint (required), include_contact_details.

get_templateGet templateA
Read-only

One template with its parties (party_id, name) and the merge fields (field_id, label) each party can have pre-filled. Use this before send_envelope_from_template.

Inputs: template_fingerprint (required).

list_envelopesList envelopesA
Read-only

List envelopes on this Signable account in the order the API returns them (the spec does not document the sort order; its example lists newest first), with status, timestamps and the parties' names. Filter by one status and/or a keyword in the title.

Inputs: q, offset, status, max_results, +1 more.

list_templatesList templatesA
Read-only

Templates on this account with their parties and merge fields, so you know what a send from each template needs.

Inputs: offset, max_results.

list_usersList usersB
Read-only

Team members on this Signable account with their role (User, Admin or Super-Admin). Emails are only returned with include_contact_details.

Inputs: max_results, include_contact_details.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool targets a distinct resource and scope: contacts, contact envelope history, account envelopes, envelope details, template lists, template details, and users. There is no meaningful overlap that would cause an agent to select the wrong tool.

    Naming Consistency4/5

    The naming mostly follows a predictable list_/get_ pattern, with list_ for collections and get_ for single items. The only minor deviation is find_contacts instead of list_contacts, but the convention is otherwise clear and consistent.

    Tool Count5/5

    Seven tools is well-scoped for a Signable server focused on searching and retrieving account data. Each tool covers a meaningful part of the domain without unnecessary redundancy.

    Completeness3/5

    The server covers listing and retrieving contacts, envelopes, templates, and users, but entirely lacks write/send operations. This is especially notable since get_template mentions using it before send_envelope_from_template, yet no send tool exists, leaving a clear workflow dead-end.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables users to create, manage, and track electronic signing requests and templates through Claude Desktop and other MCP-compatible clients. Provides multi-tenant authentication with customer API keys for secure document workflow operations.
      66 npm
      -
    • A
      license
      B
      quality
      C
      maintenance
      Enables Claude, ChatGPT and other MCP clients to read practice-management data including organization, clinicians, diaries, availability, bookings, patients, invoices, payments, staff tasks, services, and locations, and optionally create staff tasks, create bookings, and cancel bookings.
      15
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables ChatGPT and Claude to list, inspect, prepare and send Documenso envelopes for the caller's own team. Read-only tools stay team-scoped, drafts are prepared before any send, and every call uses the calling user's own team token rather than a shared credential.
      116 npm
      MIT