@mcp-i/core 0.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 (226) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +390 -0
  3. package/dist/auth/handshake.d.ts +104 -0
  4. package/dist/auth/handshake.d.ts.map +1 -0
  5. package/dist/auth/handshake.js +230 -0
  6. package/dist/auth/handshake.js.map +1 -0
  7. package/dist/auth/index.d.ts +3 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +2 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/auth/types.d.ts +31 -0
  12. package/dist/auth/types.d.ts.map +1 -0
  13. package/dist/auth/types.js +7 -0
  14. package/dist/auth/types.js.map +1 -0
  15. package/dist/delegation/audience-validator.d.ts +9 -0
  16. package/dist/delegation/audience-validator.d.ts.map +1 -0
  17. package/dist/delegation/audience-validator.js +17 -0
  18. package/dist/delegation/audience-validator.js.map +1 -0
  19. package/dist/delegation/bitstring.d.ts +37 -0
  20. package/dist/delegation/bitstring.d.ts.map +1 -0
  21. package/dist/delegation/bitstring.js +117 -0
  22. package/dist/delegation/bitstring.js.map +1 -0
  23. package/dist/delegation/cascading-revocation.d.ts +45 -0
  24. package/dist/delegation/cascading-revocation.d.ts.map +1 -0
  25. package/dist/delegation/cascading-revocation.js +148 -0
  26. package/dist/delegation/cascading-revocation.js.map +1 -0
  27. package/dist/delegation/delegation-graph.d.ts +49 -0
  28. package/dist/delegation/delegation-graph.d.ts.map +1 -0
  29. package/dist/delegation/delegation-graph.js +99 -0
  30. package/dist/delegation/delegation-graph.js.map +1 -0
  31. package/dist/delegation/did-key-resolver.d.ts +64 -0
  32. package/dist/delegation/did-key-resolver.d.ts.map +1 -0
  33. package/dist/delegation/did-key-resolver.js +154 -0
  34. package/dist/delegation/did-key-resolver.js.map +1 -0
  35. package/dist/delegation/did-web-resolver.d.ts +83 -0
  36. package/dist/delegation/did-web-resolver.d.ts.map +1 -0
  37. package/dist/delegation/did-web-resolver.js +218 -0
  38. package/dist/delegation/did-web-resolver.js.map +1 -0
  39. package/dist/delegation/index.d.ts +21 -0
  40. package/dist/delegation/index.d.ts.map +1 -0
  41. package/dist/delegation/index.js +21 -0
  42. package/dist/delegation/index.js.map +1 -0
  43. package/dist/delegation/outbound-headers.d.ts +81 -0
  44. package/dist/delegation/outbound-headers.d.ts.map +1 -0
  45. package/dist/delegation/outbound-headers.js +139 -0
  46. package/dist/delegation/outbound-headers.js.map +1 -0
  47. package/dist/delegation/outbound-proof.d.ts +43 -0
  48. package/dist/delegation/outbound-proof.d.ts.map +1 -0
  49. package/dist/delegation/outbound-proof.js +52 -0
  50. package/dist/delegation/outbound-proof.js.map +1 -0
  51. package/dist/delegation/statuslist-manager.d.ts +44 -0
  52. package/dist/delegation/statuslist-manager.d.ts.map +1 -0
  53. package/dist/delegation/statuslist-manager.js +126 -0
  54. package/dist/delegation/statuslist-manager.js.map +1 -0
  55. package/dist/delegation/storage/memory-graph-storage.d.ts +70 -0
  56. package/dist/delegation/storage/memory-graph-storage.d.ts.map +1 -0
  57. package/dist/delegation/storage/memory-graph-storage.js +145 -0
  58. package/dist/delegation/storage/memory-graph-storage.js.map +1 -0
  59. package/dist/delegation/storage/memory-statuslist-storage.d.ts +19 -0
  60. package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +1 -0
  61. package/dist/delegation/storage/memory-statuslist-storage.js +33 -0
  62. package/dist/delegation/storage/memory-statuslist-storage.js.map +1 -0
  63. package/dist/delegation/utils.d.ts +49 -0
  64. package/dist/delegation/utils.d.ts.map +1 -0
  65. package/dist/delegation/utils.js +131 -0
  66. package/dist/delegation/utils.js.map +1 -0
  67. package/dist/delegation/vc-issuer.d.ts +56 -0
  68. package/dist/delegation/vc-issuer.d.ts.map +1 -0
  69. package/dist/delegation/vc-issuer.js +80 -0
  70. package/dist/delegation/vc-issuer.js.map +1 -0
  71. package/dist/delegation/vc-verifier.d.ts +112 -0
  72. package/dist/delegation/vc-verifier.d.ts.map +1 -0
  73. package/dist/delegation/vc-verifier.js +280 -0
  74. package/dist/delegation/vc-verifier.js.map +1 -0
  75. package/dist/index.d.ts +45 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +53 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/logging/index.d.ts +2 -0
  80. package/dist/logging/index.d.ts.map +1 -0
  81. package/dist/logging/index.js +2 -0
  82. package/dist/logging/index.js.map +1 -0
  83. package/dist/logging/logger.d.ts +23 -0
  84. package/dist/logging/logger.d.ts.map +1 -0
  85. package/dist/logging/logger.js +82 -0
  86. package/dist/logging/logger.js.map +1 -0
  87. package/dist/middleware/index.d.ts +7 -0
  88. package/dist/middleware/index.d.ts.map +1 -0
  89. package/dist/middleware/index.js +7 -0
  90. package/dist/middleware/index.js.map +1 -0
  91. package/dist/middleware/with-mcpi.d.ts +152 -0
  92. package/dist/middleware/with-mcpi.d.ts.map +1 -0
  93. package/dist/middleware/with-mcpi.js +472 -0
  94. package/dist/middleware/with-mcpi.js.map +1 -0
  95. package/dist/proof/errors.d.ts +49 -0
  96. package/dist/proof/errors.d.ts.map +1 -0
  97. package/dist/proof/errors.js +61 -0
  98. package/dist/proof/errors.js.map +1 -0
  99. package/dist/proof/generator.d.ts +65 -0
  100. package/dist/proof/generator.d.ts.map +1 -0
  101. package/dist/proof/generator.js +163 -0
  102. package/dist/proof/generator.js.map +1 -0
  103. package/dist/proof/index.d.ts +4 -0
  104. package/dist/proof/index.d.ts.map +1 -0
  105. package/dist/proof/index.js +4 -0
  106. package/dist/proof/index.js.map +1 -0
  107. package/dist/proof/verifier.d.ts +108 -0
  108. package/dist/proof/verifier.d.ts.map +1 -0
  109. package/dist/proof/verifier.js +299 -0
  110. package/dist/proof/verifier.js.map +1 -0
  111. package/dist/providers/base.d.ts +64 -0
  112. package/dist/providers/base.d.ts.map +1 -0
  113. package/dist/providers/base.js +19 -0
  114. package/dist/providers/base.js.map +1 -0
  115. package/dist/providers/index.d.ts +3 -0
  116. package/dist/providers/index.d.ts.map +1 -0
  117. package/dist/providers/index.js +3 -0
  118. package/dist/providers/index.js.map +1 -0
  119. package/dist/providers/memory.d.ts +33 -0
  120. package/dist/providers/memory.d.ts.map +1 -0
  121. package/dist/providers/memory.js +102 -0
  122. package/dist/providers/memory.js.map +1 -0
  123. package/dist/session/index.d.ts +2 -0
  124. package/dist/session/index.d.ts.map +1 -0
  125. package/dist/session/index.js +2 -0
  126. package/dist/session/index.js.map +1 -0
  127. package/dist/session/manager.d.ts +77 -0
  128. package/dist/session/manager.d.ts.map +1 -0
  129. package/dist/session/manager.js +251 -0
  130. package/dist/session/manager.js.map +1 -0
  131. package/dist/types/protocol.d.ts +320 -0
  132. package/dist/types/protocol.d.ts.map +1 -0
  133. package/dist/types/protocol.js +229 -0
  134. package/dist/types/protocol.js.map +1 -0
  135. package/dist/utils/base58.d.ts +31 -0
  136. package/dist/utils/base58.d.ts.map +1 -0
  137. package/dist/utils/base58.js +104 -0
  138. package/dist/utils/base58.js.map +1 -0
  139. package/dist/utils/base64.d.ts +13 -0
  140. package/dist/utils/base64.d.ts.map +1 -0
  141. package/dist/utils/base64.js +99 -0
  142. package/dist/utils/base64.js.map +1 -0
  143. package/dist/utils/crypto-service.d.ts +37 -0
  144. package/dist/utils/crypto-service.d.ts.map +1 -0
  145. package/dist/utils/crypto-service.js +153 -0
  146. package/dist/utils/crypto-service.js.map +1 -0
  147. package/dist/utils/did-helpers.d.ts +156 -0
  148. package/dist/utils/did-helpers.d.ts.map +1 -0
  149. package/dist/utils/did-helpers.js +193 -0
  150. package/dist/utils/did-helpers.js.map +1 -0
  151. package/dist/utils/ed25519-constants.d.ts +18 -0
  152. package/dist/utils/ed25519-constants.d.ts.map +1 -0
  153. package/dist/utils/ed25519-constants.js +21 -0
  154. package/dist/utils/ed25519-constants.js.map +1 -0
  155. package/dist/utils/index.d.ts +5 -0
  156. package/dist/utils/index.d.ts.map +1 -0
  157. package/dist/utils/index.js +5 -0
  158. package/dist/utils/index.js.map +1 -0
  159. package/package.json +105 -0
  160. package/src/__tests__/integration/full-flow.test.ts +362 -0
  161. package/src/__tests__/providers/base.test.ts +173 -0
  162. package/src/__tests__/providers/memory.test.ts +332 -0
  163. package/src/__tests__/utils/mock-providers.ts +319 -0
  164. package/src/__tests__/utils/node-crypto-provider.ts +93 -0
  165. package/src/auth/handshake.ts +411 -0
  166. package/src/auth/index.ts +11 -0
  167. package/src/auth/types.ts +40 -0
  168. package/src/delegation/__tests__/audience-validator.test.ts +110 -0
  169. package/src/delegation/__tests__/bitstring.test.ts +346 -0
  170. package/src/delegation/__tests__/cascading-revocation.test.ts +624 -0
  171. package/src/delegation/__tests__/delegation-graph.test.ts +623 -0
  172. package/src/delegation/__tests__/did-key-resolver.test.ts +265 -0
  173. package/src/delegation/__tests__/did-web-resolver.test.ts +467 -0
  174. package/src/delegation/__tests__/outbound-headers.test.ts +230 -0
  175. package/src/delegation/__tests__/outbound-proof.test.ts +179 -0
  176. package/src/delegation/__tests__/statuslist-manager.test.ts +515 -0
  177. package/src/delegation/__tests__/utils.test.ts +185 -0
  178. package/src/delegation/__tests__/vc-issuer.test.ts +487 -0
  179. package/src/delegation/__tests__/vc-verifier.test.ts +1029 -0
  180. package/src/delegation/audience-validator.ts +24 -0
  181. package/src/delegation/bitstring.ts +160 -0
  182. package/src/delegation/cascading-revocation.ts +224 -0
  183. package/src/delegation/delegation-graph.ts +143 -0
  184. package/src/delegation/did-key-resolver.ts +181 -0
  185. package/src/delegation/did-web-resolver.ts +270 -0
  186. package/src/delegation/index.ts +33 -0
  187. package/src/delegation/outbound-headers.ts +193 -0
  188. package/src/delegation/outbound-proof.ts +90 -0
  189. package/src/delegation/statuslist-manager.ts +219 -0
  190. package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
  191. package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
  192. package/src/delegation/storage/memory-graph-storage.ts +178 -0
  193. package/src/delegation/storage/memory-statuslist-storage.ts +42 -0
  194. package/src/delegation/utils.ts +189 -0
  195. package/src/delegation/vc-issuer.ts +137 -0
  196. package/src/delegation/vc-verifier.ts +440 -0
  197. package/src/index.ts +264 -0
  198. package/src/logging/__tests__/logger.test.ts +366 -0
  199. package/src/logging/index.ts +6 -0
  200. package/src/logging/logger.ts +91 -0
  201. package/src/middleware/__tests__/with-mcpi.test.ts +504 -0
  202. package/src/middleware/index.ts +16 -0
  203. package/src/middleware/with-mcpi.ts +766 -0
  204. package/src/proof/__tests__/proof-generator.test.ts +483 -0
  205. package/src/proof/__tests__/verifier.test.ts +488 -0
  206. package/src/proof/errors.ts +75 -0
  207. package/src/proof/generator.ts +255 -0
  208. package/src/proof/index.ts +22 -0
  209. package/src/proof/verifier.ts +449 -0
  210. package/src/providers/base.ts +68 -0
  211. package/src/providers/index.ts +15 -0
  212. package/src/providers/memory.ts +130 -0
  213. package/src/session/__tests__/session-manager.test.ts +342 -0
  214. package/src/session/index.ts +7 -0
  215. package/src/session/manager.ts +332 -0
  216. package/src/types/protocol.ts +596 -0
  217. package/src/utils/__tests__/base58.test.ts +281 -0
  218. package/src/utils/__tests__/base64.test.ts +239 -0
  219. package/src/utils/__tests__/crypto-service.test.ts +530 -0
  220. package/src/utils/__tests__/did-helpers.test.ts +156 -0
  221. package/src/utils/base58.ts +115 -0
  222. package/src/utils/base64.ts +116 -0
  223. package/src/utils/crypto-service.ts +209 -0
  224. package/src/utils/did-helpers.ts +210 -0
  225. package/src/utils/ed25519-constants.ts +23 -0
  226. package/src/utils/index.ts +9 -0
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @mcp-i/core — MCP-I Protocol Reference Implementation
3
+ *
4
+ * Delegation, proof, and session for Model Context Protocol Identity.
5
+ * This package is a DIF TAAWG protocol reference implementation.
6
+ *
7
+ * Related Spec: https://modelcontextprotocol-identity.io
8
+ *
9
+ * ## Error handling strategy
10
+ *
11
+ * - **Validation functions** (`verify*`, `validate*`) return result objects `{ valid, reason }` — never throw
12
+ * - **Construction/setup functions** throw `Error` on invalid configuration
13
+ * - **Resolution functions** (`resolve*`, `fetch*`) return `null` on failure — never throw
14
+ *
15
+ * This ensures callers can always handle failures without try/catch on validation paths.
16
+ */
17
+ export { wrapDelegationAsVC, extractDelegationFromVC, isDelegationCredentialExpired, isDelegationCredentialNotYetValid, validateDelegationCredential, validateDetachedProof, createNeedsAuthorizationError, isNeedsAuthorizationError, DELEGATION_CREDENTIAL_CONTEXT, DEFAULT_SESSION_TTL_MINUTES, DEFAULT_TIMESTAMP_SKEW_SECONDS, NONCE_LENGTH_BYTES, } from './types/protocol.js';
18
+ // Delegation module
19
+ export { DelegationCredentialIssuer, createDelegationIssuer, } from './delegation/vc-issuer.js';
20
+ export { DelegationCredentialVerifier, createDelegationVerifier, } from './delegation/vc-verifier.js';
21
+ export { DelegationGraphManager, createDelegationGraph, } from './delegation/delegation-graph.js';
22
+ export { StatusList2021Manager, createStatusListManager, } from './delegation/statuslist-manager.js';
23
+ export { CascadingRevocationManager, createCascadingRevocationManager, } from './delegation/cascading-revocation.js';
24
+ export { BitstringManager, isIndexSet, } from './delegation/bitstring.js';
25
+ export { verifyDelegationAudience, } from './delegation/audience-validator.js';
26
+ export { buildDelegationProofJWT, buildChainString, } from './delegation/outbound-proof.js';
27
+ export { buildOutboundDelegationHeaders, OUTBOUND_HEADER_NAMES, } from './delegation/outbound-headers.js';
28
+ export { canonicalizeJSON, createUnsignedVCJWT, completeVCJWT, parseVCJWT, } from './delegation/utils.js';
29
+ export { MemoryStatusListStorage } from './delegation/storage/memory-statuslist-storage.js';
30
+ export { MemoryDelegationGraphStorage } from './delegation/storage/memory-graph-storage.js';
31
+ export { createDidKeyResolver, resolveDidKeySync, isEd25519DidKey, extractPublicKeyFromDidKey, publicKeyToJwk, } from './delegation/did-key-resolver.js';
32
+ export { DidWebResolver, createDidWebResolver, isDidWeb, parseDidWeb, didWebToUrl, } from './delegation/did-web-resolver.js';
33
+ // Utils
34
+ export { base58Encode, base58Decode, isValidBase58, } from './utils/base58.js';
35
+ export { isValidDid, getDidMethod, normalizeDid, compareDids, getServerDid, extractAgentId, extractAgentSlug, generateDidKeyFromBytes, generateDidKeyFromBase64, } from './utils/did-helpers.js';
36
+ // Auth module
37
+ export { verifyOrHints, hasSensitiveScopes, MemoryResumeTokenStore, } from './auth/index.js';
38
+ // Proof module
39
+ export { ProofGenerator, createProofResponse, extractCanonicalData, } from './proof/index.js';
40
+ export { ProofVerifier, } from './proof/verifier.js';
41
+ export { ProofVerificationError, PROOF_VERIFICATION_ERROR_CODES, createProofVerificationError, } from './proof/errors.js';
42
+ // Session module
43
+ export { SessionManager, createHandshakeRequest, validateHandshakeFormat, } from './session/index.js';
44
+ // Providers
45
+ export { CryptoProvider, ClockProvider, FetchProvider, StorageProvider, NonceCacheProvider, IdentityProvider, } from './providers/base.js';
46
+ export { MemoryStorageProvider, MemoryNonceCacheProvider, MemoryIdentityProvider, } from './providers/memory.js';
47
+ // Middleware
48
+ export { createMCPIMiddleware, } from './middleware/index.js';
49
+ // Logging
50
+ export { logger, createDefaultConsoleLogger, } from './logging/index.js';
51
+ // Ed25519 Constants
52
+ export { ED25519_PKCS8_DER_HEADER, ED25519_SPKI_DER_HEADER_LENGTH, ED25519_KEY_SIZE, } from './utils/index.js';
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { logger, createDefaultConsoleLogger, type Logger, type Level, } from './logger.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,0BAA0B,EAC1B,KAAK,MAAM,EACX,KAAK,KAAK,GACX,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { logger, createDefaultConsoleLogger, } from './logger.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,0BAA0B,GAG3B,MAAM,aAAa,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Transport-aware Logger for MCP-I
3
+ *
4
+ * Provides a lightweight, dependency-free logging interface that:
5
+ * - Maps log levels correctly for Cloudflare Workers
6
+ * - Routes all logs to stderr for stdio transport (so stdout remains protocol-only)
7
+ * - Supports runtime configuration of log level and transport mode
8
+ */
9
+ export type Level = 'debug' | 'info' | 'warn' | 'error';
10
+ export interface Logger {
11
+ configure: (opts?: {
12
+ level?: Level;
13
+ transport?: string;
14
+ forceStderr?: boolean;
15
+ }) => void;
16
+ debug: (...args: unknown[]) => void;
17
+ info: (...args: unknown[]) => void;
18
+ warn: (...args: unknown[]) => void;
19
+ error: (...args: unknown[]) => void;
20
+ }
21
+ export declare function createDefaultConsoleLogger(): Logger;
22
+ export declare const logger: Logger;
23
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logging/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AASxD,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACzF,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CA8DnD;AAED,eAAO,MAAM,MAAM,QAA+B,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Transport-aware Logger for MCP-I
3
+ *
4
+ * Provides a lightweight, dependency-free logging interface that:
5
+ * - Maps log levels correctly for Cloudflare Workers
6
+ * - Routes all logs to stderr for stdio transport (so stdout remains protocol-only)
7
+ * - Supports runtime configuration of log level and transport mode
8
+ */
9
+ const SEVERITY = {
10
+ debug: 10,
11
+ info: 20,
12
+ warn: 30,
13
+ error: 40,
14
+ };
15
+ export function createDefaultConsoleLogger() {
16
+ let level = 'info';
17
+ let forceStderr = false;
18
+ function shouldLog(l) {
19
+ return SEVERITY[l] >= SEVERITY[level];
20
+ }
21
+ function write(l, ...args) {
22
+ if (!shouldLog(l))
23
+ return;
24
+ if (forceStderr) {
25
+ console.error(...args);
26
+ return;
27
+ }
28
+ switch (l) {
29
+ case 'debug':
30
+ if (typeof console.debug === 'function') {
31
+ console.debug(...args);
32
+ }
33
+ else {
34
+ console.log(...args);
35
+ }
36
+ break;
37
+ case 'info':
38
+ if (typeof console.info === 'function') {
39
+ console.info(...args);
40
+ }
41
+ else {
42
+ console.log(...args);
43
+ }
44
+ break;
45
+ case 'warn':
46
+ if (typeof console.warn === 'function') {
47
+ console.warn(...args);
48
+ }
49
+ else {
50
+ console.error(...args);
51
+ }
52
+ break;
53
+ case 'error':
54
+ console.error(...args);
55
+ break;
56
+ }
57
+ }
58
+ return {
59
+ configure(opts = {}) {
60
+ if (opts.level)
61
+ level = opts.level;
62
+ if (opts.forceStderr === true) {
63
+ forceStderr = true;
64
+ }
65
+ else if (opts.forceStderr === false) {
66
+ forceStderr = false;
67
+ }
68
+ else if (opts.transport === 'stdio') {
69
+ forceStderr = true;
70
+ }
71
+ else if (opts.transport === 'sse' || opts.transport === 'http') {
72
+ forceStderr = false;
73
+ }
74
+ },
75
+ debug: (...a) => write('debug', ...a),
76
+ info: (...a) => write('info', ...a),
77
+ warn: (...a) => write('warn', ...a),
78
+ error: (...a) => write('error', ...a),
79
+ };
80
+ }
81
+ export const logger = createDefaultConsoleLogger();
82
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logging/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP-I Middleware
3
+ *
4
+ * Provides identity-aware middleware for @modelcontextprotocol/sdk Server.
5
+ */
6
+ export { createMCPIMiddleware, type MCPIConfig, type MCPIDelegationConfig, type MCPIIdentityConfig, type MCPIMiddleware, type MCPIToolDefinition, type MCPIToolHandler, type MCPIServer, } from './with-mcpi.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP-I Middleware
3
+ *
4
+ * Provides identity-aware middleware for @modelcontextprotocol/sdk Server.
5
+ */
6
+ export { createMCPIMiddleware, } from './with-mcpi.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,oBAAoB,GAQrB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * MCP-I Middleware for @modelcontextprotocol/sdk Server
3
+ *
4
+ * Adds identity, session management, and proof generation to a standard
5
+ * MCP SDK Server.
6
+ *
7
+ * Usage:
8
+ * const { handshakeTool, registerToolWithProof } = createMCPIMiddleware(config, crypto);
9
+ * server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: [handshakeTool, ...] }));
10
+ * registerToolWithProof(server, myToolDef, myHandler);
11
+ */
12
+ import { type CryptoProvider, FetchProvider } from "../providers/base.js";
13
+ import { SessionManager, type SessionConfig } from "../session/manager.js";
14
+ import { ProofGenerator } from "../proof/generator.js";
15
+ import { type DIDResolver, type StatusListResolver } from "../delegation/vc-verifier.js";
16
+ import { type DelegationCredential } from "../types/protocol.js";
17
+ export interface MCPIIdentityConfig {
18
+ did: string;
19
+ kid: string;
20
+ privateKey: string;
21
+ publicKey: string;
22
+ }
23
+ export interface MCPIDelegationConfig {
24
+ /**
25
+ * Optional custom DID resolver. If it returns null, middleware falls back to
26
+ * built-in did:key resolution and fetch-backed did:web resolution.
27
+ */
28
+ didResolver?: DIDResolver;
29
+ /**
30
+ * Optional fetch provider used for did:web resolution.
31
+ * If omitted, middleware falls back to the runtime global fetch when available.
32
+ */
33
+ fetchProvider?: FetchProvider;
34
+ /**
35
+ * Resolver for StatusList2021 checks. Credentials with credentialStatus are
36
+ * rejected when no resolver is configured.
37
+ */
38
+ statusListResolver?: StatusListResolver;
39
+ /**
40
+ * Resolve ancestor credentials for a delegated chain. The returned array may
41
+ * contain only ancestors (root -> parent) or the full chain (root -> leaf).
42
+ */
43
+ resolveDelegationChain?: (leafCredential: DelegationCredential) => Promise<DelegationCredential[]>;
44
+ /**
45
+ * Compatibility mode for legacy integrations that cannot yet provide
46
+ * full delegation-chain and status-list resolvers.
47
+ *
48
+ * WARNING: Enabling this weakens verification guarantees:
49
+ * - Parent-linked delegations are accepted without chain resolution
50
+ * - credentialStatus is accepted without StatusList checks
51
+ *
52
+ * Default is false (strict security behavior).
53
+ */
54
+ allowLegacyUnsafeDelegation?: boolean;
55
+ }
56
+ export interface MCPIConfig {
57
+ /** Agent identity (DID + key material) */
58
+ identity: MCPIIdentityConfig;
59
+ /** Session configuration overrides */
60
+ session?: Omit<SessionConfig, "nonceCache">;
61
+ /** Delegation verification overrides */
62
+ delegation?: MCPIDelegationConfig;
63
+ /**
64
+ * When true, automatically creates a session on the first tool call
65
+ * if no session exists. Useful for demos and development where
66
+ * MCP clients don't support the _mcpi_handshake flow.
67
+ * In production, MCP-I-aware clients handle handshake automatically.
68
+ */
69
+ autoSession?: boolean;
70
+ }
71
+ export interface MCPIToolDefinition {
72
+ name: string;
73
+ description?: string;
74
+ inputSchema: {
75
+ type: "object";
76
+ properties?: Record<string, unknown>;
77
+ required?: string[];
78
+ [key: string]: unknown;
79
+ };
80
+ }
81
+ export interface MCPIToolHandler {
82
+ (args: Record<string, unknown>, sessionId?: string): Promise<{
83
+ content: Array<{
84
+ type: string;
85
+ text: string;
86
+ [key: string]: unknown;
87
+ }>;
88
+ isError?: boolean;
89
+ [key: string]: unknown;
90
+ }>;
91
+ }
92
+ /**
93
+ * Server interface — minimal subset of @modelcontextprotocol/sdk Server.
94
+ * This avoids a hard dependency on the SDK at the type level.
95
+ */
96
+ export interface MCPIServer {
97
+ setRequestHandler(schema: unknown, handler: (...args: unknown[]) => unknown): void;
98
+ }
99
+ export interface MCPIMiddleware {
100
+ /** The SessionManager instance for manual session operations */
101
+ sessionManager: SessionManager;
102
+ /** The ProofGenerator instance for manual proof operations */
103
+ proofGenerator: ProofGenerator;
104
+ /**
105
+ * Tool definition for `_mcpi_handshake`.
106
+ * Include this in your ListToolsRequest handler's tool list.
107
+ */
108
+ handshakeTool: MCPIToolDefinition;
109
+ /**
110
+ * Handle a handshake call. Use this in your CallToolRequest handler
111
+ * when `request.params.name === '_mcpi_handshake'`.
112
+ */
113
+ handleHandshake(args: Record<string, unknown>): Promise<{
114
+ content: Array<{
115
+ type: string;
116
+ text: string;
117
+ }>;
118
+ isError?: boolean;
119
+ }>;
120
+ /**
121
+ * Wrap a tool handler to automatically generate proofs.
122
+ * Returns a new handler that appends proof metadata to the response.
123
+ */
124
+ wrapWithProof(toolName: string, handler: MCPIToolHandler): MCPIToolHandler;
125
+ /**
126
+ * Wrap a tool handler to require a valid W3C Delegation Credential.
127
+ *
128
+ * Caller must pass the VC as `_mcpi_delegation` in the tool args.
129
+ * - If absent: returns a `needs_authorization` response with the consentUrl.
130
+ * - If present but invalid: returns a structured error with reason.
131
+ * - If valid with correct scope: strips `_mcpi_delegation` and calls the handler.
132
+ */
133
+ wrapWithDelegation(toolName: string, config: {
134
+ scopeId: string;
135
+ consentUrl: string;
136
+ }, handler: MCPIToolHandler): MCPIToolHandler;
137
+ }
138
+ /**
139
+ * Create MCP-I middleware for a standard MCP SDK Server.
140
+ *
141
+ * @param config - Agent identity and session configuration
142
+ * @param cryptoProvider - Platform-specific crypto implementation
143
+ * @returns Middleware components for session management and proof generation
144
+ *
145
+ * @remarks
146
+ * **Single-process only**: This middleware stores session state in memory using closure
147
+ * variables (`activeSessionId`, `sessionNonces`). It is NOT suitable for multi-instance
148
+ * deployments behind a load balancer. For distributed deployments, implement a custom
149
+ * `SessionStore` backed by Redis, DynamoDB, or similar and pass it via `config.session`.
150
+ */
151
+ export declare function createMCPIMiddleware(config: MCPIConfig, cryptoProvider: CryptoProvider): MCPIMiddleware;
152
+ //# sourceMappingURL=with-mcpi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-mcpi.d.ts","sourceRoot":"","sources":["../../src/middleware/with-mcpi.ts"],"names":[],"mappings":"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"}