mcp-trellis 1.0.0 → 2.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 (296) hide show
  1. package/README.md +63 -93
  2. package/dist/adapters/node-request.d.ts +53 -0
  3. package/dist/adapters/node-request.d.ts.map +1 -0
  4. package/dist/adapters/node-request.js +165 -0
  5. package/dist/adapters/node-request.js.map +1 -0
  6. package/dist/adapters/node.d.ts +13 -30
  7. package/dist/adapters/node.d.ts.map +1 -1
  8. package/dist/adapters/node.js +55 -101
  9. package/dist/adapters/node.js.map +1 -1
  10. package/dist/advanced.d.ts +18 -0
  11. package/dist/advanced.d.ts.map +1 -0
  12. package/dist/advanced.js +18 -0
  13. package/dist/advanced.js.map +1 -0
  14. package/dist/app-options.d.ts +132 -0
  15. package/dist/app-options.d.ts.map +1 -0
  16. package/dist/app-options.js +2 -0
  17. package/dist/app-options.js.map +1 -0
  18. package/dist/app.d.ts +2 -89
  19. package/dist/app.d.ts.map +1 -1
  20. package/dist/app.js +143 -63
  21. package/dist/app.js.map +1 -1
  22. package/dist/audit.d.ts +5 -5
  23. package/dist/audit.d.ts.map +1 -1
  24. package/dist/audit.js +19 -8
  25. package/dist/audit.js.map +1 -1
  26. package/dist/auth/bearer.d.ts +4 -1
  27. package/dist/auth/bearer.d.ts.map +1 -1
  28. package/dist/auth/bearer.js +19 -4
  29. package/dist/auth/bearer.js.map +1 -1
  30. package/dist/clients.js +1 -1
  31. package/dist/clients.js.map +1 -1
  32. package/dist/deprecated.d.ts +42 -0
  33. package/dist/deprecated.d.ts.map +1 -0
  34. package/dist/deprecated.js +35 -0
  35. package/dist/deprecated.js.map +1 -0
  36. package/dist/{body.d.ts → http/body.d.ts} +27 -6
  37. package/dist/http/body.d.ts.map +1 -0
  38. package/dist/{body.js → http/body.js} +33 -13
  39. package/dist/http/body.js.map +1 -0
  40. package/dist/http/http.d.ts +42 -0
  41. package/dist/http/http.d.ts.map +1 -0
  42. package/dist/http/http.js +100 -0
  43. package/dist/http/http.js.map +1 -0
  44. package/dist/http/origins.d.ts +37 -0
  45. package/dist/http/origins.d.ts.map +1 -0
  46. package/dist/http/origins.js +87 -0
  47. package/dist/http/origins.js.map +1 -0
  48. package/dist/{dispatch.d.ts → mcp/dispatch.d.ts} +1 -1
  49. package/dist/mcp/dispatch.d.ts.map +1 -0
  50. package/dist/mcp/dispatch.js +99 -0
  51. package/dist/mcp/dispatch.js.map +1 -0
  52. package/dist/{jsonrpc.d.ts → mcp/jsonrpc.d.ts} +9 -0
  53. package/dist/mcp/jsonrpc.d.ts.map +1 -0
  54. package/dist/mcp/jsonrpc.js +88 -0
  55. package/dist/mcp/jsonrpc.js.map +1 -0
  56. package/dist/{methods.d.ts → mcp/methods.d.ts} +60 -11
  57. package/dist/mcp/methods.d.ts.map +1 -0
  58. package/dist/mcp/methods.js +84 -0
  59. package/dist/mcp/methods.js.map +1 -0
  60. package/dist/{protocol.d.ts → mcp/protocol.d.ts} +1 -3
  61. package/dist/mcp/protocol.d.ts.map +1 -0
  62. package/dist/{protocol.js → mcp/protocol.js} +1 -3
  63. package/dist/mcp/protocol.js.map +1 -0
  64. package/dist/mcp/registry.d.ts +58 -0
  65. package/dist/mcp/registry.d.ts.map +1 -0
  66. package/dist/mcp/registry.js +81 -0
  67. package/dist/mcp/registry.js.map +1 -0
  68. package/dist/mcp/rpc-handlers.d.ts +11 -0
  69. package/dist/mcp/rpc-handlers.d.ts.map +1 -0
  70. package/dist/mcp/rpc-handlers.js +133 -0
  71. package/dist/mcp/rpc-handlers.js.map +1 -0
  72. package/dist/{tools.d.ts → mcp/tools.d.ts} +20 -1
  73. package/dist/mcp/tools.d.ts.map +1 -0
  74. package/dist/mcp/tools.js +166 -0
  75. package/dist/mcp/tools.js.map +1 -0
  76. package/dist/{validate.d.ts → mcp/validate.d.ts} +18 -21
  77. package/dist/mcp/validate.d.ts.map +1 -0
  78. package/dist/{validate.js → mcp/validate.js} +59 -41
  79. package/dist/mcp/validate.js.map +1 -0
  80. package/dist/oauth/audit.d.ts +20 -0
  81. package/dist/oauth/audit.d.ts.map +1 -0
  82. package/dist/oauth/audit.js +29 -0
  83. package/dist/oauth/audit.js.map +1 -0
  84. package/dist/oauth/cimd/cimd-parse.d.ts +4 -0
  85. package/dist/oauth/cimd/cimd-parse.d.ts.map +1 -0
  86. package/dist/oauth/cimd/cimd-parse.js +70 -0
  87. package/dist/oauth/cimd/cimd-parse.js.map +1 -0
  88. package/dist/oauth/cimd/cimd-ssrf.d.ts +8 -0
  89. package/dist/oauth/cimd/cimd-ssrf.d.ts.map +1 -0
  90. package/dist/oauth/cimd/cimd-ssrf.js +193 -0
  91. package/dist/oauth/cimd/cimd-ssrf.js.map +1 -0
  92. package/dist/oauth/cimd/cimd.d.ts +36 -0
  93. package/dist/oauth/cimd/cimd.d.ts.map +1 -0
  94. package/dist/oauth/cimd/cimd.js +132 -0
  95. package/dist/oauth/cimd/cimd.js.map +1 -0
  96. package/dist/oauth/cimd/types.d.ts +12 -0
  97. package/dist/oauth/cimd/types.d.ts.map +1 -0
  98. package/dist/oauth/cimd/types.js +3 -0
  99. package/dist/oauth/cimd/types.js.map +1 -0
  100. package/dist/oauth/config.d.ts +51 -0
  101. package/dist/oauth/config.d.ts.map +1 -0
  102. package/dist/oauth/config.js +108 -0
  103. package/dist/oauth/config.js.map +1 -0
  104. package/dist/oauth/constants.d.ts +11 -0
  105. package/dist/oauth/constants.d.ts.map +1 -1
  106. package/dist/oauth/constants.js +11 -0
  107. package/dist/oauth/constants.js.map +1 -1
  108. package/dist/oauth/{base64url.d.ts → crypto/base64url.d.ts} +0 -1
  109. package/dist/oauth/crypto/base64url.d.ts.map +1 -0
  110. package/dist/oauth/{base64url.js → crypto/base64url.js} +0 -1
  111. package/dist/oauth/crypto/base64url.js.map +1 -0
  112. package/dist/oauth/crypto/clientauth.d.ts +13 -0
  113. package/dist/oauth/crypto/clientauth.d.ts.map +1 -0
  114. package/dist/oauth/crypto/clientauth.js +195 -0
  115. package/dist/oauth/crypto/clientauth.js.map +1 -0
  116. package/dist/oauth/crypto/codes.d.ts +65 -0
  117. package/dist/oauth/crypto/codes.d.ts.map +1 -0
  118. package/dist/oauth/crypto/codes.js +121 -0
  119. package/dist/oauth/crypto/codes.js.map +1 -0
  120. package/dist/oauth/crypto/hkdf.d.ts +13 -0
  121. package/dist/oauth/crypto/hkdf.d.ts.map +1 -0
  122. package/dist/oauth/crypto/hkdf.js +30 -0
  123. package/dist/oauth/crypto/hkdf.js.map +1 -0
  124. package/dist/oauth/crypto/keycache.d.ts +19 -0
  125. package/dist/oauth/crypto/keycache.d.ts.map +1 -0
  126. package/dist/oauth/crypto/keycache.js +44 -0
  127. package/dist/oauth/crypto/keycache.js.map +1 -0
  128. package/dist/oauth/crypto/pkce.d.ts.map +1 -0
  129. package/dist/oauth/{pkce.js → crypto/pkce.js} +1 -1
  130. package/dist/oauth/crypto/pkce.js.map +1 -0
  131. package/dist/oauth/{sealed.d.ts → crypto/sealed.d.ts} +12 -3
  132. package/dist/oauth/crypto/sealed.d.ts.map +1 -0
  133. package/dist/oauth/{sealed.js → crypto/sealed.js} +22 -14
  134. package/dist/oauth/crypto/sealed.js.map +1 -0
  135. package/dist/oauth/{secrethash.d.ts → crypto/secrethash.d.ts} +14 -0
  136. package/dist/oauth/crypto/secrethash.d.ts.map +1 -0
  137. package/dist/oauth/{secrethash.js → crypto/secrethash.js} +27 -11
  138. package/dist/oauth/crypto/secrethash.js.map +1 -0
  139. package/dist/oauth/deprecated.d.ts +52 -0
  140. package/dist/oauth/deprecated.d.ts.map +1 -0
  141. package/dist/oauth/deprecated.js +49 -0
  142. package/dist/oauth/deprecated.js.map +1 -0
  143. package/dist/oauth/endpoints/authorize.d.ts +3 -0
  144. package/dist/oauth/endpoints/authorize.d.ts.map +1 -0
  145. package/dist/oauth/endpoints/authorize.js +209 -0
  146. package/dist/oauth/endpoints/authorize.js.map +1 -0
  147. package/dist/oauth/endpoints/callback.d.ts +20 -0
  148. package/dist/oauth/endpoints/callback.d.ts.map +1 -0
  149. package/dist/oauth/endpoints/callback.js +31 -0
  150. package/dist/oauth/endpoints/callback.js.map +1 -0
  151. package/dist/oauth/endpoints/consent-page.d.ts +5 -0
  152. package/dist/oauth/endpoints/consent-page.d.ts.map +1 -0
  153. package/dist/oauth/endpoints/consent-page.js +63 -0
  154. package/dist/oauth/endpoints/consent-page.js.map +1 -0
  155. package/dist/oauth/endpoints/consent.d.ts +29 -0
  156. package/dist/oauth/endpoints/consent.d.ts.map +1 -0
  157. package/dist/oauth/endpoints/consent.js +98 -0
  158. package/dist/oauth/endpoints/consent.js.map +1 -0
  159. package/dist/oauth/{metadata.d.ts → endpoints/metadata.d.ts} +8 -2
  160. package/dist/oauth/endpoints/metadata.d.ts.map +1 -0
  161. package/dist/oauth/{metadata.js → endpoints/metadata.js} +10 -4
  162. package/dist/oauth/endpoints/metadata.js.map +1 -0
  163. package/dist/oauth/endpoints/register.d.ts +10 -0
  164. package/dist/oauth/endpoints/register.d.ts.map +1 -0
  165. package/dist/oauth/endpoints/register.js +96 -0
  166. package/dist/oauth/endpoints/register.js.map +1 -0
  167. package/dist/oauth/{revoke.d.ts → endpoints/revoke.d.ts} +1 -1
  168. package/dist/oauth/endpoints/revoke.d.ts.map +1 -0
  169. package/dist/oauth/{revoke.js → endpoints/revoke.js} +8 -18
  170. package/dist/oauth/endpoints/revoke.js.map +1 -0
  171. package/dist/oauth/endpoints/token.d.ts +3 -0
  172. package/dist/oauth/endpoints/token.d.ts.map +1 -0
  173. package/dist/oauth/{token.js → endpoints/token.js} +32 -25
  174. package/dist/oauth/endpoints/token.js.map +1 -0
  175. package/dist/oauth/{wellknown.d.ts → endpoints/wellknown.d.ts} +1 -1
  176. package/dist/oauth/endpoints/wellknown.d.ts.map +1 -0
  177. package/dist/oauth/{wellknown.js → endpoints/wellknown.js} +7 -9
  178. package/dist/oauth/endpoints/wellknown.js.map +1 -0
  179. package/dist/oauth/policy/redirect.d.ts.map +1 -0
  180. package/dist/oauth/policy/redirect.js.map +1 -0
  181. package/dist/oauth/policy/reqbody.d.ts +18 -0
  182. package/dist/oauth/policy/reqbody.d.ts.map +1 -0
  183. package/dist/oauth/policy/reqbody.js +68 -0
  184. package/dist/oauth/policy/reqbody.js.map +1 -0
  185. package/dist/oauth/{resource.d.ts → policy/resource.d.ts} +1 -1
  186. package/dist/oauth/policy/resource.d.ts.map +1 -0
  187. package/dist/oauth/{resource.js → policy/resource.js} +2 -2
  188. package/dist/oauth/policy/resource.js.map +1 -0
  189. package/dist/oauth/{scope.d.ts → policy/scope.d.ts} +2 -2
  190. package/dist/oauth/policy/scope.d.ts.map +1 -0
  191. package/dist/oauth/{scope.js → policy/scope.js} +3 -3
  192. package/dist/oauth/policy/scope.js.map +1 -0
  193. package/dist/oauth/router.d.ts +10 -13
  194. package/dist/oauth/router.d.ts.map +1 -1
  195. package/dist/oauth/router.js +93 -115
  196. package/dist/oauth/router.js.map +1 -1
  197. package/dist/oauth/types.d.ts +99 -45
  198. package/dist/oauth/types.d.ts.map +1 -1
  199. package/dist/oauth/types.js +1 -90
  200. package/dist/oauth/types.js.map +1 -1
  201. package/dist/server.d.ts +12 -12
  202. package/dist/server.d.ts.map +1 -1
  203. package/dist/server.js +9 -8
  204. package/dist/server.js.map +1 -1
  205. package/dist/util/defined.d.ts +11 -0
  206. package/dist/util/defined.d.ts.map +1 -0
  207. package/dist/util/defined.js +15 -0
  208. package/dist/util/defined.js.map +1 -0
  209. package/dist/util/json.d.ts +3 -0
  210. package/dist/util/json.d.ts.map +1 -0
  211. package/dist/util/json.js +3 -0
  212. package/dist/util/json.js.map +1 -0
  213. package/docs/ROADMAP.md +35 -47
  214. package/docs/compatibility.md +84 -0
  215. package/docs/diagrams/mcp-trellis-architecture.html +305 -0
  216. package/docs/guide.md +37 -13
  217. package/docs/reference.md +54 -22
  218. package/docs/security.md +58 -9
  219. package/docs/troubleshooting.md +19 -0
  220. package/package.json +23 -10
  221. package/dist/adapters/origins.d.ts +0 -19
  222. package/dist/adapters/origins.d.ts.map +0 -1
  223. package/dist/adapters/origins.js +0 -52
  224. package/dist/adapters/origins.js.map +0 -1
  225. package/dist/body.d.ts.map +0 -1
  226. package/dist/body.js.map +0 -1
  227. package/dist/dispatch.d.ts.map +0 -1
  228. package/dist/dispatch.js +0 -119
  229. package/dist/dispatch.js.map +0 -1
  230. package/dist/http.d.ts +0 -17
  231. package/dist/http.d.ts.map +0 -1
  232. package/dist/http.js +0 -38
  233. package/dist/http.js.map +0 -1
  234. package/dist/jsonrpc.d.ts.map +0 -1
  235. package/dist/jsonrpc.js +0 -18
  236. package/dist/jsonrpc.js.map +0 -1
  237. package/dist/methods.d.ts.map +0 -1
  238. package/dist/methods.js +0 -130
  239. package/dist/methods.js.map +0 -1
  240. package/dist/oauth/authorize.d.ts +0 -3
  241. package/dist/oauth/authorize.d.ts.map +0 -1
  242. package/dist/oauth/authorize.js +0 -141
  243. package/dist/oauth/authorize.js.map +0 -1
  244. package/dist/oauth/base64url.d.ts.map +0 -1
  245. package/dist/oauth/base64url.js.map +0 -1
  246. package/dist/oauth/clientauth.d.ts +0 -24
  247. package/dist/oauth/clientauth.d.ts.map +0 -1
  248. package/dist/oauth/clientauth.js +0 -119
  249. package/dist/oauth/clientauth.js.map +0 -1
  250. package/dist/oauth/codes.d.ts +0 -30
  251. package/dist/oauth/codes.d.ts.map +0 -1
  252. package/dist/oauth/codes.js +0 -85
  253. package/dist/oauth/codes.js.map +0 -1
  254. package/dist/oauth/consent.d.ts +0 -65
  255. package/dist/oauth/consent.d.ts.map +0 -1
  256. package/dist/oauth/consent.js +0 -173
  257. package/dist/oauth/consent.js.map +0 -1
  258. package/dist/oauth/metadata.d.ts.map +0 -1
  259. package/dist/oauth/metadata.js.map +0 -1
  260. package/dist/oauth/pkce.d.ts.map +0 -1
  261. package/dist/oauth/pkce.js.map +0 -1
  262. package/dist/oauth/redirect.d.ts.map +0 -1
  263. package/dist/oauth/redirect.js.map +0 -1
  264. package/dist/oauth/reqbody.d.ts +0 -10
  265. package/dist/oauth/reqbody.d.ts.map +0 -1
  266. package/dist/oauth/reqbody.js +0 -29
  267. package/dist/oauth/reqbody.js.map +0 -1
  268. package/dist/oauth/resource.d.ts.map +0 -1
  269. package/dist/oauth/resource.js.map +0 -1
  270. package/dist/oauth/revoke.d.ts.map +0 -1
  271. package/dist/oauth/revoke.js.map +0 -1
  272. package/dist/oauth/scope.d.ts.map +0 -1
  273. package/dist/oauth/scope.js.map +0 -1
  274. package/dist/oauth/sealed.d.ts.map +0 -1
  275. package/dist/oauth/sealed.js.map +0 -1
  276. package/dist/oauth/secrethash.d.ts.map +0 -1
  277. package/dist/oauth/secrethash.js.map +0 -1
  278. package/dist/oauth/token.d.ts +0 -3
  279. package/dist/oauth/token.d.ts.map +0 -1
  280. package/dist/oauth/token.js.map +0 -1
  281. package/dist/oauth/wellknown.d.ts.map +0 -1
  282. package/dist/oauth/wellknown.js.map +0 -1
  283. package/dist/protocol.d.ts.map +0 -1
  284. package/dist/protocol.js.map +0 -1
  285. package/dist/registry.d.ts +0 -37
  286. package/dist/registry.d.ts.map +0 -1
  287. package/dist/registry.js +0 -77
  288. package/dist/registry.js.map +0 -1
  289. package/dist/tools.d.ts.map +0 -1
  290. package/dist/tools.js +0 -98
  291. package/dist/tools.js.map +0 -1
  292. package/dist/validate.d.ts.map +0 -1
  293. package/dist/validate.js.map +0 -1
  294. /package/dist/oauth/{pkce.d.ts → crypto/pkce.d.ts} +0 -0
  295. /package/dist/oauth/{redirect.d.ts → policy/redirect.d.ts} +0 -0
  296. /package/dist/oauth/{redirect.js → policy/redirect.js} +0 -0
@@ -1,121 +1,65 @@
1
1
  /**
2
2
  * Node HTTP `(req, res)` adapter — Express, Cloud Functions, `http.createServer`, etc.
3
3
  * Bridges duck-typed Node request/response objects to Web `Request`/`Response`.
4
+ * Request-side plumbing (origin resolution, `toWebRequest`, body reading)
5
+ * lives in `node-request.ts` and is re-exported below unchanged.
4
6
  */
5
- import { BodyTooLargeError, DEFAULT_MCP_BODY_LIMIT, DEFAULT_OAUTH_BODY_LIMIT, isNodeReadable, readBoundedNodeBody, } from "../body.js";
6
- import { INTERNAL_ERROR } from "../http.js";
7
- import { JSONRPC_PAYLOAD_TOO_LARGE, rpcError } from "../jsonrpc.js";
8
- import { isAllowedOrigin } from "./origins.js";
9
- export { isAllowedOrigin };
10
- const headerValue = (value) => Array.isArray(value) ? value[0] : value;
11
- const lastForwarded = (value) => value?.split(",").pop()?.trim();
12
- /** Derive origin from Host, or from forwarded headers when trustProxy. */
13
- export const resolveOrigin = (req, options = {}) => {
14
- const trustProxy = options.trustProxy === true;
15
- const proto = trustProxy
16
- ? lastForwarded(headerValue(req.headers["x-forwarded-proto"])) || "https"
17
- : "https";
18
- const host = trustProxy
19
- ? lastForwarded(headerValue(req.headers["x-forwarded-host"])) || headerValue(req.headers.host)
20
- : headerValue(req.headers.host);
21
- if (!host) {
22
- throw new Error("Cannot resolve origin: pass options.origin or set Host" +
23
- (trustProxy ? " / X-Forwarded-Host" : ""));
24
- }
25
- return `${proto}://${host}`;
26
- };
27
- const toBodyInit = (body) => {
28
- if (body === undefined || body === null)
29
- return undefined;
30
- if (typeof body === "string")
31
- return body;
32
- if (body instanceof Uint8Array) {
33
- return body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength);
34
- }
35
- return JSON.stringify(body);
36
- };
37
- export const toWebRequest = (req, options) => {
38
- // Never trust an absolute-form request target — rebase onto the validated origin.
39
- const target = new URL(req.url ?? "/", options.origin);
40
- const url = `${options.origin}${target.pathname}${target.search}`;
41
- const headers = new Headers(Object.entries(req.headers)
42
- .map(([key, value]) => {
43
- const resolved = headerValue(value);
44
- return resolved === undefined ? null : [key, resolved];
45
- })
46
- .filter((entry) => entry !== null));
47
- const method = (req.method ?? "GET").toUpperCase();
48
- if (method === "GET" || method === "HEAD") {
49
- return new Request(url, { method, headers });
50
- }
51
- const body = options.body !== undefined ? options.body : req.body;
52
- const bodyInit = toBodyInit(body);
53
- return new Request(url, {
54
- method,
55
- headers,
56
- ...(bodyInit !== undefined ? { body: bodyInit } : {}),
57
- });
58
- };
59
- const isAsyncIterable = (value) => typeof value?.[Symbol.asyncIterator] ===
60
- "function";
61
- const requestPath = (req) => (req.url ?? "/").split("?")[0] ?? "/";
62
- /** OAuth routes under `…/oauth/…` get the 64 KiB cap; everything else gets 1 MiB. */
63
- export const bodyLimitForPath = (path) => /\/oauth(?:\/|$)/.test(path) ? DEFAULT_OAUTH_BODY_LIMIT : DEFAULT_MCP_BODY_LIMIT;
64
- const enforcePresetBodySize = (body, maxBytes) => {
65
- if (typeof body === "string" && new TextEncoder().encode(body).byteLength > maxBytes) {
66
- throw new BodyTooLargeError(maxBytes);
67
- }
68
- if (body instanceof Uint8Array && body.byteLength > maxBytes) {
69
- throw new BodyTooLargeError(maxBytes);
70
- }
71
- };
7
+ import { BodyTooLargeError } from "../http/body.js";
8
+ import { INTERNAL_ERROR } from "../http/http.js";
9
+ import { isAllowedOrigin } from "../http/origins.js";
10
+ import { JSONRPC_PAYLOAD_TOO_LARGE, rpcError } from "../mcp/jsonrpc.js";
11
+ import { bodyLimitForPath, InvalidOriginError, isOAuthPath, readNodeBody, requestPath, resolveOrigin, toWebRequest, } from "./node-request.js";
12
+ export { isAllowedOrigin, isAllowedRequestOrigin, } from "../http/origins.js";
13
+ export { bodyLimitForPath, InvalidOriginError, readNodeBody, resolveOrigin, toWebRequest, } from "./node-request.js";
72
14
  /**
73
- * Prefer `req.body`; else drain the stream (raw `http.createServer`), capped
74
- * at `maxBytes`. Throws `BodyTooLargeError` past the cap without destroying
75
- * the socket — `asNodeHandler` writes 413 first, then destroys after flush.
15
+ * Unlike every other header, `Set-Cookie` cannot be folded into one
16
+ * comma-joined value — a cookie's own `Expires` attribute contains a comma.
17
+ * The Fetch `Headers` object accordingly keeps duplicates apart internally
18
+ * and exposes them via `getSetCookie()`, but `forEach`/`entries()` still
19
+ * yields one `"set-cookie"` pair per cookie — calling `res.setHeader` once
20
+ * per pair (as for any other header) makes each call overwrite the last,
21
+ * silently dropping every cookie but the final one.
76
22
  */
77
- export const readNodeBody = async (req, maxBytes = DEFAULT_MCP_BODY_LIMIT) => {
78
- if (req.body !== undefined && req.body !== null) {
79
- enforcePresetBodySize(req.body, maxBytes);
80
- return req.body;
81
- }
82
- const opts = { contentLength: headerValue(req.headers["content-length"]) };
83
- if (isNodeReadable(req)) {
84
- const bytes = await readBoundedNodeBody(req, maxBytes, opts);
85
- return bytes.byteLength > 0 ? bytes : undefined;
86
- }
87
- if (!isAsyncIterable(req))
88
- return undefined;
89
- const bytes = await readBoundedNodeBody(req, maxBytes, opts);
90
- return bytes.byteLength > 0 ? bytes : undefined;
91
- };
92
23
  export const sendWebResponse = async (res, response) => {
93
24
  res.statusCode = response.status;
94
25
  response.headers.forEach((value, key) => {
26
+ if (key.toLowerCase() === "set-cookie")
27
+ return;
95
28
  res.setHeader(key, value);
96
29
  });
30
+ const cookies = response.headers.getSetCookie();
31
+ if (cookies.length > 0)
32
+ res.setHeader("set-cookie", cookies);
97
33
  res.end(new Uint8Array(await response.arrayBuffer()));
98
34
  };
99
- /** Always answer — an unhandled rejection on `http.createServer` hangs the client. */
100
- const sendJsonError = (res, status, body, after) => {
101
- res.statusCode = status;
35
+ /**
36
+ * Always answer — an unhandled rejection on `http.createServer` hangs the
37
+ * client. `onFlushed` also closes the connection once the body is written.
38
+ */
39
+ const sendJsonError = (res, error, onFlushed) => {
40
+ res.statusCode = error.status;
102
41
  res.setHeader("Content-Type", "application/json");
103
- if (after)
42
+ if (onFlushed)
104
43
  res.setHeader("Connection", "close");
105
- res.end(body, after);
44
+ res.end(error.body, onFlushed);
106
45
  };
107
- const payloadTooLargeBody = (path) => /\/oauth(?:\/|$)/.test(path)
46
+ const ORIGIN_NOT_ALLOWED = { status: 400, body: JSON.stringify({ error: "origin not allowed" }) };
47
+ const payloadTooLargeBody = (path) => isOAuthPath(path)
108
48
  ? JSON.stringify({ error: "request body too large" })
109
49
  : JSON.stringify(rpcError(null, JSONRPC_PAYLOAD_TOO_LARGE, "Payload too large"));
110
- /** One-liner: Node `(req, res)` → MCP / OAuth Web handler. */
111
- export const asNodeHandler = (mcp, options) => {
50
+ /**
51
+ * Validates that `options` resolves to an origin `asNodeHandler` can trust —
52
+ * either an explicit `options.origin` already covered by `allowedOrigins`,
53
+ * or (Host-derived) an `allowedOrigins` that isn't empty. A forgettable Host
54
+ * spoof would otherwise leak straight into the AS issuer / PRM /
55
+ * WWW-Authenticate values every request produces.
56
+ */
57
+ const assertNodeHandlerOptions = (options) => {
112
58
  const hostDerived = !options?.origin;
113
59
  if (hostDerived && options?.trustProxy !== true) {
114
60
  throw new Error("asNodeHandler requires options.origin or options.trustProxy: true");
115
61
  }
116
- // Forgettable Host spoof → AS issuer / PRM / WWW-Authenticate. Require an
117
- // explicit allowlist whenever origin comes from the request.
118
- if (hostDerived && !options.allowedOrigins?.length) {
62
+ if (hostDerived && !options?.allowedOrigins?.length) {
119
63
  throw new Error('asNodeHandler with Host-derived origin requires options.allowedOrigins (use ["*"] to admit any Host)');
120
64
  }
121
65
  if (options?.origin &&
@@ -123,26 +67,36 @@ export const asNodeHandler = (mcp, options) => {
123
67
  !isAllowedOrigin(options.origin, options)) {
124
68
  throw new Error("asNodeHandler: options.origin is not in options.allowedOrigins");
125
69
  }
70
+ };
71
+ /** One-liner: Node `(req, res)` → MCP / OAuth Web handler. */
72
+ export const asNodeHandler = (mcp, options) => {
73
+ assertNodeHandlerOptions(options);
126
74
  return async (req, res) => {
127
75
  const path = requestPath(req);
128
76
  try {
129
77
  const origin = options?.origin ?? resolveOrigin(req, { trustProxy: true });
130
78
  if (!isAllowedOrigin(origin, options)) {
131
- sendJsonError(res, 400, JSON.stringify({ error: "origin not allowed" }));
79
+ sendJsonError(res, ORIGIN_NOT_ALLOWED);
132
80
  return;
133
81
  }
134
82
  const body = await readNodeBody(req, bodyLimitForPath(path));
135
83
  const request = toWebRequest(req, { origin, body });
136
84
  await sendWebResponse(res, await mcp.fetch(request));
137
85
  }
138
- catch (exc) {
139
- if (exc instanceof BodyTooLargeError) {
140
- sendJsonError(res, 413, payloadTooLargeBody(path), () => {
86
+ catch (caught) {
87
+ if (caught instanceof BodyTooLargeError) {
88
+ sendJsonError(res, { status: 413, body: payloadTooLargeBody(path) }, () => {
141
89
  req.destroy?.();
142
90
  });
143
91
  return;
144
92
  }
145
- sendJsonError(res, 500, JSON.stringify({ error: INTERNAL_ERROR }));
93
+ if (caught instanceof InvalidOriginError) {
94
+ // Bad client input (a malformed or missing Host / X-Forwarded-*),
95
+ // not a server fault — 400, not the generic 500 below.
96
+ sendJsonError(res, ORIGIN_NOT_ALLOWED);
97
+ return;
98
+ }
99
+ sendJsonError(res, { status: 500, body: JSON.stringify({ error: INTERNAL_ERROR }) });
146
100
  }
147
101
  };
148
102
  };
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `mcp-trellis/advanced` — low-level building blocks for hosts assembling
3
+ * their own MCP transport or OAuth flow. Less stable than the root and
4
+ * `mcp-trellis/oauth` entry points: these follow the internals more closely
5
+ * and may change in a minor release when the protocol work requires it.
6
+ */
7
+ export { matchesAny, timingSafeEqual } from "./auth/bearer.js";
8
+ export { corsHeaders, emptyResponse, methodNotAllowed, optionsResponse } from "./http/http.js";
9
+ export { ASSUMED_HEADER_PROTOCOL_VERSION, pickProtocolVersion } from "./mcp/protocol.js";
10
+ export { IGNORED_SCHEMA_KEYWORDS, JSON_SCHEMA_TYPES, missingObjectType, SUPPORTED_SCHEMA_KEYWORDS, unsupportedKeywords, validateAgainstSchema, } from "./mcp/validate.js";
11
+ export { advertisedScopes, defaultScopes, registeredClientsRequired, unregisteredClientsAllowed, } from "./oauth/config.js";
12
+ export { type ClientAuth, firstClientAuthError, readClientAuth, } from "./oauth/crypto/clientauth.js";
13
+ export { type AuthCodeRecord, type CodeStore, consumeAuthCode, issueAuthCode, newClientId, } from "./oauth/crypto/codes.js";
14
+ export { randomBase64Url, sha256Base64Url, verifyPkceS256 } from "./oauth/crypto/pkce.js";
15
+ export { buildErrorRedirectUrl } from "./oauth/endpoints/callback.js";
16
+ export { firstResourceError, normalizeConfiguredPath, resourceErrorInfo, } from "./oauth/policy/resource.js";
17
+ export { firstScopeError, formatScope, parseScope, requestedScopes, scopeErrorInfo, } from "./oauth/policy/scope.js";
18
+ //# sourceMappingURL=advanced.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../src/advanced.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,+BAA+B,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,UAAU,EACf,oBAAoB,EACpB,cAAc,GACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,GACf,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `mcp-trellis/advanced` — low-level building blocks for hosts assembling
3
+ * their own MCP transport or OAuth flow. Less stable than the root and
4
+ * `mcp-trellis/oauth` entry points: these follow the internals more closely
5
+ * and may change in a minor release when the protocol work requires it.
6
+ */
7
+ export { matchesAny, timingSafeEqual } from "./auth/bearer.js";
8
+ export { corsHeaders, emptyResponse, methodNotAllowed, optionsResponse } from "./http/http.js";
9
+ export { ASSUMED_HEADER_PROTOCOL_VERSION, pickProtocolVersion } from "./mcp/protocol.js";
10
+ export { IGNORED_SCHEMA_KEYWORDS, JSON_SCHEMA_TYPES, missingObjectType, SUPPORTED_SCHEMA_KEYWORDS, unsupportedKeywords, validateAgainstSchema, } from "./mcp/validate.js";
11
+ export { advertisedScopes, defaultScopes, registeredClientsRequired, unregisteredClientsAllowed, } from "./oauth/config.js";
12
+ export { firstClientAuthError, readClientAuth, } from "./oauth/crypto/clientauth.js";
13
+ export { consumeAuthCode, issueAuthCode, newClientId, } from "./oauth/crypto/codes.js";
14
+ export { randomBase64Url, sha256Base64Url, verifyPkceS256 } from "./oauth/crypto/pkce.js";
15
+ export { buildErrorRedirectUrl } from "./oauth/endpoints/callback.js";
16
+ export { firstResourceError, normalizeConfiguredPath, resourceErrorInfo, } from "./oauth/policy/resource.js";
17
+ export { firstScopeError, formatScope, parseScope, requestedScopes, scopeErrorInfo, } from "./oauth/policy/scope.js";
18
+ //# sourceMappingURL=advanced.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced.js","sourceRoot":"","sources":["../src/advanced.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,+BAA+B,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,oBAAoB,EACpB,cAAc,GACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAGL,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,GACf,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,132 @@
1
+ import type { ClientName } from "./clients.js";
2
+ import type { AuditEntry, Principal, ServerInfo } from "./mcp/methods.js";
3
+ import type { ToolDef } from "./mcp/registry.js";
4
+ import type { CimdCache } from "./oauth/cimd/types.js";
5
+ import type { CodeStore } from "./oauth/crypto/codes.js";
6
+ import type { ClientStore, ConsentOptions, MintAccessTokenInput, MintedToken, OAuthAuditEntry, OAuthUser, RefreshAccessTokenInput, RevokeTokenInput } from "./oauth/types.js";
7
+ /** One sink for both MCP tool-call and OAuth AS audit events. */
8
+ export type UnifiedAuditEntry = ({
9
+ source: "mcp";
10
+ } & AuditEntry) | ({
11
+ source: "oauth";
12
+ } & OAuthAuditEntry);
13
+ /** What your token verification returns. The library checks the audience. */
14
+ export type VerifiedToken = {
15
+ userId: string;
16
+ scopes: string[];
17
+ /** RFC 8707 audience the token was minted for. */
18
+ audience: string;
19
+ /** Optional host claims passed through to `context` via `Principal`. */
20
+ claims?: Record<string, unknown>;
21
+ };
22
+ export type McpAppAuth = {
23
+ /**
24
+ * Secret(s) that seal auth codes, consent tickets, and self-issued DCR
25
+ * client assertions, and key `ClientStore.secretHash`. Pass a string, or
26
+ * an array for key rotation — the first
27
+ * entry seals new material, every entry is tried when unsealing/verifying.
28
+ * See `OAuthPorts.codeSecret` for the full rotation contract.
29
+ */
30
+ codeSecret: string | string[] | ((req: Request) => string | string[] | Promise<string | string[]>);
31
+ /** Resolve the logged-in user, or null → redirect to `loginUrl`. */
32
+ resolveUser: (req: Request) => Promise<OAuthUser | null>;
33
+ /** Where to send unauthenticated authorize requests. */
34
+ loginUrl: (req: Request, nextPath: string) => string;
35
+ /** Mint an access token; embed `resource` as the audience. */
36
+ mintAccessToken: (input: MintAccessTokenInput) => Promise<MintedToken>;
37
+ /**
38
+ * Decode and validate a bearer token. Return its `audience` —
39
+ * `createMcpApp` rejects tokens minted for a different resource itself,
40
+ * so this check cannot be forgotten.
41
+ */
42
+ verifyToken: (token: string, req: Request) => Promise<VerifiedToken | null>;
43
+ refreshAccessToken?: (input: RefreshAccessTokenInput) => Promise<MintedToken | null>;
44
+ /** RFC 7009 — presence mounts `/revoke` and advertises it. */
45
+ revokeToken?: (input: RevokeTokenInput) => Promise<void>;
46
+ codeStore?: CodeStore;
47
+ /** Required when any configured client is pre-registered (e.g. Gemini). */
48
+ clientStore?: ClientStore;
49
+ /**
50
+ * Opt-in OAuth-side metrics hook — see the tool-call `audit` below for
51
+ * the general shape. This one sees the real reason behind a collapsed
52
+ * `invalid_client` or a rejected `codeSecret`, which the caller never
53
+ * does. Omit for silence.
54
+ */
55
+ audit?: (entry: OAuthAuditEntry) => void | Promise<void>;
56
+ };
57
+ export type McpAppOptions<TCtx> = {
58
+ serverInfo: ServerInfo;
59
+ tools: ToolDef<TCtx>[];
60
+ auth: McpAppAuth;
61
+ /** Connector clients to serve. Default: `["claude"]`. */
62
+ clients?: ClientName[];
63
+ instructions?: string;
64
+ /** MCP endpoint path. Default `"/mcp"`. */
65
+ resourcePath?: string;
66
+ /** OAuth prefix. Default `` `${resourcePath}/oauth` ``. */
67
+ oauthPath?: string;
68
+ /** Scopes this server grants. Default `["mcp"]`. */
69
+ scopes?: string[];
70
+ /** Required when `scopes` has more than one entry — see `OAuthRouterOptions.defaultScopes`. */
71
+ defaultScopes?: string[];
72
+ realm?: string;
73
+ /** Extra exact-match redirect URIs beyond the client profiles. */
74
+ extraRedirectUris?: string[];
75
+ /** Allow loopback redirects (native clients). Default true. */
76
+ allowLoopback?: boolean;
77
+ /**
78
+ * Consent policy — policy, not a credential, so it sits alongside
79
+ * `allowLoopback` rather than under `auth`. Omit for the built-in
80
+ * hardened interstitial.
81
+ */
82
+ consent?: ConsentOptions;
83
+ /**
84
+ * Require every `client_id` to come from `clientStore` or this server's
85
+ * own `/register` (sealed assertion). Default **true** since 1.0.
86
+ * Set false only to accept invented public ids (pre-CIMD).
87
+ */
88
+ requireRegisteredClients?: boolean;
89
+ /**
90
+ * Validate tools/call args against each tool's `inputSchema`. Default
91
+ * **true** since 2.0. Set false only to skip schema checks intentionally.
92
+ */
93
+ validateArgs?: boolean;
94
+ /**
95
+ * See `OAuthRouterOptions.allowInMemoryCodeStore`. Default false.
96
+ */
97
+ allowInMemoryCodeStore?: boolean;
98
+ /**
99
+ * Opt into CIMD (HTTPS URL `client_id`s). Default **false** — see
100
+ * `OAuthRouterOptions.cimd`.
101
+ */
102
+ cimd?: boolean;
103
+ /**
104
+ * CIMD document cache. Strongly recommended with `cimd: true` — see
105
+ * `OAuthRouterOptions.cimdCache`.
106
+ */
107
+ cimdCache?: CimdCache;
108
+ /** Optional DNS lookup for CIMD SSRF checks. */
109
+ cimdLookup?: (hostname: string) => Promise<string[]>;
110
+ onToolError?: (error: unknown) => string;
111
+ /**
112
+ * Per-call context for tools, built only when a `tools/call` is about to
113
+ * run (see `McpPorts.context`). Defaults to an empty object.
114
+ */
115
+ context?: (req: Request, principal: Principal | null) => TCtx | Promise<TCtx>;
116
+ /**
117
+ * Unified metrics hook for MCP and OAuth events (`source: "mcp" | "oauth"`).
118
+ * Omit for silence. `auth.audit` overrides OAuth delivery when both are set.
119
+ * See `consoleAudit` or `examples/audit-store.ts`.
120
+ */
121
+ audit?: (entry: UnifiedAuditEntry) => void | Promise<void>;
122
+ /** Max time to wait for `audit` above before responding anyway. Default 1000ms. Also applied to `auth.audit`. */
123
+ auditTimeoutMs?: number;
124
+ /**
125
+ * Browser `Origin` allowlist for `/mcp` — see `McpHandlerOptions.allowedRequestOrigins`.
126
+ * Omitted → reject any request that sends `Origin`. Native clients omit the header.
127
+ */
128
+ allowedRequestOrigins?: string[];
129
+ /** Filter `tools/list` by scope. See `McpHandlerOptions.hideToolsOutsideScope`. Default false. */
130
+ hideToolsOutsideScope?: boolean;
131
+ };
132
+ //# sourceMappingURL=app-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-options.d.ts","sourceRoot":"","sources":["../src/app-options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=app-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-options.js","sourceRoot":"","sources":["../src/app-options.ts"],"names":[],"mappings":""}
package/dist/app.d.ts CHANGED
@@ -4,95 +4,8 @@
4
4
  * This layers over `createMcpHandler` and `createOAuthRouter`, which stay
5
5
  * exported for anyone who wants to compose the pieces themselves.
6
6
  */
7
- import { type ClientName } from "./clients.js";
8
- import type { AuditEntry, Principal, ServerInfo } from "./methods.js";
9
- import type { CodeStore } from "./oauth/codes.js";
10
- import type { ConsentOptions } from "./oauth/consent.js";
11
- import type { ClientStore, MintAccessTokenInput, MintedToken, OAuthAuditEntry, OAuthUser, RefreshAccessTokenInput, RevokeTokenInput } from "./oauth/types.js";
12
- import { type ToolDef } from "./registry.js";
13
- /** What your token verification returns. The library checks the audience. */
14
- export type VerifiedToken = {
15
- userId: string;
16
- scopes: string[];
17
- /** RFC 8707 audience the token was minted for. */
18
- audience: string;
19
- /** Optional host claims passed through to `context` via `Principal`. */
20
- claims?: Record<string, unknown>;
21
- };
22
- export type McpAppAuth = {
23
- /** HMAC secret for signing auth codes. */
24
- codeSecret: string | ((req: Request) => string | Promise<string>);
25
- /** Resolve the logged-in user, or null → redirect to `loginUrl`. */
26
- resolveUser: (req: Request) => Promise<OAuthUser | null>;
27
- /** Where to send unauthenticated authorize requests. */
28
- loginUrl: (req: Request, nextPath: string) => string;
29
- /** Mint an access token; embed `resource` as the audience. */
30
- mintAccessToken: (input: MintAccessTokenInput) => Promise<MintedToken>;
31
- /**
32
- * Decode and validate a bearer token. Return its `audience` —
33
- * `createMcpApp` rejects tokens minted for a different resource itself,
34
- * so this check cannot be forgotten.
35
- */
36
- verifyToken: (token: string, req: Request) => Promise<VerifiedToken | null>;
37
- refreshAccessToken?: (input: RefreshAccessTokenInput) => Promise<MintedToken | null>;
38
- /** RFC 7009 — presence mounts `/revoke` and advertises it. */
39
- revokeToken?: (input: RevokeTokenInput) => Promise<void>;
40
- codeStore?: CodeStore;
41
- /** Required when any configured client is pre-registered (e.g. Gemini). */
42
- clientStore?: ClientStore;
43
- /**
44
- * Opt-in OAuth-side metrics hook — see the tool-call `audit` below for
45
- * the general shape. This one sees the real reason behind a collapsed
46
- * `invalid_client` or a rejected `codeSecret`, which the caller never
47
- * does. Omit for silence.
48
- */
49
- audit?: (entry: OAuthAuditEntry) => void | Promise<void>;
50
- };
51
- export type McpAppOptions<TCtx> = {
52
- serverInfo: ServerInfo;
53
- tools: ToolDef<TCtx>[];
54
- auth: McpAppAuth;
55
- /** Connector clients to serve. Default: `["claude"]`. */
56
- clients?: ClientName[];
57
- instructions?: string;
58
- /** MCP endpoint path. Default `"/mcp"`. */
59
- resourcePath?: string;
60
- /** OAuth prefix. Default `` `${resourcePath}/oauth` ``. */
61
- oauthPath?: string;
62
- /** Scopes this server grants. Default `["mcp"]`. */
63
- scopes?: string[];
64
- /** Required when `scopes` has more than one entry — see `OAuthRouterOptions.defaultScopes`. */
65
- defaultScopes?: string[];
66
- realm?: string;
67
- /** Extra exact-match redirect URIs beyond the client profiles. */
68
- extraRedirectUris?: string[];
69
- /** Allow loopback redirects (native clients). Default true. */
70
- allowLoopback?: boolean;
71
- /**
72
- * Consent policy — policy, not a credential, so it sits alongside
73
- * `allowLoopback` rather than under `auth`. Omit for the built-in
74
- * hardened interstitial.
75
- */
76
- consent?: ConsentOptions;
77
- /**
78
- * Require every `client_id` to come from `clientStore` or this server's
79
- * own `/register` (sealed assertion). Default **true** since 1.0.
80
- * Set false only to accept invented public ids (pre-CIMD).
81
- */
82
- requireRegisteredClients?: boolean;
83
- validateArgs?: boolean;
84
- onToolError?: (exc: unknown) => string;
85
- /** Per-request context for tools. Defaults to an empty object. */
86
- context?: (req: Request, principal: Principal | null) => TCtx | Promise<TCtx>;
87
- /**
88
- * Opt-in metrics hook — same as `McpPorts.audit`. Omit for silence. The
89
- * library never stores or prints these itself. See `consoleAudit` or
90
- * `examples/audit-store.ts`.
91
- */
92
- audit?: (entry: AuditEntry) => void | Promise<void>;
93
- /** Max time to wait for `audit` above before responding anyway. Default 1000ms. */
94
- auditTimeoutMs?: number;
95
- };
7
+ import type { McpAppOptions } from "./app-options.js";
8
+ export type { McpAppAuth, McpAppOptions, UnifiedAuditEntry, VerifiedToken, } from "./app-options.js";
96
9
  export type McpApp = {
97
10
  fetch: (request: Request) => Promise<Response>;
98
11
  };
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAGL,KAAK,UAAU,EAIhB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAQzD,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAEjE,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,oEAAoE;IACpE,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACzD,wDAAwD;IACxD,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACrD,8DAA8D;IAC9D,eAAe,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACvE;;;;OAIG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAC5E,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACrF,8DAA8D;IAC9D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,IAAI,IAAI;IAChC,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,yDAAyD;IACzD,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IACvC,kEAAkE;IAClE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,IAAI,EAAE,SAAS,aAAa,CAAC,IAAI,CAAC,KAAG,MAwGjE,CAAC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA0BtD,YAAY,EACV,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChD,CAAC;AAwLF,eAAO,MAAM,YAAY,GAAI,IAAI,EAAE,SAAS,aAAa,CAAC,IAAI,CAAC,KAAG,MA8CjE,CAAC"}