sign-cli

Agent-first e-signature MCP server with offline PAdES signing and hash-chained audit.

Community: Submitted by a user or imported; check the owner before granting accessDegradedNo sign-inGlobalFreeRead-only

What it can do

  • Signer List: List pending local-provider requests where the given signer is a recipient. Pass signer_email to scope; omit to list every pending local request the inbox can see.
  • Signer Fetch Document: Read the unsigned PDF for a local signing request. Requires the per-signer token. If out_path is provided, also writes the file to disk. Records request.signer_fetched_document.
  • Sign: Sign a local signing request as the holder of the given token. Requires --provider local. The token resolves the signer; pre-sign safety checks (require_hash, require_title, require_signer_email

What data it sees

Do you need an account

No: the server works without sign-in

Agent-first e-signature MCP server with offline PAdES signing and hash-chained audit. The same 19 tools / 4 prompts / 12 resources are reachable via stdio (npx @drbaher/sign-cli mcp serve) for local agents and over HTTP for remote ones.

Architectural claim: an LLM agent can drive every step of a contract workflow except the actual signing gesture, which stays gated behind a human via per-signer approval tokens (TTL-bounded, scoped to one email, single-use). Pre-sign safety checks (--require-hash, --require-title, --require-signer-email) throw structured errors before any state mutation — so an agent that computed a hash earlier can refuse to sign if the document was swapped mid-flight.

Highlights:

  • Fully-offline PAdES signer (real PKCS#7, self-issued X.509)
  • Hash-chained audit log with append-only DB triggers + RFC 3161 timestamping
  • Read-only mode (--read-only true) returns FORBIDDEN_READ_ONLY for mutating tools
  • Multi-provider routing (local / Dropbox Sign / DocuSign / SignWell)
  • Pre-sign signature visibility (existingSignatures on every fetch)
  • Tool allow-list + capability scoping for sandboxed agents

This Smithery deployment runs in read-only mode against an ephemeral SQLite that wipes every 4 hours — safe to explore, not for production signing. For local agent use, install via npm i -g @drbaher/sign-cli.

MIT-licensed. No telemetry. Source: github.com/DrBaher/sign-cli. Showcase: cli.drbaher.com.

How to connect

How to connect sign-cli to Claude

The server address to paste into Claude settings:

https://sign-cli--drbaher.run.tools

  1. Open Claude (claude.ai or the desktop app).
  2. Go to Settings → Connectors.
  3. Click Add custom connector.
  4. Paste the server address copied below into Remote MCP server URL and click Add.
  5. In a chat, click + → Connectors and switch the new connector on.

Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.

Authorization

After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.

How to connect sign-cli to ChatGPT

The server address to paste into ChatGPT settings:

https://sign-cli--drbaher.run.tools

  1. Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
  2. Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
  3. Open Settings → Connectors and click Create.
  4. Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
  5. Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
  6. In a new chat open + → Apps/Connectors and enable the connector.

OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.

Authorization

On first use ChatGPT opens the service's sign-in window. Sign in and approve access.

How to connect sign-cli to Cursor

The server address to paste into Cursor settings:

https://sign-cli--drbaher.run.tools

Fastest: click Open in Cursor below and confirm the prompt.

Manually:

  1. In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
  2. Paste the JSON copied below into ~/.cursor/mcp.json (per project: .cursor/mcp.json in the repo root).
  3. Save the file. The server appears in the MCP list; authorize it there if asked.

Authorization

If the service needs sign-in, an authorize button appears next to the server in the MCP list.

Server tool list (19)

Raw names from tools/list. Only developers need these.

signer_listList pending local-provider requests where the given signer is a recipient. Pass signer_email to scope; omit to list every pending local request the inbox can see.
signer_fetch_documentRead the unsigned PDF for a local signing request. Requires the per-signer token. If out_path is provided, also writes the file to disk. Records request.signer_fetched_document.
signSign a local signing request as the holder of the given token. Requires --provider local. The token resolves the signer; pre-sign safety checks (require_hash, require_title, require_signer_email) throw with a structured error code before any state mutation.
signer_declineDecline a local signing request as the holder of the given token. Sets status to declined.
request_showReturn the enriched request snapshot: request, approvals (with tokenHint/expiresAt/expired/signed), signedBy[], declinedBy/declineReason, and a nextSteps[] array of suggested commands.
request_statusPoll the provider for the latest status of a request. For dropbox/signwell, reads API keys from DROPBOX_SIGN_API_KEY / SIGNWELL_API_KEY in the server's environment.
audit_verifyVerify the cryptographic audit chain for a request and report any break.
request_watchPoll a request's status until terminal (completed/declined/canceled/timeout). When the MCP client supplies a progressToken, emits notifications/progress on each poll.
pdf_detect_signature_fieldDetect signature-field placement candidates in a PDF (AcroForm /Sig widgets + anchor-text matches). Returns ranked candidates with confidence + adjustment method. Read-only — does not modify the PDF.
pdf_detect_date_fieldDetect date-field placement candidates in a PDF. Returns candidates with `alreadyFilled: true` when a date string is already present near the anchor — callers can skip those when stamping. Read-only.
pdf_inspect_signaturesInspect existing PADES signatures on ANY PDF — ours, Adobe's, DocuSign's, Dropbox Sign's, SignWell's. Returns per-signature signer CN/email, cert subject + issuer, validity window, fingerprint, trust label (self_signed_local | self_signed_other | ca_signed | unknown), message-digest match, and parse warnings. Trust label is structural (issuer vs subject); no chain validation, no expiry check. Pure read — no DB interaction, no audit events.
profile_listList the profiles configured in the user's profiles.json. Shows the active source so the agent knows whether a flag, env var, or default selected the currently-active profile.
profile_showShow the resolved active profile (or a specific user profile by name) with per-field provenance. Credentials are redacted by default; pass show_secrets: true to reveal resolved values. Read-only.
pdf_stamp_textStamp a text string (e.g. a date) onto a PDF. Mirrors `sign pdf stamp-text`. Position via auto_place (true|first|last|all|page:N|index:N) on DATE anchors, or explicit image_page/image_x/image_y/image_width/image_height. By default, candidates whose date appears already filled in are skipped — pass overwrite_filled: true to include them. Writes to out_path and returns the actual stamp positions + quality warnings.
previewStamp a signature image or rendered name onto a PDF as a draft preview — NO PAdES seal, no signing-request state mutation. Mirrors `sign preview`. Returns positions + drawnRects (actual on-page rectangles after preserve-aspect-ratio shrink-to-fit) + warnings.
documentOne-shot DOCX|PDF → signed PDF. Mirrors `sign document`. Orchestrates DOCX→PDF (via docx2pdf-cli) → auto-place detection → stamp + PAdES seal → verify. Uses an isolated temp database so the caller's main db is never touched. Defaults auto_place to 'first'.
signer_reissue_tokenMint a new per-signer token for an existing request; the previous token is invalidated. Use when a signer lost their original token or it's about to expire. Mutating.
audit_scanVerify the audit chain of every request in the local DB (or filtered by provider/status). Returns per-request validity and any chain break. Read-only.
request_receiptExport a cryptographically-signed receipt bundle for a request: audit.json, signed.pdf, manifest.json, manifest.sig (RSA-SHA256 over manifest.json), manifest.cert.pem. Verifiable end-to-end with `sign request verify-receipt`. Mutating (writes to out_dir).