@proof-holdings/mcp-server 1.0.0 → 1.2.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.
- package/LICENSE +1 -1
- package/README.md +220 -217
- package/dist/authBoundary.d.ts +193 -0
- package/dist/authBoundary.d.ts.map +1 -0
- package/dist/authBoundary.js +341 -0
- package/dist/authBoundary.js.map +1 -0
- package/dist/factory.d.ts +35 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +130 -0
- package/dist/factory.js.map +1 -0
- package/dist/http.d.ts +78 -3
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +251 -6
- package/dist/http.js.map +1 -1
- package/dist/remote.d.ts +111 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +789 -0
- package/dist/remote.js.map +1 -0
- package/dist/server.js +11 -57
- package/dist/server.js.map +1 -1
- package/dist/toolAnnotations.d.ts +27 -0
- package/dist/toolAnnotations.d.ts.map +1 -0
- package/dist/toolAnnotations.js +158 -0
- package/dist/toolAnnotations.js.map +1 -0
- package/dist/tools/{projects.d.ts → accounts.d.ts} +1 -1
- package/dist/tools/accounts.d.ts.map +1 -0
- package/dist/tools/accounts.js +70 -0
- package/dist/tools/accounts.js.map +1 -0
- package/dist/tools/api-keys.d.ts.map +1 -1
- package/dist/tools/api-keys.js +14 -5
- package/dist/tools/api-keys.js.map +1 -1
- package/dist/tools/auth-flows.d.ts +4 -0
- package/dist/tools/auth-flows.d.ts.map +1 -0
- package/dist/tools/auth-flows.js +34 -0
- package/dist/tools/auth-flows.js.map +1 -0
- package/dist/tools/auth.js +1 -1
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/authorizations.d.ts +4 -0
- package/dist/tools/authorizations.d.ts.map +1 -0
- package/dist/tools/authorizations.js +111 -0
- package/dist/tools/authorizations.js.map +1 -0
- package/dist/tools/circles.d.ts +4 -0
- package/dist/tools/circles.d.ts.map +1 -0
- package/dist/tools/circles.js +215 -0
- package/dist/tools/circles.js.map +1 -0
- package/dist/tools/confirmations.d.ts +4 -0
- package/dist/tools/confirmations.d.ts.map +1 -0
- package/dist/tools/confirmations.js +86 -0
- package/dist/tools/confirmations.js.map +1 -0
- package/dist/tools/delegation-verify-outcomes.d.ts +23 -0
- package/dist/tools/delegation-verify-outcomes.d.ts.map +1 -0
- package/dist/tools/delegation-verify-outcomes.js +51 -0
- package/dist/tools/delegation-verify-outcomes.js.map +1 -0
- package/dist/tools/delegation-verify.d.ts +24 -0
- package/dist/tools/delegation-verify.d.ts.map +1 -0
- package/dist/tools/delegation-verify.js +192 -0
- package/dist/tools/delegation-verify.js.map +1 -0
- package/dist/tools/delegations.d.ts +4 -0
- package/dist/tools/delegations.d.ts.map +1 -0
- package/dist/tools/delegations.js +84 -0
- package/dist/tools/delegations.js.map +1 -0
- package/dist/tools/domains.d.ts.map +1 -1
- package/dist/tools/domains.js +1 -2
- package/dist/tools/domains.js.map +1 -1
- package/dist/tools/hitl-keys.d.ts +4 -0
- package/dist/tools/hitl-keys.d.ts.map +1 -0
- package/dist/tools/hitl-keys.js +52 -0
- package/dist/tools/hitl-keys.js.map +1 -0
- package/dist/tools/hitl.d.ts +4 -0
- package/dist/tools/hitl.d.ts.map +1 -0
- package/dist/tools/hitl.js +151 -0
- package/dist/tools/hitl.js.map +1 -0
- package/dist/tools/phones.js +1 -1
- package/dist/tools/phones.js.map +1 -1
- package/dist/tools/profiles.d.ts.map +1 -1
- package/dist/tools/profiles.js +73 -0
- package/dist/tools/profiles.js.map +1 -1
- package/dist/tools/proof-me.d.ts +4 -0
- package/dist/tools/proof-me.d.ts.map +1 -0
- package/dist/tools/proof-me.js +36 -0
- package/dist/tools/proof-me.js.map +1 -0
- package/dist/tools/proofs.d.ts.map +1 -1
- package/dist/tools/proofs.js +9 -6
- package/dist/tools/proofs.js.map +1 -1
- package/dist/tools/render-auth-link.d.ts +3 -0
- package/dist/tools/render-auth-link.d.ts.map +1 -0
- package/dist/tools/render-auth-link.js +30 -0
- package/dist/tools/render-auth-link.js.map +1 -0
- package/dist/tools/sessions.js +5 -5
- package/dist/tools/sessions.js.map +1 -1
- package/dist/tools/settings.d.ts.map +1 -1
- package/dist/tools/settings.js +77 -2
- package/dist/tools/settings.js.map +1 -1
- package/dist/tools/twofa.d.ts.map +1 -1
- package/dist/tools/twofa.js +16 -3
- package/dist/tools/twofa.js.map +1 -1
- package/dist/tools/user-requests.d.ts.map +1 -1
- package/dist/tools/user-requests.js +1 -2
- package/dist/tools/user-requests.js.map +1 -1
- package/dist/tools/verification-requests.d.ts.map +1 -1
- package/dist/tools/verification-requests.js +40 -13
- package/dist/tools/verification-requests.js.map +1 -1
- package/dist/tools/verifications.d.ts.map +1 -1
- package/dist/tools/verifications.js +59 -12
- package/dist/tools/verifications.js.map +1 -1
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +114 -5
- package/dist/types.js.map +1 -1
- package/package.json +11 -5
- package/dist/tools/projects.d.ts.map +0 -1
- package/dist/tools/projects.js +0 -159
- package/dist/tools/projects.js.map +0 -1
package/dist/remote.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Remote entrypoint: the Proof MCP server over Streamable HTTP (`h-mcp-remote`, SC-3 + SC-4).
|
|
4
|
+
*
|
|
5
|
+
* Deployed as its own service, NOT as a route inside the existing backend. The reason is
|
|
6
|
+
* structural rather than stylistic: `src/cluster.ts` forks one worker per CPU and round-robins
|
|
7
|
+
* between them, while a Streamable HTTP session lives in the memory of ONE process. Mounting this
|
|
8
|
+
* on the clustered backend would lose sessions by default, not in an edge case. The deployment
|
|
9
|
+
* therefore pins requests to a replica by the REPLICA PREFIX this server puts in every session id
|
|
10
|
+
* it mints (`<replica>.<uuid>`); see `replicaId` below for why hashing the id itself cannot work,
|
|
11
|
+
* and `k8s/mcp-remote/nginx-mcp.conf` for the routing that consumes the prefix. That routing is
|
|
12
|
+
* deliberately NOT in the base nginx configmap — see that directory's README for the ingress it
|
|
13
|
+
* would otherwise take down, and `src/__tests__/drift/mcp-remote-deployment.test.ts`, which asserts
|
|
14
|
+
* the base stays free of it.
|
|
15
|
+
*
|
|
16
|
+
* ANONYMOUS FIRST, KEYED ON REQUEST (`h-mcp-oauth-remote-wiring`). Every connection starts with the
|
|
17
|
+
* keyless surface and the ability to log in through the normal flows; a client that has been
|
|
18
|
+
* through the OAuth ceremony (`h-mcp-oauth-server`) presents the API key it was granted, and this
|
|
19
|
+
* server reads it from the `Authorization` header ONLY. A `?api_key=` query parameter is never
|
|
20
|
+
* read: a token in a URL is copied into proxy logs and `Referer`, and the standard clients all send
|
|
21
|
+
* a header. The token is resolved ONCE, at open, by self-inspection (`GET /api/v1/me/api-key`) —
|
|
22
|
+
* purely so the refusal is legible; nothing is cached from it, and the key travels to the backend
|
|
23
|
+
* on every call, which is what makes a revocation take effect immediately rather than at session
|
|
24
|
+
* TTL. Where the 401 lands is a measurement, not a preference: on the TOOL CALL that needs an
|
|
25
|
+
* account, because a 401 on `initialize` reached the human as a connection timeout and cost the
|
|
26
|
+
* anonymous connection entirely (`docs/mcp-oauth-client-probe.md`).
|
|
27
|
+
*
|
|
28
|
+
* Each connection needs its OWN `HttpClient` for two reasons now: `captureSetCookie` writes a login
|
|
29
|
+
* session onto the instance, and the API key of one connection must never be reachable from
|
|
30
|
+
* another. The boundary between keyless and keyed tools lives in `./authBoundary.js`.
|
|
31
|
+
*/
|
|
32
|
+
import { type Server } from 'node:http';
|
|
33
|
+
import { HttpClient } from './http.js';
|
|
34
|
+
export interface RemoteServerOptions {
|
|
35
|
+
baseUrl: string;
|
|
36
|
+
/** Maximum concurrent MCP sessions. Each one registers the full tool set, so this is a memory bound. */
|
|
37
|
+
maxSessions?: number;
|
|
38
|
+
/** Idle time after which a session is closed and dropped. */
|
|
39
|
+
sessionTtlMs?: number;
|
|
40
|
+
sweepIntervalMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Which replica this process is. It is PREFIXED to every session id it mints, and the proxy
|
|
43
|
+
* routes on that prefix.
|
|
44
|
+
*
|
|
45
|
+
* This is not decoration, it is the only thing that makes sticky routing possible. Hashing the
|
|
46
|
+
* session id — the obvious reading of "sticky by mcp-session-id" — cannot work: the replica is
|
|
47
|
+
* chosen when the connection OPENS, and at that moment no session id exists yet, so the hash of
|
|
48
|
+
* the id minted afterwards lands wherever it lands. Measured on a two-replica nginx stand, that
|
|
49
|
+
* arrangement sent 45 of 60 follow-up requests to a replica that had never heard of the session.
|
|
50
|
+
* Carrying the replica in the id turns the routing decision into a lookup instead of a guess.
|
|
51
|
+
*/
|
|
52
|
+
replicaId?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface RemoteServer {
|
|
55
|
+
httpServer: Server;
|
|
56
|
+
sessionCount(): number;
|
|
57
|
+
/** Test seam: the live per-session HTTP clients, to assert they are distinct instances. */
|
|
58
|
+
debugClients(): HttpClient[];
|
|
59
|
+
close(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Ceiling on the burst, expressed FLEET-WIDE because the bucket it spends is fleet-wide.
|
|
63
|
+
*
|
|
64
|
+
* The burst below is sized off `maxSessions`, which is per replica — and the bucket it lands in is
|
|
65
|
+
* `ipRateLimit(300, 60, 'me')` keyed on the pod's egress IP, i.e. shared by every replica. So the
|
|
66
|
+
* figure that matters is `replicas × burst`, and stating the burst per replica beside a rate stated
|
|
67
|
+
* fleet-wide is how those two drift apart: at `replicas: 3` and the default cap, an unbounded burst
|
|
68
|
+
* is 300 — the entire minute's bucket, spent at exactly the moment those sessions also begin their
|
|
69
|
+
* ordinary `/me/*` calls through it. `src/__tests__/drift/mcp-remote-deployment.test.ts` derives
|
|
70
|
+
* `replicas × min(MCP_MAX_SESSIONS, RESOLVE_BURST_CEILING)` — the EFFECTIVE burst, not this
|
|
71
|
+
* constant alone — against the backend's own literal, so SCALING THE FLEET reddens it instead of
|
|
72
|
+
* surfacing as 429s in production. Raising THIS constant is caught elsewhere and deliberately so:
|
|
73
|
+
* while the manifest cap sits at or below the ceiling, the effective burst does not move, and the
|
|
74
|
+
* unit case in `mcp/__tests__/remote.test.ts` that runs a cap ABOVE the ceiling is what holds it.
|
|
75
|
+
*/
|
|
76
|
+
export declare const RESOLVE_BURST_CEILING = 100;
|
|
77
|
+
/**
|
|
78
|
+
* A token bucket over the self-inspection above. Process-local on purpose: what it protects is this
|
|
79
|
+
* process's own outbound channel, and a shared counter would need a store this service does not
|
|
80
|
+
* have and must not grow for a defensive bound.
|
|
81
|
+
*
|
|
82
|
+
* Exported for its own test. The arithmetic below has a failure mode no HTTP-level case can reach
|
|
83
|
+
* cheaply — a clock that steps BACKWARDS — and the previous version's clock seam was a default
|
|
84
|
+
* parameter on an unexported function, i.e. unreachable from a test even in principle. That is the
|
|
85
|
+
* same shape `positiveIntEnv` above was fixed for once already.
|
|
86
|
+
*/
|
|
87
|
+
export declare function createResolveBudget(maxSessions: number, now?: () => number): {
|
|
88
|
+
/** True when a self-inspection may be sent; consumes one token. */
|
|
89
|
+
take(): boolean;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* The replica's own index: `MCP_REPLICA_ID` if set, otherwise the ordinal a StatefulSet puts at the
|
|
93
|
+
* end of the pod hostname (`mcp-remote-1` → `1`). Falls back to `0` for a single process, which is
|
|
94
|
+
* what the stdio-style local run and the tests get.
|
|
95
|
+
*/
|
|
96
|
+
/**
|
|
97
|
+
* Reads a positive-integer setting, falling back to the built-in default on anything else.
|
|
98
|
+
*
|
|
99
|
+
* A typo must not disable the bound it configures. `Number('abc')` is NaN, and both
|
|
100
|
+
* `size >= NaN` and `lastSeen < NaN` are false — so an unparseable value would fail OPEN on exactly
|
|
101
|
+
* the two limits this server relies on, with the pod still passing every probe. INTEGER rather than
|
|
102
|
+
* merely finite-and-positive, because `MCP_SESSION_TTL_MS=0.5` would sweep every session on the
|
|
103
|
+
* first tick and `MCP_MAX_SESSIONS=0.5` would silently mean one.
|
|
104
|
+
*
|
|
105
|
+
* Exported and at module scope so it can be tested — the previous version was a closure inside the
|
|
106
|
+
* entrypoint guard, unreachable from a test even in principle, which left the fix one edit wide.
|
|
107
|
+
*/
|
|
108
|
+
export declare function positiveIntEnv(name: string, env?: NodeJS.ProcessEnv): number | undefined;
|
|
109
|
+
export declare function resolveReplicaId(explicit?: string, hostname?: string): string;
|
|
110
|
+
export declare function createRemoteServer(options: RemoteServerOptions): RemoteServer;
|
|
111
|
+
//# sourceMappingURL=remote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAiBjG,OAAO,EAAY,UAAU,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,IAAI,MAAM,CAAC;IACvB,2FAA2F;IAC3F,YAAY,IAAI,UAAU,EAAE,CAAC;IAC7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AA6RD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAkBzC;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,MAAgC;IAMhG,mEAAmE;YAC3D,OAAO;EAclB;AAoGD;;;;GAIG;AACH;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAarG;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAI5F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CA0T7E"}
|