@kya-os/mcp-i-core 1.3.28 → 1.4.1

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.
package/dist/index.d.ts CHANGED
@@ -43,6 +43,8 @@ export type { ToolProtection, ToolProtectionConfig, ToolProtectionServiceConfig,
43
43
  export { DelegationRequiredError } from "./types/tool-protection";
44
44
  export { OAuthRequiredError } from "./types/oauth-required-error";
45
45
  export type { OAuthRequiredErrorOptions } from "./types/oauth-required-error";
46
+ export { DelegationErrorFormatter, createDelegationErrorFormatter, } from "./services/delegation-error-formatter";
47
+ export type { DelegationErrorFormatOptions, DelegationErrorResult, ClientMessageTemplate, ClientMessagesConfig, } from "./services/delegation-error-formatter";
46
48
  export { DelegationCredentialIssuer, createDelegationIssuer, type IssueDelegationOptions, type VCSigningFunction, type IdentityProvider as DelegationIdentityProvider, } from "./delegation/vc-issuer";
47
49
  export { DelegationCredentialVerifier, createDelegationVerifier, type DelegationVCVerificationResult, type VerifyDelegationVCOptions, type DIDResolver, type DIDDocument, type VerificationMethod, type StatusListResolver, type SignatureVerificationFunction, } from "./delegation/vc-verifier";
48
50
  export { StatusList2021Manager, createStatusListManager, type StatusListStorageProvider, type StatusListIdentityProvider, } from "./delegation/statuslist-manager";
package/dist/index.js CHANGED
@@ -20,8 +20,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
20
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.CascadingRevocationManager = exports.createDelegationGraph = exports.DelegationGraphManager = exports.isIndexSet = exports.BitstringManager = exports.createStatusListManager = exports.StatusList2021Manager = exports.createDelegationVerifier = exports.DelegationCredentialVerifier = exports.createDelegationIssuer = exports.DelegationCredentialIssuer = exports.OAuthRequiredError = exports.DelegationRequiredError = exports.NoOpToolProtectionCache = exports.InMemoryToolProtectionCache = exports.createProofVerificationError = exports.PROOF_VERIFICATION_ERROR_CODES = exports.ProofVerificationError = exports.migrateLegacyKeys = exports.StorageKeyHelpers = exports.createStorageProviders = exports.NoOpOAuthConfigCache = exports.InMemoryOAuthConfigCache = exports.BatchDelegationService = exports.OAuthTokenRetrievalService = exports.ProviderValidationError = exports.ProviderValidator = exports.ConsentOnlyModeError = exports.ProviderResolver = exports.OAuthProviderRegistry = exports.ToolContextBuilder = exports.OAuthService = exports.OAuthConfigService = exports.createSessionRegistrationService = exports.SessionRegistrationService = exports.authorizationMatches = exports.AccessControlApiService = exports.ProofVerifier = exports.CryptoService = exports.ToolProtectionService = exports.MCPIRuntimeBase = exports.MemoryIdentityProvider = exports.MemoryNonceCacheProvider = exports.MemoryStorageProvider = exports.IdentityProvider = exports.NonceCacheProvider = exports.StorageProvider = exports.FetchProvider = exports.ClockProvider = exports.CryptoProvider = void 0;
24
- exports.IdpTokenResolver = exports.UserDidManager = exports.fetchRemoteConfig = exports.bytesToBase64 = exports.base64urlDecodeToString = exports.base64urlDecodeToBytes = exports.base64urlEncodeFromString = exports.base64urlEncodeFromBytes = exports.parseVCJWT = exports.completeVCJWT = exports.createUnsignedVCJWT = exports.canonicalizeJSON = exports.getSchemaStats = exports.getCriticalSchemas = exports.getSchemaById = exports.getSchemasByCategory = exports.getAllSchemas = exports.SCHEMA_REGISTRY = exports.createSchemaVerifier = exports.SchemaVerifier = exports.isValidBase58 = exports.base58Decode = exports.base58Encode = exports.resolveDidKeySync = exports.publicKeyToJwk = exports.extractPublicKeyFromDidKey = exports.isEd25519DidKey = exports.createDidKeyResolver = exports.MemoryDelegationGraphStorage = exports.MemoryStatusListStorage = exports.createCascadingRevocationManager = void 0;
23
+ exports.DelegationGraphManager = exports.isIndexSet = exports.BitstringManager = exports.createStatusListManager = exports.StatusList2021Manager = exports.createDelegationVerifier = exports.DelegationCredentialVerifier = exports.createDelegationIssuer = exports.DelegationCredentialIssuer = exports.createDelegationErrorFormatter = exports.DelegationErrorFormatter = exports.OAuthRequiredError = exports.DelegationRequiredError = exports.NoOpToolProtectionCache = exports.InMemoryToolProtectionCache = exports.createProofVerificationError = exports.PROOF_VERIFICATION_ERROR_CODES = exports.ProofVerificationError = exports.migrateLegacyKeys = exports.StorageKeyHelpers = exports.createStorageProviders = exports.NoOpOAuthConfigCache = exports.InMemoryOAuthConfigCache = exports.BatchDelegationService = exports.OAuthTokenRetrievalService = exports.ProviderValidationError = exports.ProviderValidator = exports.ConsentOnlyModeError = exports.ProviderResolver = exports.OAuthProviderRegistry = exports.ToolContextBuilder = exports.OAuthService = exports.OAuthConfigService = exports.createSessionRegistrationService = exports.SessionRegistrationService = exports.authorizationMatches = exports.AccessControlApiService = exports.ProofVerifier = exports.CryptoService = exports.ToolProtectionService = exports.MCPIRuntimeBase = exports.MemoryIdentityProvider = exports.MemoryNonceCacheProvider = exports.MemoryStorageProvider = exports.IdentityProvider = exports.NonceCacheProvider = exports.StorageProvider = exports.FetchProvider = exports.ClockProvider = exports.CryptoProvider = void 0;
24
+ exports.IdpTokenResolver = exports.UserDidManager = exports.fetchRemoteConfig = exports.bytesToBase64 = exports.base64urlDecodeToString = exports.base64urlDecodeToBytes = exports.base64urlEncodeFromString = exports.base64urlEncodeFromBytes = exports.parseVCJWT = exports.completeVCJWT = exports.createUnsignedVCJWT = exports.canonicalizeJSON = exports.getSchemaStats = exports.getCriticalSchemas = exports.getSchemaById = exports.getSchemasByCategory = exports.getAllSchemas = exports.SCHEMA_REGISTRY = exports.createSchemaVerifier = exports.SchemaVerifier = exports.isValidBase58 = exports.base58Decode = exports.base58Encode = exports.resolveDidKeySync = exports.publicKeyToJwk = exports.extractPublicKeyFromDidKey = exports.isEd25519DidKey = exports.createDidKeyResolver = exports.MemoryDelegationGraphStorage = exports.MemoryStatusListStorage = exports.createCascadingRevocationManager = exports.CascadingRevocationManager = exports.createDelegationGraph = void 0;
25
25
  // Base providers
26
26
  var base_1 = require("./providers/base");
27
27
  Object.defineProperty(exports, "CryptoProvider", { enumerable: true, get: function () { return base_1.CryptoProvider; } });
@@ -104,6 +104,10 @@ var tool_protection_1 = require("./types/tool-protection");
104
104
  Object.defineProperty(exports, "DelegationRequiredError", { enumerable: true, get: function () { return tool_protection_1.DelegationRequiredError; } });
105
105
  var oauth_required_error_1 = require("./types/oauth-required-error");
106
106
  Object.defineProperty(exports, "OAuthRequiredError", { enumerable: true, get: function () { return oauth_required_error_1.OAuthRequiredError; } });
107
+ // Delegation Error Formatter (client-specific messages)
108
+ var delegation_error_formatter_1 = require("./services/delegation-error-formatter");
109
+ Object.defineProperty(exports, "DelegationErrorFormatter", { enumerable: true, get: function () { return delegation_error_formatter_1.DelegationErrorFormatter; } });
110
+ Object.defineProperty(exports, "createDelegationErrorFormatter", { enumerable: true, get: function () { return delegation_error_formatter_1.createDelegationErrorFormatter; } });
107
111
  // Delegation (W3C VC-based)
108
112
  var vc_issuer_1 = require("./delegation/vc-issuer");
109
113
  Object.defineProperty(exports, "DelegationCredentialIssuer", { enumerable: true, get: function () { return vc_issuer_1.DelegationCredentialIssuer; } });
@@ -1000,6 +1000,119 @@ class MCPIRuntimeBase {
1000
1000
  timestamp: this.clock.now(),
1001
1001
  };
1002
1002
  }
1003
+ // SEP-1649 MCP Server Card for client discovery
1004
+ // Support both paths during spec transition:
1005
+ // - /.well-known/mcp.json (current Cursor/Claude Desktop usage)
1006
+ // - /.well-known/mcp/server-card.json (SEP-1649 proposed spec)
1007
+ if (path === "/.well-known/mcp.json" || path === "/.well-known/mcp/server-card.json") {
1008
+ const serverName = config?.serviceName || "mcp-i-server";
1009
+ // SEP-1649 compliant MCP Server Card
1010
+ const mcpServerCard = {
1011
+ $schema: "https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",
1012
+ version: "1.0",
1013
+ protocolVersion: config?.protocolVersion || "2025-06-18",
1014
+ serverInfo: {
1015
+ name: serverName,
1016
+ title: config?.serviceTitle || config?.serviceName || "MCP-I Server",
1017
+ version: config?.serverVersion || "1.0.0",
1018
+ },
1019
+ description: config?.description || "MCP-I enabled server with cryptographic identity",
1020
+ ...(config?.iconUrl && { iconUrl: config.iconUrl }),
1021
+ ...(config?.documentationUrl && { documentationUrl: config.documentationUrl }),
1022
+ transport: {
1023
+ type: "streamable-http",
1024
+ endpoint: "/mcp",
1025
+ },
1026
+ capabilities: {
1027
+ tools: { listChanged: true },
1028
+ },
1029
+ ...(config?.requiresAuth && {
1030
+ authentication: {
1031
+ required: true,
1032
+ schemes: config.authSchemes || ["oauth2"],
1033
+ },
1034
+ }),
1035
+ ...(config?.instructions && { instructions: config.instructions }),
1036
+ // Tools are dynamic - discovered via protocol
1037
+ tools: "dynamic",
1038
+ _meta: {
1039
+ ...config?.metadata,
1040
+ "mcp-i": {
1041
+ agentDid: identity.did,
1042
+ publicKey: identity.publicKey,
1043
+ generatedAt: this.clock.now(),
1044
+ },
1045
+ },
1046
+ };
1047
+ const headers = {
1048
+ "Content-Type": "application/json",
1049
+ "Cache-Control": this.config.environment === "production"
1050
+ ? "public, max-age=3600" // SEP-1649 recommends 1 hour
1051
+ : "no-store",
1052
+ // SEP-1649 CORS requirements for browser-based client discovery
1053
+ "Access-Control-Allow-Origin": "*",
1054
+ "Access-Control-Allow-Methods": "GET",
1055
+ "Access-Control-Allow-Headers": "Content-Type",
1056
+ };
1057
+ return {
1058
+ status: 200,
1059
+ headers,
1060
+ body: JSON.stringify(mcpServerCard, null, 2),
1061
+ };
1062
+ }
1063
+ // Client configuration helper - ready-to-use config for Cursor/Claude Desktop
1064
+ if (path === "/.well-known/mcp-client-config.json") {
1065
+ const serviceEndpoint = config?.serviceEndpoint || "https://example.com";
1066
+ const serverName = config?.serviceName || "mcp-i-server";
1067
+ const mcpUrl = `${serviceEndpoint}/mcp`;
1068
+ // Generate Cursor deep link
1069
+ // Note: Base64 can contain +, /, = which have special meaning in URLs
1070
+ // Must URL-encode the base64 string for safe transmission
1071
+ const cursorConfig = { [serverName]: { url: mcpUrl, transport: "sse" } };
1072
+ const encodedConfig = Buffer.from(JSON.stringify(cursorConfig)).toString("base64");
1073
+ const cursorDeepLink = `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(serverName)}&config=${encodeURIComponent(encodedConfig)}`;
1074
+ const clientConfig = {
1075
+ // For claude_desktop_config.json
1076
+ claudeDesktop: {
1077
+ mcpServers: {
1078
+ [serverName]: {
1079
+ url: mcpUrl,
1080
+ transport: "sse",
1081
+ },
1082
+ },
1083
+ },
1084
+ // For .cursor/mcp.json
1085
+ cursor: {
1086
+ mcpServers: {
1087
+ [serverName]: {
1088
+ url: mcpUrl,
1089
+ transport: "sse",
1090
+ },
1091
+ },
1092
+ },
1093
+ // One-click install for Cursor
1094
+ cursorDeepLink,
1095
+ // Additional info
1096
+ _meta: {
1097
+ serverName,
1098
+ serverUrl: serviceEndpoint,
1099
+ mcpEndpoint: mcpUrl,
1100
+ agentDid: identity.did,
1101
+ generatedAt: this.clock.now(),
1102
+ instructions: "Copy the appropriate config section to your client configuration file.",
1103
+ },
1104
+ };
1105
+ return {
1106
+ status: 200,
1107
+ headers: {
1108
+ "Content-Type": "application/json",
1109
+ "Cache-Control": this.config.environment === "production"
1110
+ ? "public, max-age=300"
1111
+ : "no-store",
1112
+ },
1113
+ body: JSON.stringify(clientConfig, null, 2),
1114
+ };
1115
+ }
1003
1116
  return null;
1004
1117
  };
1005
1118
  }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * DelegationErrorFormatter - Formats delegation error messages for MCP clients
3
+ *
4
+ * This service provides a single source of truth for formatting delegation
5
+ * required error messages. It supports:
6
+ * - Default message templates
7
+ * - Client-specific message customization (claude, chatgpt, cursor, etc.)
8
+ * - Template interpolation with placeholders
9
+ * - Markdown support toggle per client
10
+ *
11
+ * @module @kya-os/mcp-i-core/services/delegation-error-formatter
12
+ */
13
+ import type { ClientMessageTemplate, ClientMessagesConfig } from "@kya-os/contracts/config";
14
+ export type { ClientMessageTemplate, ClientMessagesConfig };
15
+ /**
16
+ * Options for formatting a delegation error message
17
+ */
18
+ export interface DelegationErrorFormatOptions {
19
+ /** Name of the tool that requires delegation */
20
+ toolName: string;
21
+ /** URL where user can provide consent/delegation */
22
+ consentUrl?: string;
23
+ /** Scopes required for the tool */
24
+ scopes?: string[];
25
+ /** Client ID (e.g., "claude", "chatgpt", "cursor") - used for client-specific messages */
26
+ clientId?: string;
27
+ }
28
+ /**
29
+ * Options for formatting an OAuth error message
30
+ */
31
+ export interface OAuthErrorFormatOptions {
32
+ /** Name of the tool that requires OAuth */
33
+ toolName: string;
34
+ /** OAuth authorization URL */
35
+ oauthUrl?: string;
36
+ /** OAuth provider name (e.g., "GitHub", "Google") */
37
+ provider?: string;
38
+ /** Scopes required for the tool */
39
+ scopes?: string[];
40
+ /** Client ID (e.g., "claude", "chatgpt", "cursor") - used for client-specific messages */
41
+ clientId?: string;
42
+ }
43
+ /**
44
+ * Result of formatting a delegation error
45
+ */
46
+ export interface DelegationErrorResult {
47
+ /** Formatted message to display to the user */
48
+ message: string;
49
+ /** Consent URL (may be modified with extra params) */
50
+ consentUrl?: string;
51
+ }
52
+ /**
53
+ * Result of formatting an OAuth error
54
+ */
55
+ export interface OAuthErrorResult {
56
+ /** Formatted message to display to the user */
57
+ message: string;
58
+ /** OAuth URL (may be modified with extra params) */
59
+ oauthUrl?: string;
60
+ }
61
+ /**
62
+ * Service for formatting delegation error messages
63
+ *
64
+ * Provides consistent message formatting across different deployment patterns
65
+ * (agent, adapter) while supporting client-specific customization.
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const formatter = new DelegationErrorFormatter();
70
+ * const { message } = formatter.format({
71
+ * toolName: "checkout",
72
+ * consentUrl: "https://example.com/consent",
73
+ * clientId: "claude"
74
+ * });
75
+ * ```
76
+ */
77
+ export declare class DelegationErrorFormatter {
78
+ private config?;
79
+ constructor(config?: ClientMessagesConfig);
80
+ /**
81
+ * Update the configuration
82
+ */
83
+ setConfig(config: ClientMessagesConfig): void;
84
+ /**
85
+ * Format a delegation error message
86
+ *
87
+ * @param options - Formatting options including toolName, consentUrl, and clientId
88
+ * @returns Formatted message and potentially modified consent URL
89
+ */
90
+ format(options: DelegationErrorFormatOptions): DelegationErrorResult;
91
+ /**
92
+ * Format an OAuth error message
93
+ *
94
+ * @param options - Formatting options including toolName, oauthUrl, provider, and clientId
95
+ * @returns Formatted message and potentially modified OAuth URL
96
+ */
97
+ formatOAuth(options: OAuthErrorFormatOptions): OAuthErrorResult;
98
+ /**
99
+ * Get the template for a specific client, merging with defaults
100
+ */
101
+ private getTemplate;
102
+ /**
103
+ * Build URL with extra parameters if configured
104
+ * Used for both consent URLs and OAuth URLs
105
+ */
106
+ private buildUrl;
107
+ /**
108
+ * Interpolate placeholders in a template string
109
+ *
110
+ * Uses a function replacement to avoid special pattern interpretation.
111
+ * JavaScript's String.replace() interprets patterns like $&, $', $` in the
112
+ * replacement string. Using () => value prevents this.
113
+ */
114
+ private interpolate;
115
+ /**
116
+ * Strip markdown links, converting [text](url) to plain "text: url"
117
+ */
118
+ private stripMarkdownLinks;
119
+ }
120
+ /**
121
+ * Create a delegation error formatter with optional configuration
122
+ */
123
+ export declare function createDelegationErrorFormatter(config?: ClientMessagesConfig): DelegationErrorFormatter;
124
+ //# sourceMappingURL=delegation-error-formatter.d.ts.map
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * DelegationErrorFormatter - Formats delegation error messages for MCP clients
4
+ *
5
+ * This service provides a single source of truth for formatting delegation
6
+ * required error messages. It supports:
7
+ * - Default message templates
8
+ * - Client-specific message customization (claude, chatgpt, cursor, etc.)
9
+ * - Template interpolation with placeholders
10
+ * - Markdown support toggle per client
11
+ *
12
+ * @module @kya-os/mcp-i-core/services/delegation-error-formatter
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DelegationErrorFormatter = void 0;
16
+ exports.createDelegationErrorFormatter = createDelegationErrorFormatter;
17
+ /**
18
+ * Default message template (matches original adapter/agent behavior)
19
+ */
20
+ const DEFAULT_TEMPLATE = {
21
+ message: `Authorization required.
22
+
23
+ [Authorize {toolName}]({consentUrl})
24
+
25
+ Retry after authorizing.`,
26
+ noUrlMessage: `Authorization required for "{toolName}" but no consent URL is available.
27
+
28
+ Please contact the administrator to configure delegation for this tool.`,
29
+ oauthMessage: `Authorization required.
30
+
31
+ [Sign in with {provider}]({oauthUrl})
32
+
33
+ Retry after authorizing.`,
34
+ noOAuthUrlMessage: `Authorization required for "{toolName}" but no {provider} URL is available.
35
+
36
+ Please contact the administrator to configure OAuth for this tool.`,
37
+ supportsMarkdown: true,
38
+ };
39
+ /**
40
+ * Service for formatting delegation error messages
41
+ *
42
+ * Provides consistent message formatting across different deployment patterns
43
+ * (agent, adapter) while supporting client-specific customization.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const formatter = new DelegationErrorFormatter();
48
+ * const { message } = formatter.format({
49
+ * toolName: "checkout",
50
+ * consentUrl: "https://example.com/consent",
51
+ * clientId: "claude"
52
+ * });
53
+ * ```
54
+ */
55
+ class DelegationErrorFormatter {
56
+ config;
57
+ constructor(config) {
58
+ this.config = config;
59
+ }
60
+ /**
61
+ * Update the configuration
62
+ */
63
+ setConfig(config) {
64
+ this.config = config;
65
+ }
66
+ /**
67
+ * Format a delegation error message
68
+ *
69
+ * @param options - Formatting options including toolName, consentUrl, and clientId
70
+ * @returns Formatted message and potentially modified consent URL
71
+ */
72
+ format(options) {
73
+ const { toolName, consentUrl, scopes, clientId } = options;
74
+ // Get the appropriate template for this client
75
+ const template = this.getTemplate(clientId);
76
+ // Build the final consent URL with any extra params
77
+ const finalUrl = this.buildUrl(consentUrl, template);
78
+ // Choose message based on whether we have a consent URL
79
+ let message;
80
+ if (finalUrl) {
81
+ const messageTemplate = template.message ?? DEFAULT_TEMPLATE.message;
82
+ message = this.interpolate(messageTemplate, {
83
+ toolName,
84
+ consentUrl: finalUrl,
85
+ scopes: scopes?.join(", ") ?? "",
86
+ });
87
+ // If client doesn't support markdown, convert markdown links to plain text
88
+ if (template.supportsMarkdown === false) {
89
+ message = this.stripMarkdownLinks(message);
90
+ }
91
+ }
92
+ else {
93
+ const noUrlTemplate = template.noUrlMessage ?? DEFAULT_TEMPLATE.noUrlMessage;
94
+ message = this.interpolate(noUrlTemplate, {
95
+ toolName,
96
+ consentUrl: "",
97
+ scopes: scopes?.join(", ") ?? "",
98
+ });
99
+ }
100
+ return { message, consentUrl: finalUrl };
101
+ }
102
+ /**
103
+ * Format an OAuth error message
104
+ *
105
+ * @param options - Formatting options including toolName, oauthUrl, provider, and clientId
106
+ * @returns Formatted message and potentially modified OAuth URL
107
+ */
108
+ formatOAuth(options) {
109
+ const { toolName, oauthUrl, provider = "OAuth", scopes, clientId } = options;
110
+ // Get the appropriate template for this client
111
+ const template = this.getTemplate(clientId);
112
+ // Build the final OAuth URL with any extra params
113
+ const finalUrl = this.buildUrl(oauthUrl, template);
114
+ // Choose message based on whether we have an OAuth URL
115
+ let message;
116
+ if (finalUrl) {
117
+ const messageTemplate = template.oauthMessage ?? DEFAULT_TEMPLATE.oauthMessage;
118
+ message = this.interpolate(messageTemplate, {
119
+ toolName,
120
+ oauthUrl: finalUrl,
121
+ provider,
122
+ scopes: scopes?.join(", ") ?? "",
123
+ });
124
+ // If client doesn't support markdown, convert markdown links to plain text
125
+ if (template.supportsMarkdown === false) {
126
+ message = this.stripMarkdownLinks(message);
127
+ }
128
+ }
129
+ else {
130
+ const noUrlTemplate = template.noOAuthUrlMessage ?? DEFAULT_TEMPLATE.noOAuthUrlMessage;
131
+ message = this.interpolate(noUrlTemplate, {
132
+ toolName,
133
+ oauthUrl: "",
134
+ provider,
135
+ scopes: scopes?.join(", ") ?? "",
136
+ });
137
+ }
138
+ return { message, oauthUrl: finalUrl };
139
+ }
140
+ /**
141
+ * Get the template for a specific client, merging with defaults
142
+ */
143
+ getTemplate(clientId) {
144
+ const defaultTemplate = this.config?.default ?? {};
145
+ // If no client ID or no client-specific config, use default
146
+ if (!clientId || !this.config?.clients?.[clientId]) {
147
+ return {
148
+ ...DEFAULT_TEMPLATE,
149
+ ...defaultTemplate,
150
+ };
151
+ }
152
+ // Merge: DEFAULT_TEMPLATE < config.default < config.clients[clientId]
153
+ return {
154
+ ...DEFAULT_TEMPLATE,
155
+ ...defaultTemplate,
156
+ ...this.config.clients[clientId],
157
+ };
158
+ }
159
+ /**
160
+ * Build URL with extra parameters if configured
161
+ * Used for both consent URLs and OAuth URLs
162
+ */
163
+ buildUrl(baseUrl, template) {
164
+ if (!baseUrl)
165
+ return undefined;
166
+ // If no extra params, return as-is
167
+ if (!template.extraParams || Object.keys(template.extraParams).length === 0) {
168
+ return baseUrl;
169
+ }
170
+ // Add extra params to URL
171
+ try {
172
+ const url = new URL(baseUrl);
173
+ for (const [key, value] of Object.entries(template.extraParams)) {
174
+ url.searchParams.set(key, value);
175
+ }
176
+ return url.toString();
177
+ }
178
+ catch {
179
+ // If URL parsing fails, return original
180
+ return baseUrl;
181
+ }
182
+ }
183
+ /**
184
+ * Interpolate placeholders in a template string
185
+ *
186
+ * Uses a function replacement to avoid special pattern interpretation.
187
+ * JavaScript's String.replace() interprets patterns like $&, $', $` in the
188
+ * replacement string. Using () => value prevents this.
189
+ */
190
+ interpolate(template, values) {
191
+ let result = template;
192
+ for (const [key, value] of Object.entries(values)) {
193
+ // Use function replacement to prevent special pattern interpretation
194
+ // e.g., URLs containing $& would otherwise get corrupted
195
+ result = result.replace(new RegExp(`\\{${key}\\}`, "g"), () => value);
196
+ }
197
+ return result;
198
+ }
199
+ /**
200
+ * Strip markdown links, converting [text](url) to plain "text: url"
201
+ */
202
+ stripMarkdownLinks(text) {
203
+ // Match [link text](url) and convert to "link text: url"
204
+ return text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1: $2");
205
+ }
206
+ }
207
+ exports.DelegationErrorFormatter = DelegationErrorFormatter;
208
+ /**
209
+ * Create a delegation error formatter with optional configuration
210
+ */
211
+ function createDelegationErrorFormatter(config) {
212
+ return new DelegationErrorFormatter(config);
213
+ }
214
+ //# sourceMappingURL=delegation-error-formatter.js.map
@@ -4,4 +4,6 @@ export { AccessControlApiService, authorizationMatches, } from './access-control
4
4
  export type { AccessControlApiServiceConfig, AccessControlApiServiceMetrics, } from './access-control.service.js';
5
5
  export { SessionRegistrationService, createSessionRegistrationService, } from './session-registration.service.js';
6
6
  export type { SessionRegistrationServiceConfig, SessionRegistrationResult, } from './session-registration.service.js';
7
+ export { DelegationErrorFormatter, createDelegationErrorFormatter, } from './delegation-error-formatter.js';
8
+ export type { DelegationErrorFormatOptions, DelegationErrorResult, OAuthErrorFormatOptions, OAuthErrorResult, ClientMessageTemplate, ClientMessagesConfig, } from './delegation-error-formatter.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createSessionRegistrationService = exports.SessionRegistrationService = exports.authorizationMatches = exports.AccessControlApiService = exports.CryptoService = void 0;
3
+ exports.createDelegationErrorFormatter = exports.DelegationErrorFormatter = exports.createSessionRegistrationService = exports.SessionRegistrationService = exports.authorizationMatches = exports.AccessControlApiService = exports.CryptoService = void 0;
4
4
  var crypto_service_js_1 = require("./crypto.service.js");
5
5
  Object.defineProperty(exports, "CryptoService", { enumerable: true, get: function () { return crypto_service_js_1.CryptoService; } });
6
6
  var access_control_service_js_1 = require("./access-control.service.js");
@@ -9,4 +9,7 @@ Object.defineProperty(exports, "authorizationMatches", { enumerable: true, get:
9
9
  var session_registration_service_js_1 = require("./session-registration.service.js");
10
10
  Object.defineProperty(exports, "SessionRegistrationService", { enumerable: true, get: function () { return session_registration_service_js_1.SessionRegistrationService; } });
11
11
  Object.defineProperty(exports, "createSessionRegistrationService", { enumerable: true, get: function () { return session_registration_service_js_1.createSessionRegistrationService; } });
12
+ var delegation_error_formatter_js_1 = require("./delegation-error-formatter.js");
13
+ Object.defineProperty(exports, "DelegationErrorFormatter", { enumerable: true, get: function () { return delegation_error_formatter_js_1.DelegationErrorFormatter; } });
14
+ Object.defineProperty(exports, "createDelegationErrorFormatter", { enumerable: true, get: function () { return delegation_error_formatter_js_1.createDelegationErrorFormatter; } });
12
15
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/mcp-i-core",
3
- "version": "1.3.28",
3
+ "version": "1.4.1",
4
4
  "description": "Core runtime and types for MCP-I framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "prepublishOnly": "npm run build && node ../create-mcpi-app/scripts/validate-no-workspace.js"
29
29
  },
30
30
  "dependencies": {
31
- "@kya-os/contracts": "^1.6.18",
31
+ "@kya-os/contracts": "^1.7.2",
32
32
  "jose": "^5.6.3",
33
33
  "json-canonicalize": "^2.0.0",
34
34
  "zod": "^3.25.76"