Tool · TypeScript
sign-cli
A command-line e-signature tool for humans, ops teams, and AI agents. The built-in PAdES
signer (PKCS#7 in /ByteRange, self-issued cert) produces real,
cryptographically verifiable signed PDFs fully offline — no signup, no API
keys, no third-party SaaS. Route through Dropbox Sign, DocuSign, or SignWell when you need an
external provider.
npm i -g sign-cli — or npx sign-cli demo for
a five-second offline walkthrough of the full lifecycle (create → send → sign → verify →
receipt). Pick the local PAdES signer or a hosted provider (Dropbox Sign, DocuSign, SignWell)
and send a PDF with one command.
See sign-cli sending a real PDF
Read-only browser demo of the full send → sign → verify → receipt flow. Sandboxes reset every few hours.
Open the live demo →What it does
- Fully-offline PAdES signing. The built-in local provider produces real PKCS#7 signed PDFs with a self-issued X.509 cert — verifiable with any standard PDF-signature inspector. Zero network calls.
- Multi-provider hosted sending. Dropbox Sign, DocuSign, and SignWell are wired in for when you need an external trust anchor. Same surface across all four providers.
- Per-signer approval tokens with TTL. Every signer gets an explicit token tied to their email; agents can't impersonate humans, and tokens expire.
- Hash-chained audit events. Every event hashes into the previous one and into append-only DB triggers. Tampering breaks
audit verify. - RFC 3161 timestamping. External TSA anchors prove a signature existed by a given date — durable evidence that survives even if the provider disappears.
- Auto-place signatures. Detect AcroForm
/Sigwidgets and anchor text (Signature:,Date:,Sign here, French/EU conventions) and stamp at the right rectangle. Multi-candidate selectors (first,last,all,page:N,index:N) handle the foot-gun where multiple anchors exist. - One-shot DOCX → sealed PDF.
sign documenttakes a.docx(or.pdf), converts via the bundled docx2pdf-cli, auto-places, stamps, PAdES-seals, and verifies — all in one call against a scoped temp database. - Named profiles. Bundle provider + dbPath + credentials under a name; activate by flag, env, or project-level
sign-profile.json(git/npm-style upward discovery). Secrets reference shell env via{{env:VAR}}— credentials never live in the profile file. - Path-traversal guards. Every input and output path runs through a validator; an agent or buggy caller can't read or write outside the working directory unless you opt in with
SIGN_ALLOW_ABSOLUTE_DOCS=1. - PDF verification. Verify a signed PDF later, offline, with the receipt bundle.
- 19-tool MCP server. Every operationally-useful CLI command is also an MCP tool over stdio — plus a 20-route HTTP API at
/v1/*for non-MCP clients.
Quickstart
# Install
npm i -g sign-cli
# Five-second offline walkthrough: create → send → sign → verify → receipt
sign demo
# Or run without installing
npx sign-cli demo Send a real document
# Fully-offline: built-in local provider produces a real PAdES-signed PDF
sign request create \
--title "Vendor MSA" \
--document contract.pdf \
--signer "name:Alice Founder,email:alice@acme.com" \
--signer "name:Bob Counsel,email:bob@beta.com" \
--provider local
# Or via a hosted provider
sign request create \
--title "Vendor MSA" \
--document contract.pdf \
--signer "name:Alice Founder,email:alice@acme.com" \
--signer "name:Bob Counsel,email:bob@beta.com" \
--provider signwell One-shot: DOCX → sealed PDF
sign document chains conversion, auto-placement, stamping, sealing,
and chain-verify in one call. All intermediate state lives in a temp database scoped to the
call — your main ./data/sign.db is untouched.
sign document \
--input contract.docx \
--signer-name "Alice Founder" \
--signer-email "alice@acme.com" \
--name-signature true \
--auto-place first \
--out contract.sealed.pdf Preview placement before committing
# See where the detector would place a signature — no DB writes, no PAdES envelope
sign pdf detect-signature-field --pdf contract.pdf
# Stamp a preview to inspect visually
sign preview --pdf contract.pdf \
--name-signature "Alice Founder" \
--auto-place first --preserve-aspect-ratio true \
--out preview.pdf Verify a signed PDF
Verification is offline and works on any signed PDF the tool produced — including the
self-issued PAdES output. The receipt bundle contains the audit chain, the timestamp anchor,
a per-signer event subset, and a detached manifest.sig + manifest.cert.pem
you can hand to opposing counsel or a court without further cooperation from the signing provider.
# Re-parse the PDF, recompute the digest, extract signer certs
sign request verify-signed-pdf contract.signed.pdf
# Verify the hash-chained audit log for a specific request
sign audit verify --request-id req_abc
# Verify a stored chain-bundle (dir or .tar.gz)
sign audit verify-chain-bundle ./bundle.tar.gz Named profiles for credentials and DBs
Profiles bundle provider, dbPath, and credentials under a name. The credentials block uses
{{env:VAR}} references that resolve from the shell at call time —
so secrets never live in the profile file. Activate via --profile prod,
SIGN_PROFILE=prod, or implicitly via a project-level
sign-profile.json.
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}}"
sign --profile prod request show --request-id req_abc Preflight check
sign doctor preflight runs a structured per-check report: Node
version, DB-path writability, provider env vars, provider API reachability, filesystem
permissions. Exit 0 on verdict: "ok"; 1 on any failure.
Branch on checks[].name for agent self-recovery.
sign doctor preflight --provider signwell
# stderr: [sign] preflight: ok (provider=signwell, 7 ok, 0 failed, 0 skipped) MCP server for agents
Every operationally-useful CLI command is also exposed as an MCP tool over stdio — 19 tools in
total, split read-only vs. mutating. Wire it into Claude Code, Cursor, or any other MCP-aware
client and your agent can drive the workflow with the same primitives — including the
per-signer approval-token guardrail, so a runaway agent can't sign on a human's behalf. Total
tool count is live in the catalog — call sign mcp tools rather than
hardcoding.
sign mcp serve # start the MCP server on stdio
sign mcp serve --read-only true # sandboxed: blocks mutating tools
sign mcp tools # print the catalog without booting the server See the MCP guide for the full tool list, wire-up snippets, and the read-only mode walkthrough. The agent quickstart contract — output envelope, exit codes, discovery, failure → recovery — is in AGENTS.md; provider setup in docs/setup/; concept deep-dives (audit chain, profiles, security model, legal posture) in docs/reference/.
HTTP API for non-MCP clients
Twenty routes under /v1/* mirror the MCP surface — same input shape,
same path-traversal guards, same read-only gating. Useful for agents and integrations that
speak REST rather than MCP.
sign serve --read-only true --rate-limit 5
curl http://localhost:8787/v1/openapi.json # discover the route catalog Where it fits in the workflow
sign-cli is the last step in the contract pipeline — after
nda-review-cli produces the agreed text and
docx2pdf-cli renders the PDF. Or skip the chain entirely
and hand a .docx straight to sign document. See the full workflow page for the chained commands.
It also stands alone for any document that needs signing — vendor agreements, employment documents, board consents, anything PDF.
Repo
github.com/DrBaher/sign-cli · MIT licensed · TypeScript · MCP server + HTTP API included.