@proof-holdings/mcp-server 1.0.0 → 1.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 (107) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +223 -216
  3. package/dist/authBoundary.d.ts +182 -0
  4. package/dist/authBoundary.d.ts.map +1 -0
  5. package/dist/authBoundary.js +328 -0
  6. package/dist/authBoundary.js.map +1 -0
  7. package/dist/factory.d.ts +33 -0
  8. package/dist/factory.d.ts.map +1 -0
  9. package/dist/factory.js +123 -0
  10. package/dist/factory.js.map +1 -0
  11. package/dist/http.d.ts +63 -3
  12. package/dist/http.d.ts.map +1 -1
  13. package/dist/http.js +183 -4
  14. package/dist/http.js.map +1 -1
  15. package/dist/remote.d.ts +111 -0
  16. package/dist/remote.d.ts.map +1 -0
  17. package/dist/remote.js +787 -0
  18. package/dist/remote.js.map +1 -0
  19. package/dist/server.js +11 -57
  20. package/dist/server.js.map +1 -1
  21. package/dist/tools/{projects.d.ts → accounts.d.ts} +1 -1
  22. package/dist/tools/accounts.d.ts.map +1 -0
  23. package/dist/tools/accounts.js +70 -0
  24. package/dist/tools/accounts.js.map +1 -0
  25. package/dist/tools/api-keys.d.ts.map +1 -1
  26. package/dist/tools/api-keys.js +14 -5
  27. package/dist/tools/api-keys.js.map +1 -1
  28. package/dist/tools/auth-flows.d.ts +4 -0
  29. package/dist/tools/auth-flows.d.ts.map +1 -0
  30. package/dist/tools/auth-flows.js +34 -0
  31. package/dist/tools/auth-flows.js.map +1 -0
  32. package/dist/tools/authorizations.d.ts +4 -0
  33. package/dist/tools/authorizations.d.ts.map +1 -0
  34. package/dist/tools/authorizations.js +111 -0
  35. package/dist/tools/authorizations.js.map +1 -0
  36. package/dist/tools/circles.d.ts +4 -0
  37. package/dist/tools/circles.d.ts.map +1 -0
  38. package/dist/tools/circles.js +215 -0
  39. package/dist/tools/circles.js.map +1 -0
  40. package/dist/tools/confirmations.d.ts +4 -0
  41. package/dist/tools/confirmations.d.ts.map +1 -0
  42. package/dist/tools/confirmations.js +86 -0
  43. package/dist/tools/confirmations.js.map +1 -0
  44. package/dist/tools/delegation-verify-outcomes.d.ts +23 -0
  45. package/dist/tools/delegation-verify-outcomes.d.ts.map +1 -0
  46. package/dist/tools/delegation-verify-outcomes.js +51 -0
  47. package/dist/tools/delegation-verify-outcomes.js.map +1 -0
  48. package/dist/tools/delegation-verify.d.ts +24 -0
  49. package/dist/tools/delegation-verify.d.ts.map +1 -0
  50. package/dist/tools/delegation-verify.js +192 -0
  51. package/dist/tools/delegation-verify.js.map +1 -0
  52. package/dist/tools/delegations.d.ts +4 -0
  53. package/dist/tools/delegations.d.ts.map +1 -0
  54. package/dist/tools/delegations.js +84 -0
  55. package/dist/tools/delegations.js.map +1 -0
  56. package/dist/tools/domains.d.ts.map +1 -1
  57. package/dist/tools/domains.js +1 -2
  58. package/dist/tools/domains.js.map +1 -1
  59. package/dist/tools/hitl-keys.d.ts +4 -0
  60. package/dist/tools/hitl-keys.d.ts.map +1 -0
  61. package/dist/tools/hitl-keys.js +52 -0
  62. package/dist/tools/hitl-keys.js.map +1 -0
  63. package/dist/tools/hitl.d.ts +4 -0
  64. package/dist/tools/hitl.d.ts.map +1 -0
  65. package/dist/tools/hitl.js +151 -0
  66. package/dist/tools/hitl.js.map +1 -0
  67. package/dist/tools/phones.js +1 -1
  68. package/dist/tools/phones.js.map +1 -1
  69. package/dist/tools/profiles.d.ts.map +1 -1
  70. package/dist/tools/profiles.js +73 -0
  71. package/dist/tools/profiles.js.map +1 -1
  72. package/dist/tools/proof-me.d.ts +4 -0
  73. package/dist/tools/proof-me.d.ts.map +1 -0
  74. package/dist/tools/proof-me.js +107 -0
  75. package/dist/tools/proof-me.js.map +1 -0
  76. package/dist/tools/proofs.d.ts.map +1 -1
  77. package/dist/tools/proofs.js +9 -6
  78. package/dist/tools/proofs.js.map +1 -1
  79. package/dist/tools/render-auth-link.d.ts +3 -0
  80. package/dist/tools/render-auth-link.d.ts.map +1 -0
  81. package/dist/tools/render-auth-link.js +30 -0
  82. package/dist/tools/render-auth-link.js.map +1 -0
  83. package/dist/tools/sessions.js +5 -5
  84. package/dist/tools/sessions.js.map +1 -1
  85. package/dist/tools/settings.d.ts.map +1 -1
  86. package/dist/tools/settings.js +69 -0
  87. package/dist/tools/settings.js.map +1 -1
  88. package/dist/tools/twofa.d.ts.map +1 -1
  89. package/dist/tools/twofa.js +16 -3
  90. package/dist/tools/twofa.js.map +1 -1
  91. package/dist/tools/user-requests.d.ts.map +1 -1
  92. package/dist/tools/user-requests.js +1 -2
  93. package/dist/tools/user-requests.js.map +1 -1
  94. package/dist/tools/verification-requests.d.ts.map +1 -1
  95. package/dist/tools/verification-requests.js +40 -13
  96. package/dist/tools/verification-requests.js.map +1 -1
  97. package/dist/tools/verifications.d.ts.map +1 -1
  98. package/dist/tools/verifications.js +59 -12
  99. package/dist/tools/verifications.js.map +1 -1
  100. package/dist/types.d.ts +18 -0
  101. package/dist/types.d.ts.map +1 -1
  102. package/dist/types.js +114 -5
  103. package/dist/types.js.map +1 -1
  104. package/package.json +11 -5
  105. package/dist/tools/projects.d.ts.map +0 -1
  106. package/dist/tools/projects.js +0 -159
  107. package/dist/tools/projects.js.map +0 -1
@@ -0,0 +1,123 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { HttpClient } from './http.js';
3
+ import { accessNoticeFor, serverInstructions } from './authBoundary.js';
4
+ import { registerTools as registerVerifications } from './tools/verifications.js';
5
+ import { registerTools as registerVerificationRequests } from './tools/verification-requests.js';
6
+ import { registerTools as registerProofs } from './tools/proofs.js';
7
+ import { registerTools as registerSessions } from './tools/sessions.js';
8
+ import { registerTools as registerAssets } from './tools/assets.js';
9
+ import { registerTools as registerAuth } from './tools/auth.js';
10
+ import { registerTools as registerSettings } from './tools/settings.js';
11
+ import { registerTools as registerTemplates } from './tools/templates.js';
12
+ import { registerTools as registerWebhookDeliveries } from './tools/webhook-deliveries.js';
13
+ import { registerTools as registerBilling } from './tools/billing.js';
14
+ import { registerTools as registerProfiles } from './tools/profiles.js';
15
+ import { registerTools as registerEmails } from './tools/emails.js';
16
+ import { registerTools as registerPhones } from './tools/phones.js';
17
+ import { registerTools as registerApiKeys } from './tools/api-keys.js';
18
+ import { registerTools as registerTwofa } from './tools/twofa.js';
19
+ import { registerTools as registerDomains } from './tools/domains.js';
20
+ import { registerTools as registerDnsCredentials } from './tools/dns-credentials.js';
21
+ import { registerTools as registerUserRequests } from './tools/user-requests.js';
22
+ import { registerTools as registerUserDomainVerify } from './tools/user-domain-verify.js';
23
+ import { registerTools as registerPublicProfiles } from './tools/public-profiles.js';
24
+ import { registerTools as registerAuthorizations } from './tools/authorizations.js';
25
+ import { registerTools as registerConfirmations } from './tools/confirmations.js';
26
+ import { registerTools as registerHitl } from './tools/hitl.js';
27
+ import { registerTools as registerHitlKeys } from './tools/hitl-keys.js';
28
+ import { registerTools as registerProofMe } from './tools/proof-me.js';
29
+ import { registerTools as registerCircles } from './tools/circles.js';
30
+ import { registerTools as registerDelegations } from './tools/delegations.js';
31
+ import { registerTools as registerDelegationVerify } from './tools/delegation-verify.js';
32
+ import { registerTools as registerAuthFlows } from './tools/auth-flows.js';
33
+ import { registerTools as registerAccounts } from './tools/accounts.js';
34
+ import { registerTools as registerRenderAuthLink } from './tools/render-auth-link.js';
35
+ /**
36
+ * Builds one MCP server with its own HTTP client.
37
+ *
38
+ * Why a factory at all (`h-mcp-remote`, SC-4): the stdio entrypoint serves exactly one user, so one
39
+ * `HttpClient` per process is correct there. The remote server serves many, and `HttpClient` keeps
40
+ * `sessionToken` / `refreshToken` as INSTANCE fields written by `captureSetCookie` — sharing one
41
+ * across connections would hand the next user the previous user's logged-in session. So the unit of
42
+ * isolation is the connection, and this function is that unit.
43
+ *
44
+ * The registration list below is the ONLY copy in the package: `server.ts` calls this rather than
45
+ * repeating it. A second copy would work on the day it was written and drift one module at a time
46
+ * afterwards, with both paths green — `__tests__/factory.test.ts` pins both the list's completeness
47
+ * against `src/tools` and the absence of a second copy in `server.ts`.
48
+ */
49
+ export function createProofServer(options) {
50
+ const http = new HttpClient({
51
+ apiKey: options.apiKey,
52
+ baseUrl: options.baseUrl,
53
+ remote: options.remote,
54
+ });
55
+ const access = { remote: options.remote, hasCredential: Boolean(options.apiKey) };
56
+ const server = new McpServer({
57
+ name: 'proof-holdings',
58
+ // The version every client reads back from `initialize`, and the one a user quotes in a bug
59
+ // report. A LITERAL rather than a read of `mcp/package.json` — a CHOICE, not a constraint;
60
+ // the manifest is reachable from here. What makes the literal safe is the pin below, never
61
+ // that choice. Held equal to the manifest by
62
+ // `src/__tests__/drift/delegation-publication.test.ts` (h-npm-registry-release). If this is
63
+ // ever replaced by a real read, delete the pin in the same change: a pin over a derived
64
+ // value guards nothing.
65
+ version: '1.1.0',
66
+ }, { instructions: serverInstructions(access) });
67
+ const bound = server.tool.bind(server);
68
+ /**
69
+ * The registrar every module below is handed, wrapping `server.tool` so the access notice is
70
+ * appended in ONE place (`h-fix-mcp-agent-facing-text`, SC-1).
71
+ *
72
+ * Editing 176 descriptions by hand would have put the same sentence in 176 places, drifting one
73
+ * tool at a time, and each copy would have had to know the transport it was registered on —
74
+ * which a description literal cannot. Here the classification in `authBoundary.ts` is read once,
75
+ * beside the connection that determines it. The signature is `server.tool`'s own, and only the
76
+ * description argument is touched: a registration whose second argument is not a string is passed
77
+ * through untouched rather than being coerced, because the SDK accepts several call shapes and a
78
+ * wrapper that assumes one would corrupt the others.
79
+ */
80
+ const tool = ((...args) => {
81
+ const [name, description] = args;
82
+ if (typeof name === 'string' && typeof description === 'string') {
83
+ const rest = args.slice(2);
84
+ return bound(name, description + accessNoticeFor(name, access), ...rest);
85
+ }
86
+ return bound(...args);
87
+ });
88
+ registerVerifications(tool, http);
89
+ registerVerificationRequests(tool, http);
90
+ registerProofs(tool, http);
91
+ registerSessions(tool, http);
92
+ registerAssets(tool, http);
93
+ registerAuth(tool, http);
94
+ registerSettings(tool, http);
95
+ registerTemplates(tool, http);
96
+ registerWebhookDeliveries(tool, http);
97
+ registerBilling(tool, http);
98
+ registerProfiles(tool, http);
99
+ registerEmails(tool, http);
100
+ registerPhones(tool, http);
101
+ registerApiKeys(tool, http);
102
+ registerTwofa(tool, http);
103
+ registerDomains(tool, http);
104
+ registerDnsCredentials(tool, http);
105
+ registerUserRequests(tool, http);
106
+ registerUserDomainVerify(tool, http);
107
+ registerPublicProfiles(tool, http);
108
+ registerAuthorizations(tool, http);
109
+ registerConfirmations(tool, http);
110
+ registerHitl(tool, http);
111
+ registerHitlKeys(tool, http);
112
+ registerProofMe(tool, http);
113
+ registerCircles(tool, http);
114
+ registerDelegations(tool, http);
115
+ // Takes the base URL rather than the HTTP client: verifying a third party's delegation runs
116
+ // against PUBLIC surfaces only and carries no API key.
117
+ registerDelegationVerify(tool, { baseUrl: options.baseUrl });
118
+ registerAuthFlows(tool, http);
119
+ registerAccounts(tool, http);
120
+ registerRenderAuthLink(tool);
121
+ return { server, http };
122
+ }
123
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts CHANGED
@@ -1,26 +1,86 @@
1
1
  export interface HttpClientConfig {
2
- apiKey: string;
2
+ /**
3
+ * API key (Bearer). OPTIONAL — the server also runs in public mode, where the bootstrap
4
+ * and verification surfaces work with no credential at all and every other tool answers
5
+ * `api_key_required` instead of the process exiting at startup.
6
+ */
7
+ apiKey?: string;
3
8
  baseUrl: string;
4
9
  timeout?: number;
5
10
  maxRetries?: number;
11
+ /**
12
+ * True when this client serves the REMOTE transport (`src/remote.ts`) rather than a local stdio
13
+ * process. It changes exactly one thing — what the "you need a key" refusal tells the user to do
14
+ * — because the stdio instruction (set `PROOF_API_KEY`, restart the server) is impossible on a
15
+ * server somebody else runs.
16
+ */
17
+ remote?: boolean;
6
18
  }
7
19
  type QueryValue = string | number | boolean | undefined;
20
+ /**
21
+ * Endpoints the client may call with NO credential — the public mode surface.
22
+ *
23
+ * Stored as (method, prefix) PAIRS, not bare prefixes, and the reason is load-bearing:
24
+ * `/api/v1/auth/sessions` is the prefix of two public routes (create a login session, poll one)
25
+ * AND of two `jwt+api_key` ones (`GET /auth/sessions` lists sessions, `DELETE /auth/sessions/:id`
26
+ * revokes one). A prefix-only list would mark those two public, so a keyless call would travel to
27
+ * the network and come back `invalid_token` instead of getting the structured hint here.
28
+ *
29
+ * The drift rule `validateMcpPublicPathCoverage` (scripts/validate-api-map.ts) requires every
30
+ * `auth: public` + `mcp: available` endpoint in docs/api-map.yaml to appear below. That rule is a
31
+ * LOWER BOUND, not the definition: the two poll routes are carried here but not required by it,
32
+ * because the map holds them `planned` (they are reached through `wait_for_login` /
33
+ * `wait_for_account_creation` rather than by a tool of their own). Removing them would leave both
34
+ * wait tools broken in public mode while every check stayed green.
35
+ */
36
+ export declare const PUBLIC_PATHS: ReadonlyArray<{
37
+ method: string;
38
+ prefix: string;
39
+ }>;
8
40
  export declare class HttpClient {
9
41
  readonly baseUrl: string;
10
- private readonly apiKey;
42
+ private readonly apiKey?;
11
43
  private readonly timeout;
12
44
  private readonly maxRetries;
45
+ private readonly remote;
46
+ private sessionToken?;
47
+ private refreshToken?;
48
+ private refreshing?;
13
49
  constructor(config: HttpClientConfig);
14
50
  request<T>(method: string, path: string, options?: {
15
51
  body?: unknown;
16
52
  query?: Record<string, QueryValue>;
53
+ headers?: Record<string, string>;
54
+ /** Internal: set on the post-refresh retry to prevent an infinite refresh loop. */
55
+ _refreshed?: boolean;
17
56
  }): Promise<T>;
57
+ /**
58
+ * True once a login flow has put a session on this client (`captureSetCookie`).
59
+ *
60
+ * Boolean only, never the token: the remote server needs to know whether this CONNECTION has
61
+ * been signed in — the bootstrap road `start_login` opens — and nothing else. Without it a caller
62
+ * with no API key looks identical before and after signing in, and the tools behind
63
+ * `SESSION_AUTH_PREFIXES` are refused to a user who just logged in.
64
+ */
65
+ hasSessionToken(): boolean;
18
66
  get<T>(path: string, query?: Record<string, QueryValue>): Promise<T>;
19
67
  post<T>(path: string, body?: unknown): Promise<T>;
20
68
  put<T>(path: string, body?: unknown): Promise<T>;
21
69
  patch<T>(path: string, body?: unknown): Promise<T>;
22
- del<T>(path: string): Promise<T>;
70
+ del<T>(path: string, body?: unknown): Promise<T>;
23
71
  private buildUrl;
72
+ /** True for endpoints behind `jwtAuth` — the user JWT session surface. */
73
+ private usesSessionAuth;
74
+ /** Capture the `token` / `refresh_token` cookies the login + refresh flows set via Set-Cookie. */
75
+ private captureSetCookie;
76
+ /**
77
+ * Exchange the refresh token for a rotated access token. Returns true on success.
78
+ * Concurrent callers share one in-flight refresh so a single-use refresh token is
79
+ * only spent once (otherwise the loser would post a consumed token and wipe the
80
+ * freshly-rotated session).
81
+ */
82
+ private refreshSession;
83
+ private doRefresh;
24
84
  private backoff;
25
85
  private sleep;
26
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAExD,qBAAa,UAAU;IACrB,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,MAAM,EAAE,gBAAgB;IAO9B,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KACpC,GACA,OAAO,CAAC,CAAC,CAAC;IA2Eb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhC,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;CAGd;AAED,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;aAClB,OAAO,CAAC,EAAE,OAAO;gBAHjC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,OAAO,YAAA;CAMpC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAwBxD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAO1E,CAAC;AAQF,qBAAa,UAAU;IACrB,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,UAAU,CAAC,CAAmB;gBAE1B,MAAM,EAAE,gBAAgB;IAQ9B,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,mFAAmF;QACnF,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GACA,OAAO,CAAC,CAAC,CAAC;IA2Hb;;;;;;;OAOG;IACH,eAAe,IAAI,OAAO;IAI1B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,OAAO,CAAC,QAAQ;IAYhB,0EAA0E;IAC1E,OAAO,CAAC,eAAe;IAIvB,kGAAkG;IAClG,OAAO,CAAC,gBAAgB;IAexB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;YASR,SAAS;IA6BvB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;CAGd;AAED,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;aAClB,OAAO,CAAC,EAAE,OAAO;gBAHjC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,OAAO,YAAA;CAMpC"}
package/dist/http.js CHANGED
@@ -1,16 +1,103 @@
1
- const VERSION = '1.0.0';
1
+ // The version this client sends in its own `User-Agent` (`proof-mcp/<version>`), i.e. what the
2
+ // issuer's logs attribute a request to. A LITERAL for the same reason `factory.ts`'s `serverInfo`
3
+ // one is, and safe for the same reason: the pin, not the choice. Held equal to `mcp/package.json`
4
+ // by `src/__tests__/drift/delegation-publication.test.ts` (h-npm-registry-release).
5
+ //
6
+ // Of the carriers a version bump has to move, this is the one it misses: a bare constant at the
7
+ // top of a module about HTTP, where nothing about editing the manifest leads a reader.
8
+ const VERSION = '1.1.0';
9
+ // Path prefixes protected by `jwtAuth` ONLY (pure JWT surface — these 401 with an API key).
10
+ // Deliberately excludes the dual-auth (`jwtOrApiKeyAuth`) endpoints that already work with the
11
+ // API key and enforce its scopes — `/me/{profiles,settings,usage,export,assets}`,
12
+ // `/profiles/me`, `/profiles/me/assets`, `/profiles/profiles/:id/proofs`, and `/auth/sessions`
13
+ // (list/revoke). Sending the JWT there would silently switch the principal from the API-key
14
+ // tenant to the logged-in user and bypass scope checks. The two `/profiles/me/*` entries
15
+ // below are the jwt-only exceptions inside that otherwise dual-auth family.
16
+ const SESSION_AUTH_PREFIXES = [
17
+ '/api/v1/me/emails',
18
+ '/api/v1/me/phones',
19
+ '/api/v1/me/api-keys',
20
+ '/api/v1/me/2fa',
21
+ '/api/v1/me/domains',
22
+ '/api/v1/me/dns-credentials',
23
+ '/api/v1/me/dns-providers',
24
+ '/api/v1/me/verification-requests',
25
+ '/api/v1/me/verify/',
26
+ '/api/v1/me/account',
27
+ '/api/v1/profiles/me/username',
28
+ '/api/v1/profiles/me/proofs',
29
+ ];
30
+ /**
31
+ * Endpoints the client may call with NO credential — the public mode surface.
32
+ *
33
+ * Stored as (method, prefix) PAIRS, not bare prefixes, and the reason is load-bearing:
34
+ * `/api/v1/auth/sessions` is the prefix of two public routes (create a login session, poll one)
35
+ * AND of two `jwt+api_key` ones (`GET /auth/sessions` lists sessions, `DELETE /auth/sessions/:id`
36
+ * revokes one). A prefix-only list would mark those two public, so a keyless call would travel to
37
+ * the network and come back `invalid_token` instead of getting the structured hint here.
38
+ *
39
+ * The drift rule `validateMcpPublicPathCoverage` (scripts/validate-api-map.ts) requires every
40
+ * `auth: public` + `mcp: available` endpoint in docs/api-map.yaml to appear below. That rule is a
41
+ * LOWER BOUND, not the definition: the two poll routes are carried here but not required by it,
42
+ * because the map holds them `planned` (they are reached through `wait_for_login` /
43
+ * `wait_for_account_creation` rather than by a tool of their own). Removing them would leave both
44
+ * wait tools broken in public mode while every check stayed green.
45
+ */
46
+ export const PUBLIC_PATHS = [
47
+ { method: 'POST', prefix: '/api/v1/proofs/validate' },
48
+ { method: 'GET', prefix: '/api/v1/proofs/revoked' },
49
+ { method: 'POST', prefix: '/api/v1/auth/sessions' },
50
+ { method: 'GET', prefix: '/api/v1/auth/sessions/' },
51
+ { method: 'POST', prefix: '/api/v1/accounts' },
52
+ { method: 'GET', prefix: '/api/v1/accounts/' },
53
+ ];
54
+ /** True when (method, path) is on the public surface above. Method is compared case-insensitively. */
55
+ function isPublicPath(method, path) {
56
+ const verb = method.toUpperCase();
57
+ return PUBLIC_PATHS.some((p) => p.method === verb && path.startsWith(p.prefix));
58
+ }
2
59
  export class HttpClient {
3
60
  baseUrl;
4
61
  apiKey;
5
62
  timeout;
6
63
  maxRetries;
64
+ remote;
65
+ sessionToken;
66
+ refreshToken;
67
+ refreshing;
7
68
  constructor(config) {
8
69
  this.apiKey = config.apiKey;
9
70
  this.baseUrl = config.baseUrl.replace(/\/$/, '');
10
71
  this.timeout = config.timeout ?? 30_000;
11
72
  this.maxRetries = config.maxRetries ?? 2;
73
+ this.remote = config.remote ?? false;
12
74
  }
13
75
  async request(method, path, options) {
76
+ const useSession = this.usesSessionAuth(path) && !!this.sessionToken;
77
+ const bearer = useSession ? this.sessionToken : this.apiKey;
78
+ // Public mode: answer before the network rather than after it. A credential-less call to a
79
+ // keyed route would otherwise spend a round trip to return `invalid_token`, which reads to an
80
+ // agent as "the key is wrong" rather than "there is no key yet".
81
+ if (!bearer && !isPublicPath(method, path)) {
82
+ // The wording matters as much as the code, and it has to be true for the transport the caller
83
+ // is actually on. It once said "run create_account to get a key from inside this session",
84
+ // which an agent can follow forever without succeeding on stdio: the key is read from the
85
+ // environment and has no runtime setter. But the fix was written for stdio alone, and on the
86
+ // REMOTE server the resulting instruction is not merely unhelpful — it is impossible, since
87
+ // nobody can set an env var on somebody else's pod or restart it. A signed-in remote user
88
+ // calling a tool outside the session surface is exactly who reads this.
89
+ throw new ApiError(this.remote
90
+ ? 'This operation needs a Proof account with an API key. Connect this server to your account ' +
91
+ '(your client\'s sign-in / "Authenticate" step), then call the tool again. Signing in with ' +
92
+ 'start_login alone covers your own contact and account records — emails, phones, domains, ' +
93
+ 'API keys, 2FA, DNS credentials, verification requests, your public profile\'s username ' +
94
+ 'and proof list; account-wide reads such as the platform summary, settings and usage ' +
95
+ 'need the key that connecting grants.'
96
+ : 'This operation needs a Proof API key, which must be present in PROOF_API_KEY when the server starts. ' +
97
+ 'Without one you can still create an account or sign in (create_account, start_login) and check ' +
98
+ 'proofs and delegations. If you are signed in, create_api_key works over that session — but the new ' +
99
+ 'key takes effect only after it is put in PROOF_API_KEY and this MCP server is restarted.', 'api_key_required', 401);
100
+ }
14
101
  const url = this.buildUrl(path, options?.query);
15
102
  let lastError;
16
103
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
@@ -20,14 +107,17 @@ export class HttpClient {
20
107
  const response = await fetch(url, {
21
108
  method,
22
109
  headers: {
110
+ ...options?.headers,
23
111
  'Content-Type': 'application/json',
24
- 'Authorization': `Bearer ${this.apiKey}`,
112
+ ...(bearer ? { 'Authorization': `Bearer ${bearer}` } : {}),
25
113
  'User-Agent': `proof-mcp/${VERSION}`,
26
114
  },
27
115
  body: options?.body ? JSON.stringify(options.body) : undefined,
28
116
  signal: controller.signal,
29
117
  });
30
118
  clearTimeout(timeoutId);
119
+ // Capture the JWT session cookie set by the login / account-creation flows
120
+ this.captureSetCookie(response);
31
121
  if (response.status === 429 && attempt < this.maxRetries) {
32
122
  const retryAfter = response.headers.get('Retry-After');
33
123
  const parsed = retryAfter ? parseInt(retryAfter, 10) : NaN;
@@ -44,6 +134,15 @@ export class HttpClient {
44
134
  const apiError = body.error;
45
135
  const code = apiError?.code ?? `http_${response.status}`;
46
136
  const message = apiError?.message ?? `Request failed with status ${response.status}`;
137
+ // Expired session JWT: refresh once and retry the original request.
138
+ if (response.status === 401 &&
139
+ code === 'token_expired' &&
140
+ useSession &&
141
+ !options?._refreshed &&
142
+ this.refreshToken &&
143
+ (await this.refreshSession())) {
144
+ return this.request(method, path, { ...options, _refreshed: true });
145
+ }
47
146
  throw new ApiError(message, code, response.status, apiError?.details);
48
147
  }
49
148
  return body;
@@ -68,6 +167,17 @@ export class HttpClient {
68
167
  }
69
168
  throw new ApiError(lastError?.message ?? 'Network request failed', 'network_error', 0);
70
169
  }
170
+ /**
171
+ * True once a login flow has put a session on this client (`captureSetCookie`).
172
+ *
173
+ * Boolean only, never the token: the remote server needs to know whether this CONNECTION has
174
+ * been signed in — the bootstrap road `start_login` opens — and nothing else. Without it a caller
175
+ * with no API key looks identical before and after signing in, and the tools behind
176
+ * `SESSION_AUTH_PREFIXES` are refused to a user who just logged in.
177
+ */
178
+ hasSessionToken() {
179
+ return !!this.sessionToken;
180
+ }
71
181
  get(path, query) {
72
182
  return this.request('GET', path, { query });
73
183
  }
@@ -80,8 +190,8 @@ export class HttpClient {
80
190
  patch(path, body) {
81
191
  return this.request('PATCH', path, { body });
82
192
  }
83
- del(path) {
84
- return this.request('DELETE', path);
193
+ del(path, body) {
194
+ return this.request('DELETE', path, body ? { body } : undefined);
85
195
  }
86
196
  buildUrl(path, query) {
87
197
  const url = new URL(path, this.baseUrl);
@@ -94,6 +204,75 @@ export class HttpClient {
94
204
  }
95
205
  return url.toString();
96
206
  }
207
+ /** True for endpoints behind `jwtAuth` — the user JWT session surface. */
208
+ usesSessionAuth(path) {
209
+ return SESSION_AUTH_PREFIXES.some((prefix) => path.startsWith(prefix)) || path === '/api/v1/auth/me';
210
+ }
211
+ /** Capture the `token` / `refresh_token` cookies the login + refresh flows set via Set-Cookie. */
212
+ captureSetCookie(response) {
213
+ // getSetCookie() requires Node >= 18.14 / undici; guard so older runtimes don't throw.
214
+ if (typeof response.headers.getSetCookie !== 'function')
215
+ return;
216
+ const cookies = response.headers.getSetCookie();
217
+ for (const cookie of cookies) {
218
+ const pair = cookie.split(';', 1)[0];
219
+ const eq = pair.indexOf('=');
220
+ if (eq === -1)
221
+ continue;
222
+ const name = pair.slice(0, eq).trim();
223
+ const value = pair.slice(eq + 1).trim();
224
+ if (name === 'token')
225
+ this.sessionToken = value;
226
+ else if (name === 'refresh_token')
227
+ this.refreshToken = value;
228
+ }
229
+ }
230
+ /**
231
+ * Exchange the refresh token for a rotated access token. Returns true on success.
232
+ * Concurrent callers share one in-flight refresh so a single-use refresh token is
233
+ * only spent once (otherwise the loser would post a consumed token and wipe the
234
+ * freshly-rotated session).
235
+ */
236
+ refreshSession() {
237
+ if (!this.refreshToken)
238
+ return Promise.resolve(false);
239
+ if (this.refreshing)
240
+ return this.refreshing;
241
+ this.refreshing = this.doRefresh().finally(() => {
242
+ this.refreshing = undefined;
243
+ });
244
+ return this.refreshing;
245
+ }
246
+ async doRefresh() {
247
+ const controller = new AbortController();
248
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
249
+ try {
250
+ const response = await fetch(this.buildUrl('/api/v1/auth/refresh'), {
251
+ method: 'POST',
252
+ headers: {
253
+ 'Content-Type': 'application/json',
254
+ 'Cookie': `refresh_token=${this.refreshToken}`,
255
+ 'User-Agent': `proof-mcp/${VERSION}`,
256
+ },
257
+ signal: controller.signal,
258
+ });
259
+ if (!response.ok) {
260
+ this.sessionToken = undefined;
261
+ this.refreshToken = undefined;
262
+ return false;
263
+ }
264
+ this.captureSetCookie(response);
265
+ return true;
266
+ }
267
+ catch {
268
+ this.sessionToken = undefined;
269
+ this.refreshToken = undefined;
270
+ return false;
271
+ }
272
+ finally {
273
+ clearTimeout(timeoutId);
274
+ }
275
+ }
97
276
  backoff(attempt) {
98
277
  return Math.min(1000 * Math.pow(2, attempt), 10000);
99
278
  }
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -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;AA2RD;;;;;;;;;;;;;;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,CAwT7E"}