mcp-trellis 1.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/README.md +65 -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/auth/signed-token.d.ts +26 -0
  31. package/dist/auth/signed-token.d.ts.map +1 -0
  32. package/dist/auth/signed-token.js +96 -0
  33. package/dist/auth/signed-token.js.map +1 -0
  34. package/dist/clients.js +1 -1
  35. package/dist/clients.js.map +1 -1
  36. package/dist/deprecated.d.ts +42 -0
  37. package/dist/deprecated.d.ts.map +1 -0
  38. package/dist/deprecated.js +35 -0
  39. package/dist/deprecated.js.map +1 -0
  40. package/dist/{body.d.ts → http/body.d.ts} +27 -6
  41. package/dist/http/body.d.ts.map +1 -0
  42. package/dist/{body.js → http/body.js} +33 -13
  43. package/dist/http/body.js.map +1 -0
  44. package/dist/http/http.d.ts +42 -0
  45. package/dist/http/http.d.ts.map +1 -0
  46. package/dist/http/http.js +100 -0
  47. package/dist/http/http.js.map +1 -0
  48. package/dist/http/origins.d.ts +37 -0
  49. package/dist/http/origins.d.ts.map +1 -0
  50. package/dist/http/origins.js +87 -0
  51. package/dist/http/origins.js.map +1 -0
  52. package/dist/{dispatch.d.ts → mcp/dispatch.d.ts} +1 -1
  53. package/dist/mcp/dispatch.d.ts.map +1 -0
  54. package/dist/mcp/dispatch.js +99 -0
  55. package/dist/mcp/dispatch.js.map +1 -0
  56. package/dist/{jsonrpc.d.ts → mcp/jsonrpc.d.ts} +9 -0
  57. package/dist/mcp/jsonrpc.d.ts.map +1 -0
  58. package/dist/mcp/jsonrpc.js +88 -0
  59. package/dist/mcp/jsonrpc.js.map +1 -0
  60. package/dist/{methods.d.ts → mcp/methods.d.ts} +60 -11
  61. package/dist/mcp/methods.d.ts.map +1 -0
  62. package/dist/mcp/methods.js +84 -0
  63. package/dist/mcp/methods.js.map +1 -0
  64. package/dist/{protocol.d.ts → mcp/protocol.d.ts} +1 -3
  65. package/dist/mcp/protocol.d.ts.map +1 -0
  66. package/dist/{protocol.js → mcp/protocol.js} +1 -3
  67. package/dist/mcp/protocol.js.map +1 -0
  68. package/dist/mcp/registry.d.ts +58 -0
  69. package/dist/mcp/registry.d.ts.map +1 -0
  70. package/dist/mcp/registry.js +81 -0
  71. package/dist/mcp/registry.js.map +1 -0
  72. package/dist/mcp/rpc-handlers.d.ts +11 -0
  73. package/dist/mcp/rpc-handlers.d.ts.map +1 -0
  74. package/dist/mcp/rpc-handlers.js +133 -0
  75. package/dist/mcp/rpc-handlers.js.map +1 -0
  76. package/dist/{tools.d.ts → mcp/tools.d.ts} +20 -1
  77. package/dist/mcp/tools.d.ts.map +1 -0
  78. package/dist/mcp/tools.js +166 -0
  79. package/dist/mcp/tools.js.map +1 -0
  80. package/dist/{validate.d.ts → mcp/validate.d.ts} +18 -21
  81. package/dist/mcp/validate.d.ts.map +1 -0
  82. package/dist/{validate.js → mcp/validate.js} +59 -41
  83. package/dist/mcp/validate.js.map +1 -0
  84. package/dist/oauth/audit.d.ts +20 -0
  85. package/dist/oauth/audit.d.ts.map +1 -0
  86. package/dist/oauth/audit.js +29 -0
  87. package/dist/oauth/audit.js.map +1 -0
  88. package/dist/oauth/cimd/cimd-parse.d.ts +4 -0
  89. package/dist/oauth/cimd/cimd-parse.d.ts.map +1 -0
  90. package/dist/oauth/cimd/cimd-parse.js +70 -0
  91. package/dist/oauth/cimd/cimd-parse.js.map +1 -0
  92. package/dist/oauth/cimd/cimd-ssrf.d.ts +8 -0
  93. package/dist/oauth/cimd/cimd-ssrf.d.ts.map +1 -0
  94. package/dist/oauth/cimd/cimd-ssrf.js +193 -0
  95. package/dist/oauth/cimd/cimd-ssrf.js.map +1 -0
  96. package/dist/oauth/cimd/cimd.d.ts +36 -0
  97. package/dist/oauth/cimd/cimd.d.ts.map +1 -0
  98. package/dist/oauth/cimd/cimd.js +132 -0
  99. package/dist/oauth/cimd/cimd.js.map +1 -0
  100. package/dist/oauth/cimd/types.d.ts +12 -0
  101. package/dist/oauth/cimd/types.d.ts.map +1 -0
  102. package/dist/oauth/cimd/types.js +3 -0
  103. package/dist/oauth/cimd/types.js.map +1 -0
  104. package/dist/oauth/config.d.ts +51 -0
  105. package/dist/oauth/config.d.ts.map +1 -0
  106. package/dist/oauth/config.js +108 -0
  107. package/dist/oauth/config.js.map +1 -0
  108. package/dist/oauth/constants.d.ts +11 -0
  109. package/dist/oauth/constants.d.ts.map +1 -1
  110. package/dist/oauth/constants.js +11 -0
  111. package/dist/oauth/constants.js.map +1 -1
  112. package/dist/oauth/{base64url.d.ts → crypto/base64url.d.ts} +0 -1
  113. package/dist/oauth/crypto/base64url.d.ts.map +1 -0
  114. package/dist/oauth/{base64url.js → crypto/base64url.js} +0 -1
  115. package/dist/oauth/crypto/base64url.js.map +1 -0
  116. package/dist/oauth/crypto/clientauth.d.ts +13 -0
  117. package/dist/oauth/crypto/clientauth.d.ts.map +1 -0
  118. package/dist/oauth/crypto/clientauth.js +195 -0
  119. package/dist/oauth/crypto/clientauth.js.map +1 -0
  120. package/dist/oauth/crypto/codes.d.ts +65 -0
  121. package/dist/oauth/crypto/codes.d.ts.map +1 -0
  122. package/dist/oauth/crypto/codes.js +121 -0
  123. package/dist/oauth/crypto/codes.js.map +1 -0
  124. package/dist/oauth/crypto/hkdf.d.ts +13 -0
  125. package/dist/oauth/crypto/hkdf.d.ts.map +1 -0
  126. package/dist/oauth/crypto/hkdf.js +30 -0
  127. package/dist/oauth/crypto/hkdf.js.map +1 -0
  128. package/dist/oauth/crypto/keycache.d.ts +19 -0
  129. package/dist/oauth/crypto/keycache.d.ts.map +1 -0
  130. package/dist/oauth/crypto/keycache.js +44 -0
  131. package/dist/oauth/crypto/keycache.js.map +1 -0
  132. package/dist/oauth/crypto/pkce.d.ts.map +1 -0
  133. package/dist/oauth/{pkce.js → crypto/pkce.js} +1 -1
  134. package/dist/oauth/crypto/pkce.js.map +1 -0
  135. package/dist/oauth/{sealed.d.ts → crypto/sealed.d.ts} +12 -3
  136. package/dist/oauth/crypto/sealed.d.ts.map +1 -0
  137. package/dist/oauth/{sealed.js → crypto/sealed.js} +22 -14
  138. package/dist/oauth/crypto/sealed.js.map +1 -0
  139. package/dist/oauth/{secrethash.d.ts → crypto/secrethash.d.ts} +14 -0
  140. package/dist/oauth/crypto/secrethash.d.ts.map +1 -0
  141. package/dist/oauth/{secrethash.js → crypto/secrethash.js} +27 -11
  142. package/dist/oauth/crypto/secrethash.js.map +1 -0
  143. package/dist/oauth/deprecated.d.ts +52 -0
  144. package/dist/oauth/deprecated.d.ts.map +1 -0
  145. package/dist/oauth/deprecated.js +49 -0
  146. package/dist/oauth/deprecated.js.map +1 -0
  147. package/dist/oauth/endpoints/authorize.d.ts +3 -0
  148. package/dist/oauth/endpoints/authorize.d.ts.map +1 -0
  149. package/dist/oauth/endpoints/authorize.js +209 -0
  150. package/dist/oauth/endpoints/authorize.js.map +1 -0
  151. package/dist/oauth/endpoints/callback.d.ts +20 -0
  152. package/dist/oauth/endpoints/callback.d.ts.map +1 -0
  153. package/dist/oauth/endpoints/callback.js +31 -0
  154. package/dist/oauth/endpoints/callback.js.map +1 -0
  155. package/dist/oauth/endpoints/consent-page.d.ts +5 -0
  156. package/dist/oauth/endpoints/consent-page.d.ts.map +1 -0
  157. package/dist/oauth/endpoints/consent-page.js +63 -0
  158. package/dist/oauth/endpoints/consent-page.js.map +1 -0
  159. package/dist/oauth/endpoints/consent.d.ts +29 -0
  160. package/dist/oauth/endpoints/consent.d.ts.map +1 -0
  161. package/dist/oauth/endpoints/consent.js +98 -0
  162. package/dist/oauth/endpoints/consent.js.map +1 -0
  163. package/dist/oauth/{metadata.d.ts → endpoints/metadata.d.ts} +8 -2
  164. package/dist/oauth/endpoints/metadata.d.ts.map +1 -0
  165. package/dist/oauth/{metadata.js → endpoints/metadata.js} +10 -4
  166. package/dist/oauth/endpoints/metadata.js.map +1 -0
  167. package/dist/oauth/endpoints/register.d.ts +10 -0
  168. package/dist/oauth/endpoints/register.d.ts.map +1 -0
  169. package/dist/oauth/endpoints/register.js +96 -0
  170. package/dist/oauth/endpoints/register.js.map +1 -0
  171. package/dist/oauth/{revoke.d.ts → endpoints/revoke.d.ts} +1 -1
  172. package/dist/oauth/endpoints/revoke.d.ts.map +1 -0
  173. package/dist/oauth/{revoke.js → endpoints/revoke.js} +8 -18
  174. package/dist/oauth/endpoints/revoke.js.map +1 -0
  175. package/dist/oauth/endpoints/token.d.ts +3 -0
  176. package/dist/oauth/endpoints/token.d.ts.map +1 -0
  177. package/dist/oauth/{token.js → endpoints/token.js} +32 -25
  178. package/dist/oauth/endpoints/token.js.map +1 -0
  179. package/dist/oauth/{wellknown.d.ts → endpoints/wellknown.d.ts} +1 -1
  180. package/dist/oauth/endpoints/wellknown.d.ts.map +1 -0
  181. package/dist/oauth/{wellknown.js → endpoints/wellknown.js} +7 -9
  182. package/dist/oauth/endpoints/wellknown.js.map +1 -0
  183. package/dist/oauth/policy/redirect.d.ts.map +1 -0
  184. package/dist/oauth/policy/redirect.js.map +1 -0
  185. package/dist/oauth/policy/reqbody.d.ts +18 -0
  186. package/dist/oauth/policy/reqbody.d.ts.map +1 -0
  187. package/dist/oauth/policy/reqbody.js +68 -0
  188. package/dist/oauth/policy/reqbody.js.map +1 -0
  189. package/dist/oauth/{resource.d.ts → policy/resource.d.ts} +1 -1
  190. package/dist/oauth/policy/resource.d.ts.map +1 -0
  191. package/dist/oauth/{resource.js → policy/resource.js} +2 -2
  192. package/dist/oauth/policy/resource.js.map +1 -0
  193. package/dist/oauth/{scope.d.ts → policy/scope.d.ts} +2 -2
  194. package/dist/oauth/policy/scope.d.ts.map +1 -0
  195. package/dist/oauth/{scope.js → policy/scope.js} +3 -3
  196. package/dist/oauth/policy/scope.js.map +1 -0
  197. package/dist/oauth/router.d.ts +10 -13
  198. package/dist/oauth/router.d.ts.map +1 -1
  199. package/dist/oauth/router.js +93 -115
  200. package/dist/oauth/router.js.map +1 -1
  201. package/dist/oauth/types.d.ts +99 -45
  202. package/dist/oauth/types.d.ts.map +1 -1
  203. package/dist/oauth/types.js +1 -90
  204. package/dist/oauth/types.js.map +1 -1
  205. package/dist/server.d.ts +13 -12
  206. package/dist/server.d.ts.map +1 -1
  207. package/dist/server.js +10 -8
  208. package/dist/server.js.map +1 -1
  209. package/dist/util/defined.d.ts +11 -0
  210. package/dist/util/defined.d.ts.map +1 -0
  211. package/dist/util/defined.js +15 -0
  212. package/dist/util/defined.js.map +1 -0
  213. package/dist/util/json.d.ts +3 -0
  214. package/dist/util/json.d.ts.map +1 -0
  215. package/dist/util/json.js +3 -0
  216. package/dist/util/json.js.map +1 -0
  217. package/docs/ROADMAP.md +37 -47
  218. package/docs/compatibility.md +86 -0
  219. package/docs/diagrams/demo-tool-result.png +0 -0
  220. package/docs/diagrams/mcp-trellis-architecture.html +305 -0
  221. package/docs/guide.md +46 -16
  222. package/docs/reference.md +55 -22
  223. package/docs/security.md +58 -9
  224. package/docs/troubleshooting.md +19 -0
  225. package/package.json +27 -10
  226. package/dist/adapters/origins.d.ts +0 -19
  227. package/dist/adapters/origins.d.ts.map +0 -1
  228. package/dist/adapters/origins.js +0 -52
  229. package/dist/adapters/origins.js.map +0 -1
  230. package/dist/body.d.ts.map +0 -1
  231. package/dist/body.js.map +0 -1
  232. package/dist/dispatch.d.ts.map +0 -1
  233. package/dist/dispatch.js +0 -119
  234. package/dist/dispatch.js.map +0 -1
  235. package/dist/http.d.ts +0 -17
  236. package/dist/http.d.ts.map +0 -1
  237. package/dist/http.js +0 -38
  238. package/dist/http.js.map +0 -1
  239. package/dist/jsonrpc.d.ts.map +0 -1
  240. package/dist/jsonrpc.js +0 -18
  241. package/dist/jsonrpc.js.map +0 -1
  242. package/dist/methods.d.ts.map +0 -1
  243. package/dist/methods.js +0 -130
  244. package/dist/methods.js.map +0 -1
  245. package/dist/oauth/authorize.d.ts +0 -3
  246. package/dist/oauth/authorize.d.ts.map +0 -1
  247. package/dist/oauth/authorize.js +0 -141
  248. package/dist/oauth/authorize.js.map +0 -1
  249. package/dist/oauth/base64url.d.ts.map +0 -1
  250. package/dist/oauth/base64url.js.map +0 -1
  251. package/dist/oauth/clientauth.d.ts +0 -24
  252. package/dist/oauth/clientauth.d.ts.map +0 -1
  253. package/dist/oauth/clientauth.js +0 -119
  254. package/dist/oauth/clientauth.js.map +0 -1
  255. package/dist/oauth/codes.d.ts +0 -30
  256. package/dist/oauth/codes.d.ts.map +0 -1
  257. package/dist/oauth/codes.js +0 -85
  258. package/dist/oauth/codes.js.map +0 -1
  259. package/dist/oauth/consent.d.ts +0 -65
  260. package/dist/oauth/consent.d.ts.map +0 -1
  261. package/dist/oauth/consent.js +0 -173
  262. package/dist/oauth/consent.js.map +0 -1
  263. package/dist/oauth/metadata.d.ts.map +0 -1
  264. package/dist/oauth/metadata.js.map +0 -1
  265. package/dist/oauth/pkce.d.ts.map +0 -1
  266. package/dist/oauth/pkce.js.map +0 -1
  267. package/dist/oauth/redirect.d.ts.map +0 -1
  268. package/dist/oauth/redirect.js.map +0 -1
  269. package/dist/oauth/reqbody.d.ts +0 -10
  270. package/dist/oauth/reqbody.d.ts.map +0 -1
  271. package/dist/oauth/reqbody.js +0 -29
  272. package/dist/oauth/reqbody.js.map +0 -1
  273. package/dist/oauth/resource.d.ts.map +0 -1
  274. package/dist/oauth/resource.js.map +0 -1
  275. package/dist/oauth/revoke.d.ts.map +0 -1
  276. package/dist/oauth/revoke.js.map +0 -1
  277. package/dist/oauth/scope.d.ts.map +0 -1
  278. package/dist/oauth/scope.js.map +0 -1
  279. package/dist/oauth/sealed.d.ts.map +0 -1
  280. package/dist/oauth/sealed.js.map +0 -1
  281. package/dist/oauth/secrethash.d.ts.map +0 -1
  282. package/dist/oauth/secrethash.js.map +0 -1
  283. package/dist/oauth/token.d.ts +0 -3
  284. package/dist/oauth/token.d.ts.map +0 -1
  285. package/dist/oauth/token.js.map +0 -1
  286. package/dist/oauth/wellknown.d.ts.map +0 -1
  287. package/dist/oauth/wellknown.js.map +0 -1
  288. package/dist/protocol.d.ts.map +0 -1
  289. package/dist/protocol.js.map +0 -1
  290. package/dist/registry.d.ts +0 -37
  291. package/dist/registry.d.ts.map +0 -1
  292. package/dist/registry.js +0 -77
  293. package/dist/registry.js.map +0 -1
  294. package/dist/tools.d.ts.map +0 -1
  295. package/dist/tools.js +0 -98
  296. package/dist/tools.js.map +0 -1
  297. package/dist/validate.d.ts.map +0 -1
  298. package/dist/validate.js.map +0 -1
  299. /package/dist/oauth/{pkce.d.ts → crypto/pkce.d.ts} +0 -0
  300. /package/dist/oauth/{redirect.d.ts → policy/redirect.d.ts} +0 -0
  301. /package/dist/oauth/{redirect.js → policy/redirect.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/mcp/dispatch.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,15 @@ export declare const JSONRPC_INVALID_PARAMS = -32602;
28
28
  export declare const JSONRPC_INTERNAL_ERROR = -32603;
29
29
  export declare const JSONRPC_UNAUTHORIZED = -32001;
30
30
  export declare const JSONRPC_PAYLOAD_TOO_LARGE = -32002;
31
+ /** Authenticated but missing required scope — paired with HTTP 403. */
32
+ export declare const JSONRPC_INSUFFICIENT_SCOPE = -32003;
31
33
  export declare const rpcResult: (id: JsonRpcId, result: unknown) => JsonRpcSuccess;
32
34
  export declare const rpcError: (id: JsonRpcId, code: number, message: string) => JsonRpcFailure;
35
+ /** Batch / jsonrpc version / shape — returns a Response or a validated request. */
36
+ export declare const validateJsonRpcEnvelope: (parsed: unknown) => Response | JsonRpcRequest;
37
+ /**
38
+ * Spec requires `MCP-Protocol-Version` past `initialize`. Unknown → 400.
39
+ * Missing → assume `2025-03-26` (header BC rule; see `protocol.ts`).
40
+ */
41
+ export declare const protocolVersionHeaderError: (request: Request, jsonRpcRequest: JsonRpcRequest) => Response | null;
33
42
  //# sourceMappingURL=jsonrpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonrpc.d.ts","sourceRoot":"","sources":["../../src/mcp/jsonrpc.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,SAAS,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,SAAS,CAAC;IACd,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;AAE9D,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAC1C,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAC9C,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAC/C,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAC7C,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAC7C,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAC3C,eAAO,MAAM,yBAAyB,SAAS,CAAC;AAChD,uEAAuE;AACvE,eAAO,MAAM,0BAA0B,SAAS,CAAC;AAEjD,eAAO,MAAM,SAAS,GAAI,IAAI,SAAS,EAAE,QAAQ,OAAO,KAAG,cAIzD,CAAC;AAEH,eAAO,MAAM,QAAQ,GAAI,IAAI,SAAS,EAAE,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,cAItE,CAAC;AAwCH,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,OAAO,KAAG,QAAQ,GAAG,cAkBpE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,SAAS,OAAO,EAChB,gBAAgB,cAAc,KAC7B,QAAQ,GAAG,IAYb,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { jsonResponse } from "../http/http.js";
2
+ import { PROTOCOL_VERSIONS } from "./protocol.js";
3
+ export const JSONRPC_PARSE_ERROR = -32700;
4
+ export const JSONRPC_INVALID_REQUEST = -32600;
5
+ export const JSONRPC_METHOD_NOT_FOUND = -32601;
6
+ export const JSONRPC_INVALID_PARAMS = -32602;
7
+ export const JSONRPC_INTERNAL_ERROR = -32603;
8
+ export const JSONRPC_UNAUTHORIZED = -32001;
9
+ export const JSONRPC_PAYLOAD_TOO_LARGE = -32002;
10
+ /** Authenticated but missing required scope — paired with HTTP 403. */
11
+ export const JSONRPC_INSUFFICIENT_SCOPE = -32003;
12
+ export const rpcResult = (id, result) => ({
13
+ jsonrpc: "2.0",
14
+ id,
15
+ result,
16
+ });
17
+ export const rpcError = (id, code, message) => ({
18
+ jsonrpc: "2.0",
19
+ id,
20
+ error: { code, message },
21
+ });
22
+ const isJsonRpcId = (id) => id === null || typeof id === "string" || typeof id === "number";
23
+ /**
24
+ * RFC-shaped JSON-RPC id for an error response — omitted → `null`; valid ids
25
+ * echoed; invalid shapes → `null` so we never reflect an illegal id.
26
+ */
27
+ const errorId = (jsonRpcRequest) => {
28
+ if (jsonRpcRequest.id === undefined)
29
+ return null;
30
+ return isJsonRpcId(jsonRpcRequest.id) ? jsonRpcRequest.id : null;
31
+ };
32
+ /** Runtime JSON-RPC Request shape — types alone do not enforce this. */
33
+ const jsonRpcShapeError = (jsonRpcRequest) => {
34
+ if (jsonRpcRequest.id !== undefined && !isJsonRpcId(jsonRpcRequest.id)) {
35
+ return jsonResponse({
36
+ data: rpcError(null, JSONRPC_INVALID_REQUEST, "id must be string, number, or null"),
37
+ status: 400,
38
+ });
39
+ }
40
+ const orphanResult = jsonRpcRequest.method === undefined &&
41
+ jsonRpcRequest.id === undefined &&
42
+ "result" in jsonRpcRequest;
43
+ if (orphanResult)
44
+ return null;
45
+ if (typeof jsonRpcRequest.method !== "string" || jsonRpcRequest.method.length === 0) {
46
+ return jsonResponse({
47
+ data: rpcError(errorId(jsonRpcRequest), JSONRPC_INVALID_REQUEST, "method must be a non-empty string"),
48
+ status: 400,
49
+ });
50
+ }
51
+ return null;
52
+ };
53
+ /** Batch / jsonrpc version / shape — returns a Response or a validated request. */
54
+ export const validateJsonRpcEnvelope = (parsed) => {
55
+ if (Array.isArray(parsed)) {
56
+ return jsonResponse({
57
+ data: rpcError(null, JSONRPC_INVALID_REQUEST, "Batch requests not supported"),
58
+ status: 400,
59
+ });
60
+ }
61
+ if (!parsed || typeof parsed !== "object") {
62
+ return jsonResponse({ data: rpcError(null, JSONRPC_PARSE_ERROR, "Parse error"), status: 400 });
63
+ }
64
+ const jsonRpcRequest = parsed;
65
+ if (jsonRpcRequest.jsonrpc !== "2.0") {
66
+ return jsonResponse({
67
+ data: rpcError(errorId(jsonRpcRequest), JSONRPC_INVALID_REQUEST, 'jsonrpc must be "2.0"'),
68
+ status: 400,
69
+ });
70
+ }
71
+ return jsonRpcShapeError(jsonRpcRequest) ?? jsonRpcRequest;
72
+ };
73
+ /**
74
+ * Spec requires `MCP-Protocol-Version` past `initialize`. Unknown → 400.
75
+ * Missing → assume `2025-03-26` (header BC rule; see `protocol.ts`).
76
+ */
77
+ export const protocolVersionHeaderError = (request, jsonRpcRequest) => {
78
+ if (jsonRpcRequest.method === "initialize")
79
+ return null;
80
+ const header = request.headers.get("MCP-Protocol-Version");
81
+ if (!header || PROTOCOL_VERSIONS.has(header))
82
+ return null;
83
+ return jsonResponse({
84
+ data: rpcError(errorId(jsonRpcRequest), JSONRPC_INVALID_REQUEST, `Unsupported MCP-Protocol-Version: ${header}`),
85
+ status: 400,
86
+ });
87
+ };
88
+ //# sourceMappingURL=jsonrpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../../src/mcp/jsonrpc.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,13 @@
1
- import { type WwwAuthenticateOptions } from "./auth/bearer.js";
1
+ import { type WwwAuthenticateOptions } from "../auth/bearer.js";
2
2
  import { type JsonRpcId, type JsonRpcRequest } from "./jsonrpc.js";
3
3
  import type { ToolRegistry } from "./registry.js";
4
4
  export type Principal = {
5
5
  id: string;
6
+ /**
7
+ * Granted scopes. The literal `"*"` is a wildcard that satisfies **every**
8
+ * tool `scope` check (see `hasScope`) — reserve it for trusted internal
9
+ * principals; never mint it for an external connector.
10
+ */
6
11
  scopes: string[];
7
12
  /** Optional host claims from `verifyToken` (tenant, plan, role, …). */
8
13
  claims?: Record<string, unknown> | undefined;
@@ -19,6 +24,12 @@ export type AuditEntry = {
19
24
  };
20
25
  export type McpPorts<TCtx> = {
21
26
  authenticate: (req: Request, method: string, tool?: string) => Promise<Principal | null>;
27
+ /**
28
+ * Builds the tool context. Called only for a `tools/call` that passed the
29
+ * unknown-tool and scope checks — never for `initialize`, `ping` or
30
+ * `tools/list`. `principal` is null only when a host adds `tools/call`
31
+ * to `publicMethods`.
32
+ */
22
33
  context: (req: Request, principal: Principal | null) => TCtx | Promise<TCtx>;
23
34
  /**
24
35
  * Opt-in metrics hook. Pass any function to receive tool results and auth
@@ -51,10 +62,46 @@ export type McpHandlerOptions<TCtx> = {
51
62
  * indefinitely — "can't fail" isn't "can't delay."
52
63
  */
53
64
  auditTimeoutMs?: number;
65
+ /**
66
+ * Browser `Origin` header allowlist for MCP (DNS rebinding / CSRF).
67
+ * Distinct from Node Host `allowedOrigins` on `asNodeHandler`.
68
+ * No `Origin` → allowed (native clients). Omitted/empty → reject any
69
+ * present `Origin`. `"*"` admits any Origin.
70
+ */
71
+ allowedRequestOrigins?: string[];
72
+ /**
73
+ * Filter `tools/list` down to tools the calling principal's scopes
74
+ * actually satisfy (an unscoped tool is always listed). Default
75
+ * **false** — every tool is always listed, `tools/call` is what enforces
76
+ * scope (with a **403** `insufficient_scope`, see `insufficientScope`).
77
+ * Turning this on trades that step-up signal away: a client can no
78
+ * longer discover "this tool exists, ask for its scope" from `tools/list`
79
+ * for a scope it doesn't hold — only worth it if listing a tool at all
80
+ * would leak something (its name, description, or schema) you don't want
81
+ * a lesser-scoped principal to see.
82
+ */
83
+ hideToolsOutsideScope?: boolean;
84
+ };
85
+ /** `McpHandlerOptions` after `createMcpHandler` resolved its defaults. */
86
+ export type ResolvedMcpHandlerOptions<TCtx> = McpHandlerOptions<TCtx> & {
87
+ publicMethods: Set<string>;
88
+ };
89
+ /** `AuditEntry.error` values for requests the handler itself denied. */
90
+ export declare const DENIAL_REASONS: {
91
+ readonly unauthorized: "unauthorized";
92
+ readonly queryStringToken: "query_string_token";
93
+ readonly originNotAllowed: "origin_not_allowed";
94
+ readonly unknownTool: "unknown_tool";
95
+ readonly missingScope: "missing_scope";
54
96
  };
55
97
  export declare const DEFAULT_PUBLIC_METHODS: Set<string>;
98
+ /**
99
+ * JSON-RPC 2.0: a notification omits `id` (no response). MCP also treats
100
+ * `notifications/*` and legacy `initialized` as notifications even when an
101
+ * `id` is present. Orphan result-shaped bodies (no method/id) get 202 too.
102
+ */
56
103
  export declare const isNotification: (body: JsonRpcRequest) => boolean;
57
- export declare const resolveWww: <TCtx>(options: McpHandlerOptions<TCtx>, req: Request) => WwwAuthenticateOptions;
104
+ export declare const resolveWwwAuthenticate: <TCtx>(options: McpHandlerOptions<TCtx>, request: Request) => WwwAuthenticateOptions;
58
105
  /**
59
106
  * `id` defaults to `null` for the transport-level call sites in
60
107
  * `dispatch.ts` — a body hasn't been parsed yet there, so there's no real
@@ -62,7 +109,16 @@ export declare const resolveWww: <TCtx>(options: McpHandlerOptions<TCtx>, req: R
62
109
  * method handlers) have one and must pass it, or a client correlating
63
110
  * responses by id sees `null` on every 401 regardless of what it sent.
64
111
  */
65
- export declare const unauthorized: (www: WwwAuthenticateOptions, message?: string, id?: JsonRpcId) => Response;
112
+ export declare const unauthorized: (wwwAuthenticate: WwwAuthenticateOptions, message?: string, id?: JsonRpcId) => Response;
113
+ /**
114
+ * RFC 6750 §3.1: a request that authenticated but lacks the required scope
115
+ * gets **403**, not 401 — 401 tells the client "authenticate", which a
116
+ * scope-step-up client obeys by re-running the exact same OAuth flow,
117
+ * getting back the exact same scopes, and retrying forever. 403 with
118
+ * `error="insufficient_scope"` says what's actually wrong: re-consent with
119
+ * a broader `scope` request, not re-authenticate.
120
+ */
121
+ export declare const insufficientScope: (wwwAuthenticate: WwwAuthenticateOptions, scope: string, id?: JsonRpcId) => Response;
66
122
  /**
67
123
  * Invoke the audit metrics hook, swallowing any failure and racing it
68
124
  * against `auditTimeoutMs` so a hanging sink can't stall the response
@@ -72,13 +128,6 @@ export declare const unauthorized: (www: WwwAuthenticateOptions, message?: strin
72
128
  * an unhandled rejection whenever it does finish.
73
129
  */
74
130
  export declare const safeAudit: <TCtx>(options: McpHandlerOptions<TCtx>, entry: AuditEntry) => Promise<void>;
131
+ /** True when `scope` is unset, granted, or covered by the `"*"` wildcard scope. */
75
132
  export declare const hasScope: (principal: Principal, scope: string | undefined) => boolean;
76
- export declare const dispatchRpc: <TCtx>(input: {
77
- req: Request;
78
- body: JsonRpcRequest;
79
- options: McpHandlerOptions<TCtx>;
80
- publicMethods: Set<string>;
81
- /** Request start (captured in `createMcpHandler.fetch`), for denial-path audit timing. */
82
- startedAt: number;
83
- }) => Promise<Response>;
84
133
  //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/mcp/methods.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { wwwAuthenticateHeader } from "../auth/bearer.js";
2
+ import { DEFAULT_AUDIT_TIMEOUT_MS, jsonResponse, runAuditBounded } from "../http/http.js";
3
+ import { JSONRPC_INSUFFICIENT_SCOPE, JSONRPC_UNAUTHORIZED, rpcError, } from "./jsonrpc.js";
4
+ /** `AuditEntry.error` values for requests the handler itself denied. */
5
+ export const DENIAL_REASONS = {
6
+ unauthorized: "unauthorized",
7
+ queryStringToken: "query_string_token",
8
+ originNotAllowed: "origin_not_allowed",
9
+ unknownTool: "unknown_tool",
10
+ missingScope: "missing_scope",
11
+ };
12
+ export const DEFAULT_PUBLIC_METHODS = new Set([
13
+ "initialize",
14
+ "ping",
15
+ "notifications/initialized",
16
+ "initialized",
17
+ ]);
18
+ /**
19
+ * JSON-RPC 2.0: a notification omits `id` (no response). MCP also treats
20
+ * `notifications/*` and legacy `initialized` as notifications even when an
21
+ * `id` is present. Orphan result-shaped bodies (no method/id) get 202 too.
22
+ */
23
+ export const isNotification = (body) => {
24
+ if (body.id === undefined) {
25
+ return typeof body.method === "string" || (body.method === undefined && "result" in body);
26
+ }
27
+ return ((typeof body.method === "string" && body.method.startsWith("notifications/")) ||
28
+ body.method === "initialized");
29
+ };
30
+ export const resolveWwwAuthenticate = (options, request) => typeof options.wwwAuthenticate === "function"
31
+ ? options.wwwAuthenticate(request)
32
+ : options.wwwAuthenticate;
33
+ /**
34
+ * `id` defaults to `null` for the transport-level call sites in
35
+ * `dispatch.ts` — a body hasn't been parsed yet there, so there's no real
36
+ * id to echo. Call sites past that point (inside `dispatchRpc` and the
37
+ * method handlers) have one and must pass it, or a client correlating
38
+ * responses by id sees `null` on every 401 regardless of what it sent.
39
+ */
40
+ export const unauthorized = (wwwAuthenticate, message = "Unauthorized", id = null) => jsonResponse({
41
+ data: rpcError(id, JSONRPC_UNAUTHORIZED, message),
42
+ status: 401,
43
+ headers: { "WWW-Authenticate": wwwAuthenticateHeader(wwwAuthenticate) },
44
+ });
45
+ /**
46
+ * RFC 6750 §3.1: a request that authenticated but lacks the required scope
47
+ * gets **403**, not 401 — 401 tells the client "authenticate", which a
48
+ * scope-step-up client obeys by re-running the exact same OAuth flow,
49
+ * getting back the exact same scopes, and retrying forever. 403 with
50
+ * `error="insufficient_scope"` says what's actually wrong: re-consent with
51
+ * a broader `scope` request, not re-authenticate.
52
+ */
53
+ export const insufficientScope = (wwwAuthenticate, scope, id = null) => jsonResponse({
54
+ data: rpcError(id, JSONRPC_INSUFFICIENT_SCOPE, `Missing scope: ${scope}`),
55
+ status: 403,
56
+ headers: {
57
+ "WWW-Authenticate": wwwAuthenticateHeader({
58
+ ...wwwAuthenticate,
59
+ error: "insufficient_scope",
60
+ scope,
61
+ }),
62
+ },
63
+ });
64
+ /**
65
+ * Invoke the audit metrics hook, swallowing any failure and racing it
66
+ * against `auditTimeoutMs` so a hanging sink can't stall the response
67
+ * either — "can't fail a request" was already true; this adds "can't
68
+ * delay one" past a bound. The audit call keeps running in the background
69
+ * if the timer wins; its own `catch` below means it can never surface as
70
+ * an unhandled rejection whenever it does finish.
71
+ */
72
+ export const safeAudit = async (options, entry) => {
73
+ const audit = options.ports.audit;
74
+ if (!audit)
75
+ return;
76
+ await runAuditBounded(() => audit(entry), options.auditTimeoutMs ?? DEFAULT_AUDIT_TIMEOUT_MS);
77
+ };
78
+ /** True when `scope` is unset, granted, or covered by the `"*"` wildcard scope. */
79
+ export const hasScope = (principal, scope) => {
80
+ if (!scope)
81
+ return true;
82
+ return principal.scopes.includes(scope) || principal.scopes.includes("*");
83
+ };
84
+ //# sourceMappingURL=methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/mcp/methods.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,7 @@
1
1
  export declare const PROTOCOL_VERSIONS: Set<string>;
2
2
  /**
3
3
  * Answered on `initialize` when the client's requested version is missing
4
- * or unrecognized. The spec's guidance is to respond with a version the
5
- * server supports, preferring the latest — not the oldest one, which is
6
- * what this constant did before.
4
+ * or unrecognized: per the spec, the latest version this server supports.
7
5
  */
8
6
  export declare const DEFAULT_PROTOCOL_VERSION = "2025-06-18";
9
7
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/mcp/protocol.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,aAAsD,CAAC;AAErF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,eAAe,CAAC;AAE5D,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAMtE,CAAC"}
@@ -1,9 +1,7 @@
1
1
  export const PROTOCOL_VERSIONS = new Set(["2024-11-05", "2025-03-26", "2025-06-18"]);
2
2
  /**
3
3
  * Answered on `initialize` when the client's requested version is missing
4
- * or unrecognized. The spec's guidance is to respond with a version the
5
- * server supports, preferring the latest — not the oldest one, which is
6
- * what this constant did before.
4
+ * or unrecognized: per the spec, the latest version this server supports.
7
5
  */
8
6
  export const DEFAULT_PROTOCOL_VERSION = "2025-06-18";
9
7
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/mcp/protocol.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAErF;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,YAAY,CAAC;AAE5D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAgC,EAAU,EAAE;IAC9E,MAAM,SAAS,GAAG,MAAM,EAAE,eAAe,CAAC;IAC1C,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACtE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,wBAAwB,CAAC;AAClC,CAAC,CAAC"}
@@ -0,0 +1,58 @@
1
+ import type { JsonSchema } from "./validate.js";
2
+ export type ToolResult = {
3
+ content: Array<{
4
+ type: "text";
5
+ text: string;
6
+ }>;
7
+ isError?: boolean | undefined;
8
+ };
9
+ export type ToolHandler<TCtx> = (ctx: TCtx, args: Record<string, unknown>) => Promise<ToolResult | string> | ToolResult | string;
10
+ export type ToolDef<TCtx> = {
11
+ name: string;
12
+ description: string;
13
+ inputSchema: JsonSchema;
14
+ /**
15
+ * Required scope, or `undefined`/omitted for "any authenticated
16
+ * principal, whatever its scopes." On a `createMcpApp` server advertising
17
+ * more than one scope, an omitted `scope` is a construction-time error —
18
+ * see `assertToolScopesConfigured` — precisely because "any authenticated
19
+ * principal" silently includes a principal with zero scopes, which is
20
+ * rarely the intent on a multi-scope server. Pass `scope: null` to state
21
+ * that intentionally instead of by omission.
22
+ */
23
+ scope?: string | null | undefined;
24
+ handler: ToolHandler<TCtx>;
25
+ };
26
+ export type ToolListEntry = {
27
+ name: string;
28
+ description: string;
29
+ inputSchema: JsonSchema;
30
+ };
31
+ export type ToolRegistry<TCtx> = {
32
+ /**
33
+ * `allowScope`, when passed, is consulted per tool with that tool's
34
+ * `scope` — omit a tool by returning `false`. Lets a caller (see
35
+ * `McpHandlerOptions.hideToolsOutsideScope`) filter `tools/list` by a
36
+ * principal's granted scopes without the registry itself knowing what a
37
+ * "principal" or "scope check" is — it only ever sees the raw `scope`
38
+ * value already on each `ToolDef`.
39
+ */
40
+ list: (allowScope?: (scope: string | null | undefined) => boolean) => ToolListEntry[];
41
+ get: (name: string) => ToolDef<TCtx> | undefined;
42
+ call: (name: string, ctx: TCtx, args: Record<string, unknown>) => Promise<ToolResult>;
43
+ };
44
+ export type RegistryOptions = {
45
+ /**
46
+ * Validate tools/call args against inputSchema. Default **true** since 2.0 —
47
+ * forgetting this was a silent injection path into handlers. Set `false`
48
+ * only when you intentionally skip schema checks.
49
+ */
50
+ validateArgs?: boolean | undefined;
51
+ /**
52
+ * Map tool exceptions to client-visible text.
53
+ * Default: `"Tool execution failed"` (no exception leakage).
54
+ */
55
+ onToolError?: ((error: unknown) => string) | undefined;
56
+ };
57
+ export declare const createToolRegistry: <TCtx>(tools: ToolDef<TCtx>[], options?: RegistryOptions) => ToolRegistry<TCtx>;
58
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,IAAI,IAAI,CAC9B,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,UAAU,GAAG,MAAM,CAAC;AAExD,MAAM,MAAM,OAAO,CAAC,IAAI,IAAI;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,IAAI,IAAI;IAC/B;;;;;;;OAOG;IACH,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,OAAO,KAAK,aAAa,EAAE,CAAC;IACtF,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACvF,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;CACxD,CAAC;AA8DF,eAAO,MAAM,kBAAkB,GAAI,IAAI,EACrC,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,EACtB,UAAS,eAAoB,KAC5B,YAAY,CAAC,IAAI,CAqCnB,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { missingObjectType, unsupportedKeywords, validateAgainstSchema } from "./validate.js";
2
+ const DEFAULT_TOOL_ERROR = "Tool execution failed";
3
+ /**
4
+ * Map a tool exception to client-visible text.
5
+ * A throwing or non-string `onToolError` falls back to the redacted default —
6
+ * a mapper must never turn a tool failure into a transport failure.
7
+ */
8
+ const resolveToolError = (caught, onToolError) => {
9
+ if (!onToolError)
10
+ return DEFAULT_TOOL_ERROR;
11
+ try {
12
+ const mapped = onToolError(caught);
13
+ return typeof mapped === "string" && mapped.length > 0 ? mapped : DEFAULT_TOOL_ERROR;
14
+ }
15
+ catch {
16
+ return DEFAULT_TOOL_ERROR;
17
+ }
18
+ };
19
+ const asToolResult = (out) => {
20
+ if (typeof out === "string") {
21
+ return { content: [{ type: "text", text: out }], isError: false };
22
+ }
23
+ return out;
24
+ };
25
+ const errorResult = (message) => ({
26
+ content: [{ type: "text", text: message }],
27
+ isError: true,
28
+ });
29
+ /** Throws with every violation listed at once, rather than failing on the first tool found. */
30
+ const assertToolSchemasValid = (tools) => {
31
+ const keywordViolations = tools.flatMap((tool) => unsupportedKeywords(tool.inputSchema).map((path) => `${tool.name}: unsupported JSON Schema keyword at ${path}`));
32
+ if (keywordViolations.length > 0) {
33
+ throw new Error(`validateArgs: true but inputSchema uses unsupported keywords:\n` +
34
+ keywordViolations.join("\n") +
35
+ "\nRemove the keyword, enforce it in the handler, or set validateArgs: false");
36
+ }
37
+ // `properties`/`required` without `type: "object"` validates nothing at
38
+ // that node, and passes the keyword check above. See `missingObjectType`.
39
+ const typeViolations = tools.flatMap((tool) => missingObjectType(tool.inputSchema).map((path) => `${tool.name}: ${path} uses properties/required without type: "object"`));
40
+ if (typeViolations.length > 0) {
41
+ throw new Error(`validateArgs: true but inputSchema implies an object shape without declaring it:\n` +
42
+ typeViolations.join("\n") +
43
+ '\nAdd type: "object" (or include it in a union), or set validateArgs: false');
44
+ }
45
+ };
46
+ export const createToolRegistry = (tools, options = {}) => {
47
+ const byName = new Map(tools.map((t) => [t.name, t]));
48
+ if (byName.size !== tools.length) {
49
+ throw new Error("duplicate tool names in registry");
50
+ }
51
+ const validateArgs = options.validateArgs !== false;
52
+ if (validateArgs)
53
+ assertToolSchemasValid(tools);
54
+ return {
55
+ list: (allowScope) => tools
56
+ .filter((tool) => !allowScope || allowScope(tool.scope))
57
+ .map(({ name, description, inputSchema }) => ({
58
+ name,
59
+ description,
60
+ inputSchema,
61
+ })),
62
+ get: (name) => byName.get(name),
63
+ call: async (name, ctx, args) => {
64
+ const tool = byName.get(name);
65
+ if (!tool)
66
+ return errorResult(`Unknown tool: ${name}`);
67
+ if (validateArgs) {
68
+ const errors = validateAgainstSchema(args, tool.inputSchema);
69
+ if (errors.length > 0)
70
+ return errorResult(errors.join("; "));
71
+ }
72
+ try {
73
+ return asToolResult(await tool.handler(ctx, args));
74
+ }
75
+ catch (caught) {
76
+ return errorResult(resolveToolError(caught, options.onToolError));
77
+ }
78
+ },
79
+ };
80
+ };
81
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /** JSON-RPC method handlers and authenticated dispatch. */
2
+ import { type JsonRpcRequest } from "./jsonrpc.js";
3
+ import { type ResolvedMcpHandlerOptions } from "./methods.js";
4
+ export declare const dispatchRpc: <TCtx>(input: {
5
+ req: Request;
6
+ body: JsonRpcRequest;
7
+ options: ResolvedMcpHandlerOptions<TCtx>;
8
+ /** Request start (captured in `createMcpHandler.fetch`), for denial-path audit timing. */
9
+ startedAt: number;
10
+ }) => Promise<Response>;
11
+ //# sourceMappingURL=rpc-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/mcp/rpc-handlers.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAI3D,OAAO,EAIL,KAAK,cAAc,EAGpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAOL,KAAK,yBAAyB,EAI/B,MAAM,cAAc,CAAC;AA8ItB,eAAO,MAAM,WAAW,GAAU,IAAI,EAAE,OAAO;IAC7C,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACzC,0FAA0F;IAC1F,SAAS,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,QAAQ,CAkCnB,CAAC"}