mcp-trellis 2.2.0 → 3.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 (173) hide show
  1. package/README.md +61 -52
  2. package/dist/adapters/node-request.d.ts +5 -0
  3. package/dist/adapters/node-request.d.ts.map +1 -1
  4. package/dist/adapters/node-request.js +17 -1
  5. package/dist/adapters/node-request.js.map +1 -1
  6. package/dist/adapters/node.d.ts +15 -0
  7. package/dist/adapters/node.d.ts.map +1 -1
  8. package/dist/adapters/node.js +38 -0
  9. package/dist/adapters/node.js.map +1 -1
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/app.js +1 -0
  12. package/dist/app.js.map +1 -1
  13. package/dist/audit.d.ts.map +1 -1
  14. package/dist/audit.js +63 -6
  15. package/dist/audit.js.map +1 -1
  16. package/dist/auth/signed/payload.d.ts +31 -0
  17. package/dist/auth/signed/payload.d.ts.map +1 -0
  18. package/dist/auth/signed/payload.js +85 -0
  19. package/dist/auth/signed/payload.js.map +1 -0
  20. package/dist/auth/signed/refresh.d.ts +34 -0
  21. package/dist/auth/signed/refresh.d.ts.map +1 -0
  22. package/dist/auth/signed/refresh.js +95 -0
  23. package/dist/auth/signed/refresh.js.map +1 -0
  24. package/dist/auth/signed/token.d.ts +41 -0
  25. package/dist/auth/signed/token.d.ts.map +1 -0
  26. package/dist/auth/signed/token.js +103 -0
  27. package/dist/auth/signed/token.js.map +1 -0
  28. package/dist/clients.js +2 -2
  29. package/dist/clients.js.map +1 -1
  30. package/dist/deprecated.d.ts +15 -15
  31. package/dist/deprecated.d.ts.map +1 -1
  32. package/dist/deprecated.js +15 -15
  33. package/dist/deprecated.js.map +1 -1
  34. package/dist/http/body.d.ts +4 -0
  35. package/dist/http/body.d.ts.map +1 -1
  36. package/dist/http/body.js +9 -2
  37. package/dist/http/body.js.map +1 -1
  38. package/dist/http/origins.d.ts.map +1 -1
  39. package/dist/http/origins.js +13 -2
  40. package/dist/http/origins.js.map +1 -1
  41. package/dist/mcp/dispatch.d.ts.map +1 -1
  42. package/dist/mcp/dispatch.js +2 -1
  43. package/dist/mcp/dispatch.js.map +1 -1
  44. package/dist/mcp/methods.d.ts +8 -0
  45. package/dist/mcp/methods.d.ts.map +1 -1
  46. package/dist/mcp/methods.js +14 -1
  47. package/dist/mcp/methods.js.map +1 -1
  48. package/dist/mcp/registry.d.ts.map +1 -1
  49. package/dist/mcp/registry.js +15 -3
  50. package/dist/mcp/registry.js.map +1 -1
  51. package/dist/mcp/rpc-handlers.d.ts.map +1 -1
  52. package/dist/mcp/rpc-handlers.js +60 -13
  53. package/dist/mcp/rpc-handlers.js.map +1 -1
  54. package/dist/mcp/tools.d.ts +14 -0
  55. package/dist/mcp/tools.d.ts.map +1 -1
  56. package/dist/mcp/tools.js +118 -23
  57. package/dist/mcp/tools.js.map +1 -1
  58. package/dist/mcp/validate.d.ts +7 -1
  59. package/dist/mcp/validate.d.ts.map +1 -1
  60. package/dist/mcp/validate.js +58 -24
  61. package/dist/mcp/validate.js.map +1 -1
  62. package/dist/oauth/audit.d.ts +10 -0
  63. package/dist/oauth/audit.d.ts.map +1 -1
  64. package/dist/oauth/audit.js +25 -1
  65. package/dist/oauth/audit.js.map +1 -1
  66. package/dist/oauth/cimd/cimd-parse.d.ts.map +1 -1
  67. package/dist/oauth/cimd/cimd-parse.js +27 -14
  68. package/dist/oauth/cimd/cimd-parse.js.map +1 -1
  69. package/dist/oauth/cimd/cimd-ssrf.d.ts +8 -4
  70. package/dist/oauth/cimd/cimd-ssrf.d.ts.map +1 -1
  71. package/dist/oauth/cimd/cimd-ssrf.js +13 -39
  72. package/dist/oauth/cimd/cimd-ssrf.js.map +1 -1
  73. package/dist/oauth/cimd/cimd.d.ts +14 -18
  74. package/dist/oauth/cimd/cimd.d.ts.map +1 -1
  75. package/dist/oauth/cimd/cimd.js +53 -37
  76. package/dist/oauth/cimd/cimd.js.map +1 -1
  77. package/dist/oauth/cimd/dns.d.ts +4 -0
  78. package/dist/oauth/cimd/dns.d.ts.map +1 -0
  79. package/dist/oauth/cimd/dns.js +45 -0
  80. package/dist/oauth/cimd/dns.js.map +1 -0
  81. package/dist/oauth/cimd/failure.d.ts +19 -0
  82. package/dist/oauth/cimd/failure.d.ts.map +1 -0
  83. package/dist/oauth/cimd/failure.js +31 -0
  84. package/dist/oauth/cimd/failure.js.map +1 -0
  85. package/dist/oauth/cimd/types.d.ts +15 -1
  86. package/dist/oauth/cimd/types.d.ts.map +1 -1
  87. package/dist/oauth/cimd/types.js +1 -1
  88. package/dist/oauth/cimd/types.js.map +1 -1
  89. package/dist/oauth/cimd/url-guard.d.ts +5 -0
  90. package/dist/oauth/cimd/url-guard.d.ts.map +1 -0
  91. package/dist/oauth/cimd/url-guard.js +53 -0
  92. package/dist/oauth/cimd/url-guard.js.map +1 -0
  93. package/dist/oauth/config.d.ts +3 -0
  94. package/dist/oauth/config.d.ts.map +1 -1
  95. package/dist/oauth/config.js +5 -1
  96. package/dist/oauth/config.js.map +1 -1
  97. package/dist/oauth/crypto/clientauth.d.ts.map +1 -1
  98. package/dist/oauth/crypto/clientauth.js +7 -6
  99. package/dist/oauth/crypto/clientauth.js.map +1 -1
  100. package/dist/oauth/deprecated.d.ts +22 -22
  101. package/dist/oauth/deprecated.d.ts.map +1 -1
  102. package/dist/oauth/deprecated.js +22 -22
  103. package/dist/oauth/deprecated.js.map +1 -1
  104. package/dist/oauth/endpoints/authorize.d.ts.map +1 -1
  105. package/dist/oauth/endpoints/authorize.js +25 -7
  106. package/dist/oauth/endpoints/authorize.js.map +1 -1
  107. package/dist/oauth/endpoints/consent/error-page.d.ts +6 -0
  108. package/dist/oauth/endpoints/consent/error-page.d.ts.map +1 -0
  109. package/dist/oauth/endpoints/consent/error-page.js +60 -0
  110. package/dist/oauth/endpoints/consent/error-page.js.map +1 -0
  111. package/dist/oauth/endpoints/{consent.d.ts → consent/handler.d.ts} +2 -2
  112. package/dist/oauth/endpoints/consent/handler.d.ts.map +1 -0
  113. package/dist/oauth/endpoints/{consent.js → consent/handler.js} +20 -13
  114. package/dist/oauth/endpoints/consent/handler.js.map +1 -0
  115. package/dist/oauth/endpoints/{consent-page.d.ts → consent/page.d.ts} +2 -2
  116. package/dist/oauth/endpoints/consent/page.d.ts.map +1 -0
  117. package/dist/oauth/endpoints/consent/page.js +106 -0
  118. package/dist/oauth/endpoints/consent/page.js.map +1 -0
  119. package/dist/oauth/endpoints/metadata.d.ts +0 -1
  120. package/dist/oauth/endpoints/metadata.d.ts.map +1 -1
  121. package/dist/oauth/endpoints/metadata.js.map +1 -1
  122. package/dist/oauth/endpoints/register.js +3 -3
  123. package/dist/oauth/endpoints/register.js.map +1 -1
  124. package/dist/oauth/endpoints/token.d.ts.map +1 -1
  125. package/dist/oauth/endpoints/token.js +9 -6
  126. package/dist/oauth/endpoints/token.js.map +1 -1
  127. package/dist/oauth/endpoints/wellknown.d.ts.map +1 -1
  128. package/dist/oauth/endpoints/wellknown.js +2 -9
  129. package/dist/oauth/endpoints/wellknown.js.map +1 -1
  130. package/dist/oauth/policy/redirect.d.ts +4 -0
  131. package/dist/oauth/policy/redirect.d.ts.map +1 -1
  132. package/dist/oauth/policy/redirect.js +15 -1
  133. package/dist/oauth/policy/redirect.js.map +1 -1
  134. package/dist/oauth/policy/reqbody.d.ts +6 -1
  135. package/dist/oauth/policy/reqbody.d.ts.map +1 -1
  136. package/dist/oauth/policy/reqbody.js +8 -3
  137. package/dist/oauth/policy/reqbody.js.map +1 -1
  138. package/dist/oauth/router.js +1 -1
  139. package/dist/oauth/router.js.map +1 -1
  140. package/dist/oauth/types.d.ts +3 -1
  141. package/dist/oauth/types.d.ts.map +1 -1
  142. package/dist/server.d.ts +1 -1
  143. package/dist/server.js +1 -1
  144. package/dist/util/clip.d.ts +7 -0
  145. package/dist/util/clip.d.ts.map +1 -0
  146. package/dist/util/clip.js +13 -0
  147. package/dist/util/clip.js.map +1 -0
  148. package/dist/util/json.d.ts +5 -0
  149. package/dist/util/json.d.ts.map +1 -1
  150. package/dist/util/json.js +21 -0
  151. package/dist/util/json.js.map +1 -1
  152. package/dist/util/own.d.ts +8 -0
  153. package/dist/util/own.d.ts.map +1 -0
  154. package/dist/util/own.js +8 -0
  155. package/dist/util/own.js.map +1 -0
  156. package/docs/ROADMAP.md +17 -229
  157. package/docs/compatibility.md +15 -3
  158. package/docs/guide.md +15 -4
  159. package/docs/reference.md +5 -3
  160. package/docs/security.md +63 -7
  161. package/docs/troubleshooting.md +4 -0
  162. package/package.json +7 -4
  163. package/dist/auth/signed-token.d.ts +0 -26
  164. package/dist/auth/signed-token.d.ts.map +0 -1
  165. package/dist/auth/signed-token.js +0 -96
  166. package/dist/auth/signed-token.js.map +0 -1
  167. package/dist/oauth/endpoints/consent-page.d.ts.map +0 -1
  168. package/dist/oauth/endpoints/consent-page.js +0 -63
  169. package/dist/oauth/endpoints/consent-page.js.map +0 -1
  170. package/dist/oauth/endpoints/consent.d.ts.map +0 -1
  171. package/dist/oauth/endpoints/consent.js.map +0 -1
  172. package/docs/diagrams/demo-tool-result.png +0 -0
  173. package/docs/diagrams/mcp-trellis-architecture.html +0 -305
@@ -1 +0,0 @@
1
- {"version":3,"file":"signed-token.d.ts","sourceRoot":"","sources":["../../src/auth/signed-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,mBAAmB,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,EAAqC,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC7D,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AA8EF,iFAAiF;AACjF,eAAO,MAAM,eAAe,GAAI,SAAS,sBAAsB,KAAG,UAiBjE,CAAC"}
@@ -1,96 +0,0 @@
1
- /**
2
- * Convenience auth: one secret seals OAuth codes (via `codeSecret`) and
3
- * signs short-lived access tokens. Domain separation is HKDF, not luck —
4
- * access-token HMAC uses `mcp-trellis:signed-access-token:v1`, distinct from
5
- * the sealed-code and client-secret-hash labels.
6
- *
7
- * ponytail: stateless tokens cannot be revoked before `exp`. No
8
- * `refreshAccessToken` / `revokeToken` — `/revoke` stays unmounted and
9
- * refresh unadvertised. Upgrade: supply those ports plus a store (see
10
- * `examples/project-desk/src/tokens.ts`).
11
- */
12
- import { bytesToBase64Url, fromBase64Url } from "../oauth/crypto/base64url.js";
13
- import { hkdfKey } from "../oauth/crypto/hkdf.js";
14
- const HKDF_INFO = "mcp-trellis:signed-access-token:v1";
15
- const HMAC_SHA256 = { name: "HMAC", hash: "SHA-256", length: 256 };
16
- const DEFAULT_TTL_SECONDS = 3600;
17
- const accessKey = (secret, usage) => hkdfKey(secret, { info: HKDF_INFO, algorithm: HMAC_SHA256, usage });
18
- const signPayload = async (secret, payload) => {
19
- const key = await accessKey(secret, "sign");
20
- const body = bytesToBase64Url(new TextEncoder().encode(JSON.stringify(payload)));
21
- const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(body));
22
- return `${body}.${bytesToBase64Url(signature)}`;
23
- };
24
- const parsePayload = (raw) => {
25
- if (raw === null || typeof raw !== "object")
26
- return null;
27
- const record = raw;
28
- if (typeof record.userId !== "string" || typeof record.audience !== "string")
29
- return null;
30
- if (typeof record.exp !== "number" || !Number.isFinite(record.exp))
31
- return null;
32
- if (record.exp < Date.now())
33
- return null;
34
- if (!Array.isArray(record.scopes) || !record.scopes.every((s) => typeof s === "string")) {
35
- return null;
36
- }
37
- return {
38
- userId: record.userId,
39
- scopes: record.scopes,
40
- audience: record.audience,
41
- exp: record.exp,
42
- };
43
- };
44
- const verifyPayload = async (secret, token) => {
45
- const parts = token.split(".");
46
- if (parts.length !== 2)
47
- return null;
48
- const [body, signature] = parts;
49
- if (!body || !signature)
50
- return null;
51
- try {
52
- const key = await accessKey(secret, "verify");
53
- const ok = await crypto.subtle.verify("HMAC", key, fromBase64Url(signature), new TextEncoder().encode(body));
54
- if (!ok)
55
- return null;
56
- return parsePayload(JSON.parse(new TextDecoder().decode(fromBase64Url(body))));
57
- }
58
- catch {
59
- return null;
60
- }
61
- };
62
- const mint = async (secret, ttlSeconds, input) => {
63
- const scopes = input.scope.split(" ").filter(Boolean);
64
- const accessToken = await signPayload(secret, {
65
- userId: input.userId,
66
- scopes,
67
- audience: input.resource,
68
- exp: Date.now() + ttlSeconds * 1000,
69
- });
70
- return { accessToken, expiresIn: ttlSeconds, scope: input.scope };
71
- };
72
- const toVerified = (payload) => ({
73
- userId: payload.userId,
74
- scopes: payload.scopes,
75
- audience: payload.audience,
76
- });
77
- /** Builds a complete `McpAppAuth` from one secret plus your session resolver. */
78
- export const signedTokenAuth = (options) => {
79
- const ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;
80
- if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {
81
- throw new Error(`signedTokenAuth: ttlSeconds must be a finite number > 0 (got ${ttlSeconds})`);
82
- }
83
- const { secret } = options;
84
- return {
85
- codeSecret: secret,
86
- resolveUser: options.resolveUser,
87
- loginUrl: options.loginUrl,
88
- mintAccessToken: (input) => mint(secret, ttlSeconds, input),
89
- verifyToken: async (token) => {
90
- const payload = await verifyPayload(secret, token);
91
- return payload ? toVerified(payload) : null;
92
- },
93
- ...(options.codeStore !== undefined ? { codeStore: options.codeStore } : {}),
94
- };
95
- };
96
- //# sourceMappingURL=signed-token.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signed-token.js","sourceRoot":"","sources":["../../src/auth/signed-token.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent-page.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/consent-page.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA+BlD,+FAA+F;AAC/F,eAAO,MAAM,oBAAoB,GAAI,OAAO,cAAc,KAAG,QAmC5D,CAAC"}
@@ -1,63 +0,0 @@
1
- /** The built-in consent interstitial, used when the host supplies no `consent.render`. */
2
- const ESCAPE_HTML = {
3
- "&": "&amp;",
4
- "<": "&lt;",
5
- ">": "&gt;",
6
- '"': "&quot;",
7
- "'": "&#39;",
8
- };
9
- const escapeHtml = (value) => value.replace(/[&<>"']/g, (ch) => ESCAPE_HTML[ch] ?? ch);
10
- /**
11
- * `form-action` governs where a form (and the redirect chain it triggers)
12
- * may end up — not just the immediate POST target. Chromium enforces it on
13
- * the 302 this page's own submission produces, so `'self'` alone blocks the
14
- * approve/deny POST to `${oauthPath}/consent` from ever reaching a
15
- * `redirectUri` on another origin (the common case — Claude, Gemini,
16
- * loopback clients). `redirectUri` is already validated by `authorize.ts`
17
- * before this renders, so its origin is safe to add here.
18
- */
19
- const consentSecurityHeaders = (redirectUri) => ({
20
- "Content-Security-Policy": `default-src 'none'; style-src 'unsafe-inline'; ` +
21
- `form-action 'self' ${new URL(redirectUri).origin}; frame-ancestors 'none'`,
22
- "X-Frame-Options": "DENY",
23
- "Referrer-Policy": "no-referrer",
24
- "Cache-Control": "no-store",
25
- });
26
- /** Built-in hardened interstitial — used whenever the host doesn't supply `consent.render`. */
27
- export const renderBuiltInConsent = (input) => {
28
- const html = `<!doctype html>
29
- <html lang="en">
30
- <head>
31
- <meta charset="utf-8">
32
- <title>Authorize access</title>
33
- <style>
34
- body { font: 16px system-ui, sans-serif; max-width: 32rem; margin: 3rem auto; padding: 0 1rem; }
35
- dl { display: grid; grid-template-columns: auto 1fr; gap: 0.25rem 1rem; }
36
- dt { font-weight: 600; }
37
- button { font-size: 1rem; padding: 0.5rem 1.25rem; margin-right: 0.5rem; }
38
- </style>
39
- </head>
40
- <body>
41
- <h1>Authorize access</h1>
42
- <p><strong>${escapeHtml(input.clientId)}</strong> is requesting access to your account.</p>
43
- <dl>
44
- <dt>Redirect URI</dt><dd>${escapeHtml(input.redirectUri)}</dd>
45
- <dt>Scope</dt><dd>${escapeHtml(input.scope.join(" ") || "(none)")}</dd>
46
- <dt>Resource</dt><dd>${escapeHtml(input.resource)}</dd>
47
- </dl>
48
- <form method="POST" action="${escapeHtml(input.oauthPath)}/consent">
49
- <input type="hidden" name="consent_ticket" value="${escapeHtml(input.ticket)}">
50
- <button type="submit" name="approved" value="true">Allow</button>
51
- <button type="submit" name="approved" value="false">Deny</button>
52
- </form>
53
- </body>
54
- </html>`;
55
- return new Response(html, {
56
- status: 200,
57
- headers: {
58
- "Content-Type": "text/html; charset=utf-8",
59
- ...consentSecurityHeaders(input.redirectUri),
60
- },
61
- });
62
- };
63
- //# sourceMappingURL=consent-page.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent-page.js","sourceRoot":"","sources":["../../../src/oauth/endpoints/consent-page.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAI1F,MAAM,WAAW,GAA2B;IAC1C,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,OAAO;CACb,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAa,EAAU,EAAE,CAC3C,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,sBAAsB,GAAG,CAAC,WAAmB,EAA0B,EAAE,CAAC,CAAC;IAC/E,yBAAyB,EACvB,iDAAiD;QACjD,sBAAsB,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,0BAA0B;IAC7E,iBAAiB,EAAE,MAAM;IACzB,iBAAiB,EAAE,aAAa;IAChC,eAAe,EAAE,UAAU;CAC5B,CAAC,CAAC;AAEH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAqB,EAAY,EAAE;IACtE,MAAM,IAAI,GAAG;;;;;;;;;;;;;;aAcF,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;;6BAEV,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;sBACpC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC;yBAC1C,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;;8BAErB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;sDACH,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;;;;;QAKtE,CAAC;IACP,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;QACxB,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACP,cAAc,EAAE,0BAA0B;YAC1C,GAAG,sBAAsB,CAAC,KAAK,CAAC,WAAW,CAAC;SAC7C;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/consent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAElB,gBAAgB,EAChB,0BAA0B,EAC3B,MAAM,aAAa,CAAC;AAMrB,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,SAAS,IAAI,CAAC,oBAAoB,EAAE,KAAK,GAAG,KAAK,CAAC,KACjD,OAAO,CAAC,MAAM,CAKkB,CAAC;AAEpC,eAAO,MAAM,aAAa,GACxB,SAAS,kBAAkB,EAC3B,OAAO,cAAc,KACpB,OAAO,CAAC,QAAQ,CAA6D,CAAC;AAEjF,4FAA4F;AAC5F,eAAO,MAAM,aAAa,GACxB,SAAS,kBAAkB,EAC3B,UAAU,MAAM,EAChB,YAAY,gBAAgB,GAAG,IAAI,KAClC,OAC0F,CAAC;AAyD9F,eAAO,MAAM,aAAa,GACxB,SAAS,OAAO,EAChB,SAAS,0BAA0B,KAClC,OAAO,CAAC,QAAQ,CAmClB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent.js","sourceRoot":"","sources":["../../../src/oauth/endpoints/consent.ts"],"names":[],"mappings":"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"}
Binary file
@@ -1,305 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>mcp-trellis · Architecture</title>
7
- <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@400;500;600;700;800&display=swap" rel="stylesheet">
8
- <style>
9
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
10
- :root {
11
- --color-paper: #f5f5fb;
12
- --color-ink: #1e1f29;
13
- --color-muted: #55566b;
14
- --color-accent: #5b5bf0;
15
- --font-sans: 'Noto Sans Hebrew', system-ui, sans-serif;
16
- --font-mono: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
17
- }
18
-
19
- body {
20
- font-family: var(--font-sans);
21
- background: var(--color-paper);
22
- color: var(--color-ink);
23
- min-height: 100vh;
24
- display: flex;
25
- align-items: center;
26
- justify-content: center;
27
- padding: 3rem 2rem;
28
- }
29
-
30
- .frame { max-width: 1280px; width: 100%; }
31
-
32
- .eyebrow {
33
- font-family: var(--font-mono);
34
- font-size: 0.66rem;
35
- font-weight: 500;
36
- letter-spacing: 0.18em;
37
- text-transform: uppercase;
38
- color: var(--color-muted);
39
- margin-bottom: 0.5rem;
40
- }
41
-
42
- h1 {
43
- font-family: var(--font-sans);
44
- font-size: clamp(1.5rem, 2.4vw + 0.75rem, 2rem);
45
- font-weight: 700;
46
- letter-spacing: -0.02em;
47
- line-height: 1.15;
48
- color: var(--color-ink);
49
- margin-bottom: 1.5rem;
50
- }
51
-
52
- svg { width: 100%; min-width: 960px; display: block; }
53
- </style>
54
- </head>
55
- <body>
56
- <div class="frame">
57
- <p class="eyebrow">Architecture · mcp-trellis</p>
58
- <h1>Host-agnostic MCP + OAuth 2.1</h1>
59
-
60
- <svg viewBox="0 0 1280 760" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="mcp-trellis-architecture-title mcp-trellis-architecture-desc">
61
- <title id="mcp-trellis-architecture-title">mcp-trellis architecture</title>
62
- <desc id="mcp-trellis-architecture-desc">Connectors reach an edge host, then createMcpApp routes OAuth and MCP traffic to library handlers and your login, token, store, and tool ports.</desc>
63
- <defs>
64
- <marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#55566b"/></marker>
65
- <marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#5b5bf0"/></marker>
66
- <marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4545c8"/></marker>
67
- </defs>
68
-
69
- <rect width="100%" height="100%" fill="#f5f5fb"/>
70
-
71
- <!-- Zones (before arrows) -->
72
- <rect x="40" y="96" width="168" height="400" rx="8"
73
- fill="rgba(30,31,41,0.02)" stroke="rgba(30,31,41,0.10)" stroke-width="0.8"/>
74
- <rect x="84" y="100" width="80" height="12" rx="2" fill="#f5f5fb"/>
75
- <text x="124" y="109" fill="rgba(30,31,41,0.40)" font-size="7" font-family="ui-monospace, monospace"
76
- text-anchor="middle" letter-spacing="0.14em">CONNECTORS</text>
77
-
78
- <rect x="440" y="56" width="480" height="520" rx="8"
79
- fill="rgba(30,31,41,0.02)" stroke="rgba(30,31,41,0.10)" stroke-width="0.8"/>
80
- <rect x="624" y="60" width="112" height="12" rx="2" fill="#f5f5fb"/>
81
- <text x="680" y="69" fill="rgba(30,31,41,0.40)" font-size="7" font-family="ui-monospace, monospace"
82
- text-anchor="middle" letter-spacing="0.14em">MCP-TRELLIS</text>
83
-
84
- <rect x="980" y="96" width="260" height="440" rx="8"
85
- fill="rgba(30,31,41,0.02)" stroke="rgba(30,31,41,0.10)" stroke-width="0.8"/>
86
- <rect x="1052" y="100" width="116" height="12" rx="2" fill="#f5f5fb"/>
87
- <text x="1110" y="109" fill="rgba(30,31,41,0.40)" font-size="7" font-family="ui-monospace, monospace"
88
- text-anchor="middle" letter-spacing="0.14em">YOUR PORTS</text>
89
-
90
- <!-- Arrows -->
91
- <!-- Clients → Edge (link) -->
92
- <line x1="192" y1="172" x2="248" y2="172" stroke="#4545c8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
93
- <line x1="192" y1="292" x2="248" y2="292" stroke="#4545c8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
94
- <line x1="192" y1="412" x2="248" y2="412" stroke="#4545c8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
95
-
96
- <!-- Edge → createMcpApp (accent primary) -->
97
- <path d="M 392,292 H 480 Q 488,292 488,284 V 120 Q 488,112 496,112 H 592"
98
- fill="none" stroke="#5b5bf0" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
99
-
100
- <!-- createMcpApp → OAuth / MCP -->
101
- <path d="M 640,144 V 168 H 558 Q 550,168 550,176 V 200"
102
- fill="none" stroke="#55566b" stroke-width="1.2" marker-end="url(#arrow)"/>
103
- <path d="M 720,144 V 168 H 802 Q 810,168 810,176 V 200"
104
- fill="none" stroke="#55566b" stroke-width="1.2" marker-end="url(#arrow)"/>
105
-
106
- <!-- OAuth → Consent / Discovery -->
107
- <line x1="550" y1="280" x2="550" y2="312" stroke="#5b5bf0" stroke-width="1.2" marker-end="url(#arrow-accent)"/>
108
- <line x1="550" y1="376" x2="550" y2="408" stroke="#55566b" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
109
-
110
- <!-- MCP → Audience → Registry -->
111
- <line x1="810" y1="280" x2="810" y2="312" stroke="#55566b" stroke-width="1.2" marker-end="url(#arrow)"/>
112
- <line x1="810" y1="376" x2="810" y2="408" stroke="#55566b" stroke-width="1.2" marker-end="url(#arrow)"/>
113
-
114
- <!-- Library → Ports (distinct Auth attach points: MINT@160, VERIFY@184) -->
115
- <path d="M 640,228 H 680 Q 688,228 688,220 V 168 Q 688,160 696,160 H 1000"
116
- fill="none" stroke="#4545c8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
117
- <path d="M 640,256 H 680 Q 688,256 688,264 V 288 Q 688,296 696,296 H 1000"
118
- fill="none" stroke="#55566b" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
119
- <path d="M 900,344 H 940 Q 948,344 948,336 V 192 Q 948,184 956,184 H 1000"
120
- fill="none" stroke="#55566b" stroke-width="1.2" marker-end="url(#arrow)"/>
121
- <line x1="900" y1="440" x2="1000" y2="440" stroke="#55566b" stroke-width="1.2" marker-end="url(#arrow)"/>
122
-
123
- <!-- Arrow labels (6–10px gap above stroke) -->
124
- <rect x="204" y="152" width="36" height="12" rx="2" fill="#f5f5fb"/>
125
- <text x="222" y="161" fill="#4545c8" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">HTTPS</text>
126
-
127
- <rect x="500" y="92" width="48" height="12" rx="2" fill="#f5f5fb"/>
128
- <text x="524" y="101" fill="#5b5bf0" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">FETCH</text>
129
-
130
- <rect x="568" y="148" width="40" height="12" rx="2" fill="#f5f5fb"/>
131
- <text x="588" y="157" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">OAUTH</text>
132
-
133
- <rect x="744" y="148" width="32" height="12" rx="2" fill="#f5f5fb"/>
134
- <text x="760" y="157" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">MCP</text>
135
-
136
- <rect x="560" y="288" width="52" height="12" rx="2" fill="#f5f5fb"/>
137
- <text x="586" y="297" fill="#5b5bf0" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">APPROVE</text>
138
-
139
- <rect x="560" y="384" width="40" height="12" rx="2" fill="#f5f5fb"/>
140
- <text x="580" y="393" fill="#8d8ea3" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">META</text>
141
-
142
- <rect x="820" y="288" width="36" height="12" rx="2" fill="#f5f5fb"/>
143
- <text x="838" y="297" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">AUD</text>
144
-
145
- <rect x="820" y="384" width="48" height="12" rx="2" fill="#f5f5fb"/>
146
- <text x="844" y="393" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">SCOPE</text>
147
-
148
- <rect x="820" y="140" width="40" height="12" rx="2" fill="#f5f5fb"/>
149
- <text x="840" y="149" fill="#4545c8" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">MINT</text>
150
-
151
- <rect x="924" y="276" width="44" height="12" rx="2" fill="#f5f5fb"/>
152
- <text x="946" y="285" fill="#8d8ea3" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">STORE</text>
153
-
154
- <rect x="880" y="164" width="48" height="12" rx="2" fill="#f5f5fb"/>
155
- <text x="904" y="173" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">VERIFY</text>
156
-
157
- <rect x="928" y="420" width="40" height="12" rx="2" fill="#f5f5fb"/>
158
- <text x="948" y="429" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.06em">CALL</text>
159
-
160
- <!-- Nodes: Connectors -->
161
- <rect x="56" y="140" width="136" height="64" rx="6" fill="#f5f5fb"/>
162
- <rect x="56" y="140" width="136" height="64" rx="6" fill="rgba(85,86,107,0.10)" stroke="#8d8ea3" stroke-width="1"/>
163
- <rect x="64" y="148" width="40" height="12" rx="2" fill="transparent" stroke="rgba(141,142,163,0.40)" stroke-width="0.8"/>
164
- <text x="84" y="157" fill="#8d8ea3" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">CLIENT</text>
165
- <text x="124" y="176" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Claude</text>
166
- <text x="124" y="192" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">DCR + PKCE</text>
167
-
168
- <rect x="56" y="260" width="136" height="64" rx="6" fill="#f5f5fb"/>
169
- <rect x="56" y="260" width="136" height="64" rx="6" fill="rgba(85,86,107,0.10)" stroke="#8d8ea3" stroke-width="1"/>
170
- <rect x="64" y="268" width="40" height="12" rx="2" fill="transparent" stroke="rgba(141,142,163,0.40)" stroke-width="0.8"/>
171
- <text x="84" y="277" fill="#8d8ea3" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">CLIENT</text>
172
- <text x="124" y="296" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Gemini</text>
173
- <text x="124" y="312" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">pre-reg secret</text>
174
-
175
- <rect x="56" y="380" width="136" height="64" rx="6" fill="#f5f5fb"/>
176
- <rect x="56" y="380" width="136" height="64" rx="6" fill="rgba(85,86,107,0.10)" stroke="#8d8ea3" stroke-width="1"/>
177
- <rect x="64" y="388" width="40" height="12" rx="2" fill="transparent" stroke="rgba(141,142,163,0.40)" stroke-width="0.8"/>
178
- <text x="84" y="397" fill="#8d8ea3" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">CLIENT</text>
179
- <text x="124" y="416" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Codex</text>
180
- <text x="124" y="432" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">OAuth 2.1 PKCE</text>
181
-
182
- <!-- Edge host -->
183
- <rect x="248" y="148" width="144" height="320" rx="6" fill="#f5f5fb"/>
184
- <rect x="248" y="148" width="144" height="320" rx="6" fill="rgba(30,31,41,0.03)" stroke="rgba(30,31,41,0.30)" stroke-width="1"/>
185
- <rect x="256" y="156" width="36" height="12" rx="2" fill="transparent" stroke="rgba(30,31,41,0.22)" stroke-width="0.8"/>
186
- <text x="274" y="165" fill="#8d8ea3" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
187
- <text x="320" y="292" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Your host</text>
188
- <text x="320" y="312" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">Workers · Next</text>
189
- <text x="320" y="328" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">Node · Deno · Bun</text>
190
- <text x="320" y="352" fill="#8d8ea3" font-size="8" font-family="ui-monospace, monospace" text-anchor="middle">Request → Response</text>
191
-
192
- <!-- createMcpApp (focal) -->
193
- <rect x="592" y="80" width="176" height="64" rx="6" fill="#f5f5fb"/>
194
- <rect x="592" y="80" width="176" height="64" rx="6" fill="#efeeff" stroke="#5b5bf0" stroke-width="1"/>
195
- <rect x="600" y="88" width="36" height="12" rx="2" fill="transparent" stroke="rgba(91,91,240,0.50)" stroke-width="0.8"/>
196
- <text x="618" y="97" fill="#5b5bf0" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">APP</text>
197
- <text x="680" y="116" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">createMcpApp</text>
198
- <text x="680" y="132" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">oauth.tryHandle → /mcp</text>
199
-
200
- <!-- OAuth AS -->
201
- <rect x="460" y="200" width="180" height="80" rx="6" fill="#f5f5fb"/>
202
- <rect x="460" y="200" width="180" height="80" rx="6" fill="#ffffff" stroke="#1e1f29" stroke-width="1"/>
203
- <rect x="468" y="208" width="28" height="12" rx="2" fill="transparent" stroke="rgba(30,31,41,0.40)" stroke-width="0.8"/>
204
- <text x="482" y="217" fill="#1e1f29" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">AS</text>
205
- <text x="550" y="240" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">OAuth router</text>
206
- <text x="550" y="256" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">/authorize · /token</text>
207
- <text x="550" y="268" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">/register · /revoke</text>
208
-
209
- <!-- Consent (security, 2nd accent) -->
210
- <rect x="460" y="312" width="180" height="64" rx="6" fill="#f5f5fb"/>
211
- <rect x="460" y="312" width="180" height="64" rx="6" fill="rgba(91,91,240,0.05)" stroke="rgba(91,91,240,0.50)" stroke-width="1" stroke-dasharray="4,4"/>
212
- <rect x="468" y="320" width="48" height="12" rx="2" fill="transparent" stroke="rgba(91,91,240,0.40)" stroke-width="0.8"/>
213
- <text x="492" y="329" fill="#5b5bf0" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">SECURE</text>
214
- <text x="550" y="348" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Consent</text>
215
- <text x="550" y="364" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">POST …/consent</text>
216
-
217
- <!-- Discovery -->
218
- <rect x="460" y="408" width="180" height="64" rx="6" fill="#f5f5fb"/>
219
- <rect x="460" y="408" width="180" height="64" rx="6" fill="rgba(30,31,41,0.02)" stroke="rgba(30,31,41,0.20)" stroke-width="1" stroke-dasharray="4,3"/>
220
- <rect x="468" y="416" width="36" height="12" rx="2" fill="transparent" stroke="rgba(30,31,41,0.25)" stroke-width="0.8"/>
221
- <text x="486" y="425" fill="#8d8ea3" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">META</text>
222
- <text x="550" y="444" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Discovery</text>
223
- <text x="550" y="460" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">.well-known/*</text>
224
-
225
- <!-- MCP Handler -->
226
- <rect x="720" y="200" width="180" height="80" rx="6" fill="#f5f5fb"/>
227
- <rect x="720" y="200" width="180" height="80" rx="6" fill="#ffffff" stroke="#1e1f29" stroke-width="1"/>
228
- <rect x="728" y="208" width="36" height="12" rx="2" fill="transparent" stroke="rgba(30,31,41,0.40)" stroke-width="0.8"/>
229
- <text x="746" y="217" fill="#1e1f29" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">MCP</text>
230
- <text x="810" y="240" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">MCP handler</text>
231
- <text x="810" y="256" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">JSON-RPC /mcp</text>
232
- <text x="810" y="268" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">initialize · tools/*</text>
233
-
234
- <!-- Audience gate (ink dashed — accent reserved for createMcpApp + Consent) -->
235
- <rect x="720" y="312" width="180" height="64" rx="6" fill="#f5f5fb"/>
236
- <rect x="720" y="312" width="180" height="64" rx="6" fill="rgba(30,31,41,0.02)" stroke="rgba(30,31,41,0.30)" stroke-width="1" stroke-dasharray="4,4"/>
237
- <rect x="728" y="320" width="36" height="12" rx="2" fill="transparent" stroke="rgba(30,31,41,0.30)" stroke-width="0.8"/>
238
- <text x="746" y="329" fill="#55566b" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">GATE</text>
239
- <text x="810" y="348" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Audience check</text>
240
- <text x="810" y="364" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">RFC 8707 aud</text>
241
-
242
- <!-- Tool registry -->
243
- <rect x="720" y="408" width="180" height="64" rx="6" fill="#f5f5fb"/>
244
- <rect x="720" y="408" width="180" height="64" rx="6" fill="rgba(30,31,41,0.05)" stroke="#55566b" stroke-width="1"/>
245
- <rect x="728" y="416" width="40" height="12" rx="2" fill="transparent" stroke="rgba(85,86,107,0.50)" stroke-width="0.8"/>
246
- <text x="748" y="425" fill="#55566b" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">REG</text>
247
- <text x="810" y="444" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Tool registry</text>
248
- <text x="810" y="460" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">scope-gated call</text>
249
-
250
- <!-- Your ports -->
251
- <rect x="1000" y="140" width="220" height="72" rx="6" fill="#f5f5fb"/>
252
- <rect x="1000" y="140" width="220" height="72" rx="6" fill="rgba(85,86,107,0.10)" stroke="#8d8ea3" stroke-width="1"/>
253
- <rect x="1008" y="148" width="40" height="12" rx="2" fill="transparent" stroke="rgba(141,142,163,0.40)" stroke-width="0.8"/>
254
- <text x="1028" y="157" fill="#8d8ea3" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">AUTH</text>
255
- <text x="1110" y="176" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Auth ports</text>
256
- <text x="1110" y="192" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">resolve · mint · verify</text>
257
-
258
- <rect x="1000" y="260" width="220" height="72" rx="6" fill="#f5f5fb"/>
259
- <rect x="1000" y="260" width="220" height="72" rx="6" fill="rgba(30,31,41,0.05)" stroke="#55566b" stroke-width="1"/>
260
- <rect x="1008" y="268" width="44" height="12" rx="2" fill="transparent" stroke="rgba(85,86,107,0.50)" stroke-width="0.8"/>
261
- <text x="1030" y="277" fill="#55566b" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
262
- <text x="1110" y="296" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Stores</text>
263
- <text x="1110" y="312" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">clientStore · codeStore</text>
264
-
265
- <rect x="1000" y="380" width="220" height="72" rx="6" fill="#f5f5fb"/>
266
- <rect x="1000" y="380" width="220" height="72" rx="6" fill="#ffffff" stroke="#1e1f29" stroke-width="1"/>
267
- <rect x="1008" y="388" width="40" height="12" rx="2" fill="transparent" stroke="rgba(30,31,41,0.40)" stroke-width="0.8"/>
268
- <text x="1028" y="397" fill="#1e1f29" font-size="7" font-family="ui-monospace, monospace" text-anchor="middle" letter-spacing="0.08em">TOOLS</text>
269
- <text x="1110" y="416" fill="#1e1f29" font-size="12" font-weight="600" font-family="'Noto Sans Hebrew', sans-serif" text-anchor="middle">Tool handlers</text>
270
- <text x="1110" y="432" fill="#55566b" font-size="9" font-family="ui-monospace, monospace" text-anchor="middle">your business logic</text>
271
-
272
- <!-- Legend -->
273
- <line x1="40" y1="640" x2="1240" y2="640" stroke="rgba(30,31,41,0.10)" stroke-width="0.8"/>
274
- <text x="40" y="660" fill="#55566b" font-size="8" font-family="ui-monospace, monospace" letter-spacing="0.14em">LEGEND</text>
275
-
276
- <rect x="40" y="676" width="14" height="10" rx="2" fill="#efeeff" stroke="#5b5bf0" stroke-width="1"/>
277
- <text x="60" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Focal router</text>
278
-
279
- <rect x="168" y="676" width="14" height="10" rx="2" fill="#ffffff" stroke="#1e1f29" stroke-width="1"/>
280
- <text x="188" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Library handler</text>
281
-
282
- <rect x="316" y="676" width="14" height="10" rx="2" fill="rgba(91,91,240,0.05)" stroke="rgba(91,91,240,0.50)" stroke-width="1" stroke-dasharray="3,2"/>
283
- <text x="336" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Security control</text>
284
-
285
- <rect x="468" y="676" width="14" height="10" rx="2" fill="rgba(30,31,41,0.05)" stroke="#55566b" stroke-width="1"/>
286
- <text x="488" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Store / registry</text>
287
-
288
- <rect x="620" y="676" width="14" height="10" rx="2" fill="rgba(30,31,41,0.03)" stroke="rgba(30,31,41,0.30)" stroke-width="1"/>
289
- <text x="640" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Edge host</text>
290
-
291
- <rect x="732" y="676" width="14" height="10" rx="2" fill="rgba(85,86,107,0.10)" stroke="#8d8ea3" stroke-width="1"/>
292
- <text x="752" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">External / port</text>
293
-
294
- <line x1="880" y1="680" x2="908" y2="680" stroke="#5b5bf0" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
295
- <text x="916" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Primary</text>
296
-
297
- <line x1="1000" y1="680" x2="1028" y2="680" stroke="#4545c8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
298
- <text x="1036" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">HTTP / mint</text>
299
-
300
- <line x1="1140" y1="680" x2="1168" y2="680" stroke="#55566b" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
301
- <text x="1176" y="684" fill="#55566b" font-size="8" font-family="'Noto Sans Hebrew', sans-serif">Optional</text>
302
- </svg>
303
- </div>
304
- </body>
305
- </html>