Skip to content
contract-ops CLI suite

MCP server

The agent drives. You approve.

The whole suite is built for an agent-first workflow. Three MCP servers expose it — pick by what you want the agent to do, or use the HTTP API for frameworks that don't speak MCP.

If the agent should… Use
Extract, draft, lint, compare, review, convert, query the vaults contract-ops-mcp — one server, all nine CLIs
Send, sign, track, and verify signatures (human-gated) sign-cli's MCP — the signing surface
Run a pre-signature drift gate only compare-cli-mcp
Integrate from a framework that doesn't speak MCP the /v1/* HTTP API

All three servers — contract-ops-mcp, sign-cli, and compare-cli-mcp — are published on the official MCP Registry (namespace io.github.DrBaher/*), so any MCP-aware runtime can discover them.

One connection, the whole suite — contract-ops-mcp

Wire it up once; it discovers your installed CLIs and exposes curated tools (plus catalog / run escape hatches), all riding the suite's uniform --catalog json contract.

claude / cursor mcp config
{
  "mcpServers": {
    "contract-ops": { "command": "npx", "args": ["-y", "contract-ops-mcp"] }
  }
}

Tools: extract_contract, lint_contract, compare_versions, fill_template, convert_to_pdf, review_nda, template_vault_*, contract_vault_*, and read-only verify_signature / verify_receipt / audit_show — plus catalog(cli), run(cli, args), and suite_status. File access is confined to CONTRACT_OPS_MCP_BASE_DIR. Needs the CLIs installed (install page, or the all-in-one container). Repo.

Signing is deliberately not in this server — it exposes only sign-cli's read/verify ops. To request or apply a signature, use sign-cli's own MCP below, where the per-signer human gate stays intact.

sign-cli's MCP — the signing surface

The deeper, signing-specific server: 19 tools for sending, tracking, detection, stamping, and verification — with the human gesture gated behind a per-signer token.

The guardrail — Agents can send documents, detect signature fields, stamp previews, track status, and verify receipts — but they can't sign on a human's behalf. Every signature requires a per-signer token tied to that signer's email, with a TTL. The agent never sees the token. The human does. That asymmetry is the whole architecture.

Start the server

stdio MCP server
# Boots the MCP server on stdio. Wire it into any MCP-aware client.
sign mcp serve

# Or via npx, no install required:
npx @drbaher/sign-cli mcp serve

# Discover the catalog without spinning up the server:
sign mcp tools --format markdown

Wire it into Claude Code

Add to your ~/.config/claude-code/settings.json (or the project-level .claude/settings.json):

.claude/settings.json
{
  "mcpServers": {
    "sign-cli": {
      "command": "npx",
      "args": ["-y", "@drbaher/sign-cli", "mcp", "serve"]
    }
  }
}

After that, every sign-cli MCP tool shows up inside Claude Code. Ask the agent to "detect the signature field on contract.pdf and send it to alice@acme.com and bob@beta.com via SignWell" and it will call the right tools with the right arguments.

Wire it into Cursor

Cursor's MCP config lives at ~/.cursor/mcp.json:

~/.cursor/mcp.json
{
  "mcpServers": {
    "sign-cli": {
      "command": "npx",
      "args": ["-y", "@drbaher/sign-cli", "mcp", "serve"],
      "env": {}
    }
  }
}

Read-only mode for sandboxed agents

Run with --read-only true to block every mutating tool with a FORBIDDEN_READ_ONLY error. Useful for letting an agent inspect and track without any side effects. Pair with --tool to allow-list a specific subset, or --capability to disable resources/prompts.

sign mcp serve --read-only true \
  --tool request_show --tool audit_verify --tool pdf_detect_signature_field \
  --emit-events ./mcp-events.ndjson \
  --emit-events-redact true

Available tools — 19 in total

Every tool ships with an inputSchema and (where applicable) an outputSchema. request_watch also streams notifications/progress when the client supplies a progressToken. Don't hardcode this list — call sign mcp tools for the live catalog.

Read-only (safe to call without approval)

Tool What it does
signer_list List pending local-provider requests where the signer is a recipient.
signer_fetch_document Read (and optionally save) the unsigned PDF for a request. Requires the per-signer token.
request_show Enriched snapshot: approvals, signedBy[], declinedBy, and a nextSteps[] hint array.
request_status Poll the provider for the latest status of a request.
request_watch Poll until terminal (completed/declined/canceled/timeout). Streams progress notifications.
audit_verify Verify the hash-chained audit log for a request; reports any break.
audit_scan Cross-request audit search with filters (request id, event type, time window).
pdf_detect_signature_field Ranked signature-field candidates (AcroForm /Sig + anchor text). Read-only.
pdf_detect_date_field Date-anchor candidates with an alreadyFilled flag to avoid overwrites.
pdf_inspect_signatures Verify a signed PDF's PKCS#7: /ByteRange digest match and the signature value against the signer cert's public key (RSA/ECDSA), signer certs, trust label.
profile_list List named profiles (provider, dbPath, credentials bundle) and the active one.
profile_show Show resolved profile state. Credentials redacted by default; show_secrets: true to reveal.

Mutating (gated by --read-only true)

Tool What it does
sign Sign a local request as the holder of a per-signer token. Requires --provider local.
signer_decline Decline a local request as the token holder. Records a request.signer_declined event.
signer_reissue_token Mint a fresh token in place of an expired/lost one. Tied to the original signer email.
pdf_stamp_text Stamp plain text (dates, names) onto a PDF without producing a PAdES envelope.
preview Stamp a signature image or rendered name onto a PDF — no envelope, no audit mutation. Iterate before committing.
document One-shot DOCX|PDF → sealed PDF: convert, auto-place, stamp, PAdES-seal, verify chain.
request_receipt Export a cryptographically-signed receipt bundle (manifest + detached signature + cert chain).

HTTP API for non-MCP clients

Every MCP tool has a 1:1 HTTP equivalent under /v1/*, served by sign serve. Same input shape, same path-traversal guards, same read-only gating. Useful for agents and integrations that speak REST rather than MCP.

# Boot the HTTP API. Auth via SIGN_HTTP_BEARER_TOKEN.
sign serve --read-only true --rate-limit 5

# Discover the route catalog:
curl http://localhost:4000/v1/openapi.json

Profiles for credential isolation

Named profiles bundle provider, dbPath, strictProvider, and a credentials block (with {{env:VAR}} references that point at shell-managed secrets). The agent never holds API keys — it activates a profile by name; the credentials resolve from environment variables at call time.

# Create a profile that reads its API key from the shell environment
sign profile init --name prod \
  --provider signwell --db "~/.sign-cli/prod.db" \
  --strict-provider true
sign profile set --name prod \
  --key credentials.SIGNWELL_API_KEY --value "{{env:SIGNWELL_API_KEY}}"

# Activate per-call
sign --profile prod request show --request-id req_abc

# Or implicitly via a project-level sign-profile.json (git/npm-style discovery)

What the agent can't do

  • Sign on a human's behalf. The sign tool requires an explicit per-signer token. Tokens are scoped to one signer's email and expire after a configurable TTL.
  • Modify past audit events. The audit chain is hash-chained with append-only triggers; tampering breaks audit_verify.
  • Bypass the timestamp anchor. RFC 3161 anchors are external — the agent can't forge one.
  • Read or write paths outside the working directory. Every input/output path runs through validateDocumentPath / validateOutputPath. Opt out with SIGN_ALLOW_ABSOLUTE_DOCS=1.
  • Leak its credentials. Profile-injected secrets flow through the error-message redactor — even custom keys never show up in stack traces.

Why this matters

Most "agent-friendly" SaaS products are agent-friendly in the sense that they have an API. They aren't agent-safe. The MCP boundary here is designed so an agent can do all the operational work (detecting, sending, stamping previews, tracking, verifying, reporting) while the actual legal commitment — the signature — stays gated behind a human gesture.

That's a meaningful architectural choice for anyone deploying agents into ops workflows. You get the productivity wins of automation without the legal liability of a hallucinating model accidentally executing a contract.

Edit this page on GitHub