@signdocs-brasil/mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -0
  3. package/dist/annotations.d.ts +31 -0
  4. package/dist/annotations.js +29 -0
  5. package/dist/annotations.js.map +1 -0
  6. package/dist/bin/stdio.d.ts +2 -0
  7. package/dist/bin/stdio.js +19 -0
  8. package/dist/bin/stdio.js.map +1 -0
  9. package/dist/client.d.ts +35 -0
  10. package/dist/client.js +80 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/http/server.d.ts +34 -0
  13. package/dist/http/server.js +38 -0
  14. package/dist/http/server.js.map +1 -0
  15. package/dist/resources.d.ts +2 -0
  16. package/dist/resources.js +91 -0
  17. package/dist/resources.js.map +1 -0
  18. package/dist/schemas.d.ts +179 -0
  19. package/dist/schemas.js +169 -0
  20. package/dist/schemas.js.map +1 -0
  21. package/dist/server.d.ts +9 -0
  22. package/dist/server.js +38 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/tools/documents.d.ts +2 -0
  25. package/dist/tools/documents.js +22 -0
  26. package/dist/tools/documents.js.map +1 -0
  27. package/dist/tools/envelopes.d.ts +2 -0
  28. package/dist/tools/envelopes.js +59 -0
  29. package/dist/tools/envelopes.js.map +1 -0
  30. package/dist/tools/evidence.d.ts +2 -0
  31. package/dist/tools/evidence.js +13 -0
  32. package/dist/tools/evidence.js.map +1 -0
  33. package/dist/tools/helpers.d.ts +20 -0
  34. package/dist/tools/helpers.js +33 -0
  35. package/dist/tools/helpers.js.map +1 -0
  36. package/dist/tools/signingSessions.d.ts +2 -0
  37. package/dist/tools/signingSessions.js +70 -0
  38. package/dist/tools/signingSessions.js.map +1 -0
  39. package/dist/tools/transactions.d.ts +2 -0
  40. package/dist/tools/transactions.js +37 -0
  41. package/dist/tools/transactions.js.map +1 -0
  42. package/dist/tools/verify.d.ts +2 -0
  43. package/dist/tools/verify.js +39 -0
  44. package/dist/tools/verify.js.map +1 -0
  45. package/dist/tools/webhooks.d.ts +2 -0
  46. package/dist/tools/webhooks.js +35 -0
  47. package/dist/tools/webhooks.js.map +1 -0
  48. package/package.json +49 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SignDocs Brasil
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # SignDocs Brasil — MCP Server
2
+
3
+ A [Model Context Protocol](https://modelcontextprotocol.io) server for the
4
+ **SignDocs Brasil** e-signature API. It lets MCP-capable AI clients (Claude
5
+ Desktop, Claude Code, Cursor, …) create signing sessions, manage multi-signer
6
+ envelopes, upload/download documents, verify signatures, and manage webhooks —
7
+ the same action catalog as the official n8n, Zapier, and Make.com integrations.
8
+
9
+ It is a thin adapter over the official [`@signdocs-brasil/api`](https://www.npmjs.com/package/@signdocs-brasil/api)
10
+ SDK, which owns OAuth2 token exchange, caching, retries, and error handling.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install -g @signdocs-brasil/mcp-server # or run on demand with npx
16
+ ```
17
+
18
+ ## Credentials
19
+
20
+ Create an API credential in the SignDocs dashboard (app.signdocs.com.br → API)
21
+ and expose it as environment variables:
22
+
23
+ | Variable | Required | Default | Notes |
24
+ |---|---|---|---|
25
+ | `SIGNDOCS_CLIENT_ID` | yes | — | OAuth2 client id |
26
+ | `SIGNDOCS_CLIENT_SECRET` | yes | — | OAuth2 client secret |
27
+ | `SIGNDOCS_ENVIRONMENT` | no | `hml` | `hml` (staging) or `production` |
28
+ | `SIGNDOCS_BASE_URL` | no | derived | override the resolved base URL |
29
+ | `SIGNDOCS_SCOPES` | no | full set | space-separated scope override |
30
+
31
+ > Start in `hml`. HML data expires after ~7 days and is safe for testing.
32
+ > Switch to `production` only when you intend to create real, legally-binding
33
+ > signatures.
34
+
35
+ ## Connect an AI client
36
+
37
+ **Claude Desktop** (`claude_desktop_config.json`):
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "signdocs": {
43
+ "command": "npx",
44
+ "args": ["-y", "@signdocs-brasil/mcp-server"],
45
+ "env": {
46
+ "SIGNDOCS_CLIENT_ID": "your_client_id",
47
+ "SIGNDOCS_CLIENT_SECRET": "your_client_secret",
48
+ "SIGNDOCS_ENVIRONMENT": "hml"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ **Claude Code**:
56
+
57
+ ```bash
58
+ claude mcp add signdocs \
59
+ -e SIGNDOCS_CLIENT_ID=your_client_id \
60
+ -e SIGNDOCS_CLIENT_SECRET=your_client_secret \
61
+ -e SIGNDOCS_ENVIRONMENT=hml \
62
+ -- npx -y @signdocs-brasil/mcp-server
63
+ ```
64
+
65
+ ## Tools
66
+
67
+ | Tool | Action | Safety |
68
+ |---|---|---|
69
+ | `create_signing_session` | Create single-signer session, returns `signingUrl` | ⚠️ binding + quota |
70
+ | `get_signing_session_status` | Poll session status | read |
71
+ | `get_signing_session` | Full session bootstrap | read |
72
+ | `list_signing_sessions` | List by status | read |
73
+ | `cancel_signing_session` | Cancel a session | ⚠️ irreversible |
74
+ | `resend_signing_session_otp` | Resend OTP | write |
75
+ | `create_envelope` | Multi-signer envelope | ⚠️ binding + quota |
76
+ | `get_envelope` | Envelope details | read |
77
+ | `add_session_to_envelope` | Add a signer, returns `signingUrl` | ⚠️ binding + quota |
78
+ | `get_envelope_combined_stamp` | Combined stamped PDF URL | read |
79
+ | `upload_document` | Attach a PDF to a transaction | write |
80
+ | `download_document` | Presigned download URLs | read |
81
+ | `list_transactions` | Search/list transactions | read |
82
+ | `get_transaction` | Transaction details | read |
83
+ | `cancel_transaction` | Cancel a transaction | ⚠️ irreversible |
84
+ | `get_evidence` | Cryptographic evidence | read |
85
+ | `verify_evidence` | Public evidence verification | read |
86
+ | `verify_envelope` | Public envelope verification | read |
87
+ | `verify_document` | Detect signatures in a PDF | ⚠️ PROD-only + quota |
88
+ | `register_webhook` / `list_webhooks` / `delete_webhook` / `test_webhook` | Webhook management | mixed |
89
+
90
+ ⚠️ tools carry `destructiveHint` annotations **and** a warning in their
91
+ description so compliant clients prompt the human before invoking them.
92
+ Annotations are only hints — review your client's auto-approval settings.
93
+
94
+ ### Not yet exposed
95
+ Trust sessions (`/v1/trust-sessions`) and `resend-invite` are not in
96
+ `@signdocs-brasil/api` v1.6.1 yet; they'll be added when the SDK supports them.
97
+ Digital ICP-Brasil A1 signing runs through the lower-level transaction/advance
98
+ flow rather than a hosted-session profile.
99
+
100
+ ## Resources
101
+
102
+ The server exposes grounding resources the model can read on demand:
103
+
104
+ - `signdocs://quickstart` — the minimal signing flow + safety notes
105
+ - `signdocs://policy-profiles` — valid `policyProfile` values and CUSTOM steps
106
+ - `signdocs://webhook-events` — all subscribable event types
107
+
108
+ ## Development
109
+
110
+ ```bash
111
+ npm install
112
+ npm run build # tsc → dist/
113
+ npm test # vitest (pure unit tests, no network)
114
+ npm run inspect # build + launch MCP Inspector against the stdio server
115
+ ```
116
+
117
+ ## Roadmap
118
+
119
+ - **v0.1 (this release):** local stdio server, full tool catalog, env credentials.
120
+ - **Phase 2:** remote Streamable-HTTP transport with per-tenant OAuth (the tool
121
+ layer is already transport-agnostic — see `src/http/server.ts`).
@@ -0,0 +1,31 @@
1
+ /**
2
+ * MCP tool annotation presets. These are *hints* — clients MAY use them to
3
+ * decide whether to auto-run a tool or prompt the human first. Because not
4
+ * every client honors them, binding/quota tools ALSO carry an explicit warning
5
+ * sentence in their `description` (see tools/*.ts).
6
+ *
7
+ * @see https://modelcontextprotocol.io/specification — Tool annotations
8
+ */
9
+ export interface ToolAnnotations {
10
+ title?: string;
11
+ /** Tool does not modify state. */
12
+ readOnlyHint?: boolean;
13
+ /** Tool may perform irreversible / consequential changes → clients should confirm. */
14
+ destructiveHint?: boolean;
15
+ /** Repeated identical calls have no additional effect. */
16
+ idempotentHint?: boolean;
17
+ /** Tool talks to an external system (always true here — it's a remote API). */
18
+ openWorldHint?: boolean;
19
+ }
20
+ /** Pure reads (status, get, list, public verification). */
21
+ export declare const READ_ONLY: ToolAnnotations;
22
+ /** Writes that are not legally binding nor irreversible (upload, resend OTP, register webhook). */
23
+ export declare const WRITE_SAFE: ToolAnnotations;
24
+ /**
25
+ * Legally-binding, quota-consuming, or irreversible actions
26
+ * (create signing session/envelope, cancel, verify-document).
27
+ * Clients SHOULD prompt the human before invoking.
28
+ */
29
+ export declare const DESTRUCTIVE: ToolAnnotations;
30
+ /** Prefix prepended to descriptions of binding/quota tools so even annotation-blind clients surface the risk. */
31
+ export declare const CONFIRM_WARNING: string;
@@ -0,0 +1,29 @@
1
+ /** Pure reads (status, get, list, public verification). */
2
+ export const READ_ONLY = {
3
+ readOnlyHint: true,
4
+ destructiveHint: false,
5
+ idempotentHint: true,
6
+ openWorldHint: true,
7
+ };
8
+ /** Writes that are not legally binding nor irreversible (upload, resend OTP, register webhook). */
9
+ export const WRITE_SAFE = {
10
+ readOnlyHint: false,
11
+ destructiveHint: false,
12
+ idempotentHint: false,
13
+ openWorldHint: true,
14
+ };
15
+ /**
16
+ * Legally-binding, quota-consuming, or irreversible actions
17
+ * (create signing session/envelope, cancel, verify-document).
18
+ * Clients SHOULD prompt the human before invoking.
19
+ */
20
+ export const DESTRUCTIVE = {
21
+ readOnlyHint: false,
22
+ destructiveHint: true,
23
+ idempotentHint: false,
24
+ openWorldHint: true,
25
+ };
26
+ /** Prefix prepended to descriptions of binding/quota tools so even annotation-blind clients surface the risk. */
27
+ export const CONFIRM_WARNING = '⚠️ This performs a consequential, possibly irreversible action (legally-binding signature ' +
28
+ 'request and/or quota consumption). Confirm with the human before calling. ';
29
+ //# sourceMappingURL=annotations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotations.js","sourceRoot":"","sources":["../src/annotations.ts"],"names":[],"mappings":"AAoBA,2DAA2D;AAC3D,MAAM,CAAC,MAAM,SAAS,GAAoB;IACxC,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,KAAK;IACtB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,mGAAmG;AACnG,MAAM,CAAC,MAAM,UAAU,GAAoB;IACzC,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,KAAK;IACtB,cAAc,EAAE,KAAK;IACrB,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC1C,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,KAAK;IACrB,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,iHAAiH;AACjH,MAAM,CAAC,MAAM,eAAe,GAC1B,4FAA4F;IAC5F,4EAA4E,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { createServer } from '../server.js';
4
+ /**
5
+ * stdio entrypoint. AI clients (Claude Desktop/Code, Cursor, …) launch this
6
+ * binary and speak MCP over stdin/stdout. NEVER write to stdout here — it is
7
+ * the protocol channel; diagnostics go to stderr.
8
+ */
9
+ async function main() {
10
+ const server = createServer();
11
+ const transport = new StdioServerTransport();
12
+ await server.connect(transport);
13
+ process.stderr.write('[signdocs-mcp] server started on stdio\n');
14
+ }
15
+ main().catch((err) => {
16
+ process.stderr.write(`[signdocs-mcp] fatal: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
17
+ process.exit(1);
18
+ });
19
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/bin/stdio.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;AACnE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { SignDocsBrasilClient } from '@signdocs-brasil/api';
2
+ /**
3
+ * Thin wrapper that turns environment variables into a configured
4
+ * {@link SignDocsBrasilClient}. The official SDK owns the OAuth2
5
+ * `client_credentials` exchange, token caching, retries and RFC-7807
6
+ * error parsing — this module only resolves config and memoizes the client.
7
+ */
8
+ export type Environment = 'production' | 'hml';
9
+ /**
10
+ * Full read/write scope set. `verification:write` is only authorized for
11
+ * PRODUCTION credentials, but the token endpoint silently filters out any
12
+ * scope the credential isn't entitled to, so requesting it everywhere is safe.
13
+ */
14
+ export declare const DEFAULT_SCOPES: string[];
15
+ export interface ResolvedEnv {
16
+ clientId: string;
17
+ clientSecret: string;
18
+ environment: Environment;
19
+ baseUrl: string;
20
+ scopes: string[];
21
+ }
22
+ export declare function resolveEnvironment(raw?: string): Environment;
23
+ export declare function getBaseUrl(environment: Environment, override?: string): string;
24
+ export declare function readEnv(env?: NodeJS.ProcessEnv): ResolvedEnv;
25
+ /** Lazily build and memoize the SDK client. Throws if credentials are missing. */
26
+ export declare function getClient(env?: NodeJS.ProcessEnv): SignDocsBrasilClient;
27
+ /** The resolved environment behind the active client (for diagnostics/guards). */
28
+ export declare function getResolvedEnv(env?: NodeJS.ProcessEnv): ResolvedEnv;
29
+ /** Reset memoized state — used by tests. */
30
+ export declare function resetClientCache(): void;
31
+ /**
32
+ * Assemble the shareable signing link. A session's `url` alone is NOT the
33
+ * link — it must carry the one-time embed token (`clientSecret`) as `?cs=`.
34
+ */
35
+ export declare function buildSigningUrl(url: string, clientSecret: string): string;
package/dist/client.js ADDED
@@ -0,0 +1,80 @@
1
+ import { SignDocsBrasilClient } from '@signdocs-brasil/api';
2
+ const BASE_URLS = {
3
+ production: 'https://api.signdocs.com.br',
4
+ // NOTE: HML uses the dash form (api-hml), NOT api.hml.
5
+ hml: 'https://api-hml.signdocs.com.br',
6
+ };
7
+ /**
8
+ * Full read/write scope set. `verification:write` is only authorized for
9
+ * PRODUCTION credentials, but the token endpoint silently filters out any
10
+ * scope the credential isn't entitled to, so requesting it everywhere is safe.
11
+ */
12
+ export const DEFAULT_SCOPES = [
13
+ 'transactions:read',
14
+ 'transactions:write',
15
+ 'steps:write',
16
+ 'evidence:read',
17
+ 'webhooks:write',
18
+ 'verification:write',
19
+ ];
20
+ export function resolveEnvironment(raw) {
21
+ const v = (raw ?? 'hml').trim().toLowerCase();
22
+ if (v === 'production' || v === 'prod')
23
+ return 'production';
24
+ if (v === 'hml' || v === 'homologacao' || v === 'homologação' || v === 'staging')
25
+ return 'hml';
26
+ throw new Error(`Invalid SIGNDOCS_ENVIRONMENT "${raw}". Use "production" or "hml".`);
27
+ }
28
+ export function getBaseUrl(environment, override) {
29
+ const trimmed = override?.trim();
30
+ return trimmed ? trimmed : BASE_URLS[environment];
31
+ }
32
+ export function readEnv(env = process.env) {
33
+ const clientId = env.SIGNDOCS_CLIENT_ID?.trim();
34
+ const clientSecret = env.SIGNDOCS_CLIENT_SECRET?.trim();
35
+ if (!clientId || !clientSecret) {
36
+ throw new Error('Missing SignDocs credentials. Set SIGNDOCS_CLIENT_ID and SIGNDOCS_CLIENT_SECRET ' +
37
+ '(get them from app.signdocs.com.br → API).');
38
+ }
39
+ const environment = resolveEnvironment(env.SIGNDOCS_ENVIRONMENT);
40
+ const baseUrl = getBaseUrl(environment, env.SIGNDOCS_BASE_URL);
41
+ const scopesRaw = env.SIGNDOCS_SCOPES?.trim();
42
+ const scopes = scopesRaw ? scopesRaw.split(/\s+/) : DEFAULT_SCOPES;
43
+ return { clientId, clientSecret, environment, baseUrl, scopes };
44
+ }
45
+ let cached;
46
+ let cachedEnv;
47
+ /** Lazily build and memoize the SDK client. Throws if credentials are missing. */
48
+ export function getClient(env = process.env) {
49
+ if (cached)
50
+ return cached;
51
+ const cfg = readEnv(env);
52
+ cachedEnv = cfg;
53
+ cached = new SignDocsBrasilClient({
54
+ clientId: cfg.clientId,
55
+ clientSecret: cfg.clientSecret,
56
+ baseUrl: cfg.baseUrl,
57
+ scopes: cfg.scopes,
58
+ });
59
+ return cached;
60
+ }
61
+ /** The resolved environment behind the active client (for diagnostics/guards). */
62
+ export function getResolvedEnv(env = process.env) {
63
+ if (cachedEnv)
64
+ return cachedEnv;
65
+ cachedEnv = readEnv(env);
66
+ return cachedEnv;
67
+ }
68
+ /** Reset memoized state — used by tests. */
69
+ export function resetClientCache() {
70
+ cached = undefined;
71
+ cachedEnv = undefined;
72
+ }
73
+ /**
74
+ * Assemble the shareable signing link. A session's `url` alone is NOT the
75
+ * link — it must carry the one-time embed token (`clientSecret`) as `?cs=`.
76
+ */
77
+ export function buildSigningUrl(url, clientSecret) {
78
+ return `${url}?cs=${encodeURIComponent(clientSecret)}`;
79
+ }
80
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Phase 2 — remote Streamable-HTTP transport (designed, not yet built).
3
+ *
4
+ * The tool/resource layer in ../server.ts is deliberately transport-agnostic,
5
+ * so going remote is purely an entrypoint + auth concern:
6
+ *
7
+ * import { StreamableHTTPServerTransport } from
8
+ * '@modelcontextprotocol/sdk/server/streamableHttp.js';
9
+ * const server = createServer();
10
+ * const transport = new StreamableHTTPServerTransport({ ...});
11
+ * await server.connect(transport);
12
+ * // node:http handler → transport.handleRequest(req, res, body)
13
+ *
14
+ * Open design decisions to settle before implementing (see plan):
15
+ *
16
+ * 1. AUTH / MULTI-TENANCY. Unlike stdio (one set of env credentials), a
17
+ * hosted server serves many tenants. The MCP server should act as an
18
+ * OAuth Resource Server: each connecting AI presents its own SignDocs
19
+ * bearer token (issued by the existing /oauth2/token AS). Validate it with
20
+ * the same ES256/KMS verifier external-api uses (auth-middleware.ts) and
21
+ * build a PER-REQUEST SDK client scoped to that tenant — do NOT reuse the
22
+ * process-wide getClient() singleton, which would cross tenant boundaries.
23
+ *
24
+ * 2. DEPLOYMENT. Reuse the external-api Lambda + API Gateway pattern via a new
25
+ * NestedStack (the Core stack is at the CFN 500-resource limit — follow the
26
+ * EnvelopeHandlersStack precedent), or a small container behind the same WAF.
27
+ *
28
+ * 3. SESSION MODE. Stateless (sessionIdGenerator: undefined) fits serverless;
29
+ * confirm against the MCP spec version current at build time, plus DCR /
30
+ * protected-resource metadata discovery needs.
31
+ *
32
+ * Intentionally not wired up yet so the v0.1 stdio package stays dependency-light.
33
+ */
34
+ export declare function createHttpServer(): never;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Phase 2 — remote Streamable-HTTP transport (designed, not yet built).
3
+ *
4
+ * The tool/resource layer in ../server.ts is deliberately transport-agnostic,
5
+ * so going remote is purely an entrypoint + auth concern:
6
+ *
7
+ * import { StreamableHTTPServerTransport } from
8
+ * '@modelcontextprotocol/sdk/server/streamableHttp.js';
9
+ * const server = createServer();
10
+ * const transport = new StreamableHTTPServerTransport({ ...});
11
+ * await server.connect(transport);
12
+ * // node:http handler → transport.handleRequest(req, res, body)
13
+ *
14
+ * Open design decisions to settle before implementing (see plan):
15
+ *
16
+ * 1. AUTH / MULTI-TENANCY. Unlike stdio (one set of env credentials), a
17
+ * hosted server serves many tenants. The MCP server should act as an
18
+ * OAuth Resource Server: each connecting AI presents its own SignDocs
19
+ * bearer token (issued by the existing /oauth2/token AS). Validate it with
20
+ * the same ES256/KMS verifier external-api uses (auth-middleware.ts) and
21
+ * build a PER-REQUEST SDK client scoped to that tenant — do NOT reuse the
22
+ * process-wide getClient() singleton, which would cross tenant boundaries.
23
+ *
24
+ * 2. DEPLOYMENT. Reuse the external-api Lambda + API Gateway pattern via a new
25
+ * NestedStack (the Core stack is at the CFN 500-resource limit — follow the
26
+ * EnvelopeHandlersStack precedent), or a small container behind the same WAF.
27
+ *
28
+ * 3. SESSION MODE. Stateless (sessionIdGenerator: undefined) fits serverless;
29
+ * confirm against the MCP spec version current at build time, plus DCR /
30
+ * protected-resource metadata discovery needs.
31
+ *
32
+ * Intentionally not wired up yet so the v0.1 stdio package stays dependency-light.
33
+ */
34
+ export function createHttpServer() {
35
+ throw new Error('Remote HTTP transport is not implemented in v0.1. Use the stdio entrypoint (bin/stdio.ts). ' +
36
+ 'See src/http/server.ts for the Phase 2 design.');
37
+ }
38
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/http/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,IAAI,KAAK,CACb,6FAA6F;QAC3F,gDAAgD,CACnD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerResources(server: McpServer): void;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Static MCP resources that ground the agent so it calls tools correctly
3
+ * without guessing. Content is inlined (no filesystem/sibling-repo coupling)
4
+ * so the published package is self-contained.
5
+ */
6
+ const POLICY_PROFILES = `# SignDocs policy profiles
7
+
8
+ Pass one of these as \`policyProfile\` when creating a signing session or
9
+ adding an envelope signer. An invalid value returns HTTP 400.
10
+
11
+ | profile | steps | typical use |
12
+ |-----------------------|-----------------------------------------|-------------|
13
+ | CLICK_ONLY | clickwrap acceptance | low-risk consent |
14
+ | CLICK_PLUS_OTP | clickwrap + e-mail/SMS one-time code | standard e-signature |
15
+ | BIOMETRIC | facial liveness + match | high-assurance identity |
16
+ | BIOMETRIC_PLUS_OTP | biometric + OTP | strongest hosted assurance |
17
+ | CUSTOM | caller-defined ordered steps | supply \`customSteps\` |
18
+
19
+ When \`policyProfile=CUSTOM\`, set \`customSteps\` to an ordered list of step
20
+ types, e.g. ["CLICKWRAP","OTP","BIOMETRIC_LIVENESS","BIOMETRIC_MATCH"].
21
+
22
+ Digital ICP-Brasil A1 certificate signing is exposed through the transaction/
23
+ advance flow (step type DIGITAL_CERTIFICATE), not as a hosted-session profile.
24
+ `;
25
+ const QUICKSTART = `# SignDocs MCP quickstart
26
+
27
+ Most integrations need only the high-level **signing session** flow:
28
+
29
+ 1. \`create_signing_session\` with purpose=DOCUMENT_SIGNATURE, a policyProfile,
30
+ the signer, and the base64 PDF (\`documentBase64\`). The result includes a
31
+ ready-to-share **signingUrl** (the session url + one-time embed token).
32
+ 2. Deliver the signingUrl to the signer (or pass \`owner.email\` so SignDocs
33
+ e-mails them automatically), or subscribe to webhooks for completion.
34
+ 3. Poll \`get_signing_session_status\` (or rely on webhooks) until COMPLETED.
35
+ 4. The COMPLETED status carries an \`evidenceId\` — verify it publicly with
36
+ \`verify_evidence\`.
37
+
38
+ Multiple signers on one document → use \`create_envelope\` then
39
+ \`add_session_to_envelope\` once per signer (signerIndex 0..N-1).
40
+
41
+ Environment: set SIGNDOCS_ENVIRONMENT=hml (default) for testing or
42
+ =production for live, binding signatures. HML data expires after ~7 days and
43
+ the verify_document tool is production-only.
44
+
45
+ ⚠️ create_/add_/cancel_ tools take real, quota-consuming, often
46
+ legally-binding actions. Confirm with the human before invoking them.
47
+ `;
48
+ const WEBHOOK_EVENTS = `# SignDocs webhook events
49
+
50
+ Subscribe via \`register_webhook\`. Payloads are signed with HMAC-SHA256 using
51
+ the secret returned at registration (300s replay tolerance).
52
+
53
+ TRANSACTION.CREATED, TRANSACTION.COMPLETED, TRANSACTION.CANCELLED,
54
+ TRANSACTION.FAILED, TRANSACTION.EXPIRED
55
+ STEP.STARTED, STEP.COMPLETED, STEP.FAILED
56
+ SIGNING_SESSION.CREATED, SIGNING_SESSION.COMPLETED, SIGNING_SESSION.CANCELLED,
57
+ SIGNING_SESSION.EXPIRED
58
+ ENVELOPE.CREATED, ENVELOPE.ALL_SIGNED, ENVELOPE.EXPIRED
59
+ QUOTA.WARNING, API.DEPRECATION_NOTICE
60
+ `;
61
+ const RESOURCES = [
62
+ {
63
+ uri: 'signdocs://policy-profiles',
64
+ name: 'policy-profiles',
65
+ title: 'SignDocs policy profiles',
66
+ description: 'Valid policyProfile values and CUSTOM step types.',
67
+ text: POLICY_PROFILES,
68
+ },
69
+ {
70
+ uri: 'signdocs://quickstart',
71
+ name: 'quickstart',
72
+ title: 'SignDocs MCP quickstart',
73
+ description: 'The minimal signing-session flow and safety notes.',
74
+ text: QUICKSTART,
75
+ },
76
+ {
77
+ uri: 'signdocs://webhook-events',
78
+ name: 'webhook-events',
79
+ title: 'SignDocs webhook events',
80
+ description: 'All subscribable webhook event types.',
81
+ text: WEBHOOK_EVENTS,
82
+ },
83
+ ];
84
+ export function registerResources(server) {
85
+ for (const r of RESOURCES) {
86
+ server.registerResource(r.name, r.uri, { title: r.title, description: r.description, mimeType: 'text/markdown' }, async (uri) => ({
87
+ contents: [{ uri: uri.href, mimeType: 'text/markdown', text: r.text }],
88
+ }));
89
+ }
90
+ }
91
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;CAkBvB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBlB,CAAC;AAEF,MAAM,cAAc,GAAG;;;;;;;;;;;;CAYtB,CAAC;AAUF,MAAM,SAAS,GAAqB;IAClC;QACE,GAAG,EAAE,4BAA4B;QACjC,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,mDAAmD;QAChE,IAAI,EAAE,eAAe;KACtB;IACD;QACE,GAAG,EAAE,uBAAuB;QAC5B,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,oDAAoD;QACjE,IAAI,EAAE,UAAU;KACjB;IACD;QACE,GAAG,EAAE,2BAA2B;QAChC,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,uCAAuC;QACpD,IAAI,EAAE,cAAc;KACrB;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,gBAAgB,CACrB,CAAC,CAAC,IAAI,EACN,CAAC,CAAC,GAAG,EACL,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,EACzE,KAAK,EAAE,GAAQ,EAAE,EAAE,CAAC,CAAC;YACnB,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SACvE,CAAC,CACH,CAAC;IACJ,CAAC;AACH,CAAC"}