@mcp-z/client 1.2.0 → 2.0.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.
Files changed (77) hide show
  1. package/dist/cjs/auth/capability-discovery.js +5 -1
  2. package/dist/cjs/auth/capability-discovery.js.map +1 -1
  3. package/dist/cjs/auth/interactive-oauth-flow.d.cts +9 -2
  4. package/dist/cjs/auth/interactive-oauth-flow.d.ts +9 -2
  5. package/dist/cjs/auth/interactive-oauth-flow.js +29 -11
  6. package/dist/cjs/auth/interactive-oauth-flow.js.map +1 -1
  7. package/dist/cjs/auth/oauth-callback-listener.js +4 -0
  8. package/dist/cjs/auth/oauth-callback-listener.js.map +1 -1
  9. package/dist/cjs/auth/types.d.cts +18 -4
  10. package/dist/cjs/auth/types.d.ts +18 -4
  11. package/dist/cjs/auth/types.js.map +1 -1
  12. package/dist/cjs/client-helpers.d.cts +5 -6
  13. package/dist/cjs/client-helpers.d.ts +5 -6
  14. package/dist/cjs/client-helpers.js +8 -8
  15. package/dist/cjs/client-helpers.js.map +1 -1
  16. package/dist/cjs/connection/connect-client.d.cts +1 -2
  17. package/dist/cjs/connection/connect-client.d.ts +1 -2
  18. package/dist/cjs/connection/connect-client.js +6 -9
  19. package/dist/cjs/connection/connect-client.js.map +1 -1
  20. package/dist/cjs/connection/existing-process-transport.d.cts +1 -2
  21. package/dist/cjs/connection/existing-process-transport.d.ts +1 -2
  22. package/dist/cjs/connection/existing-process-transport.js +3 -3
  23. package/dist/cjs/connection/existing-process-transport.js.map +1 -1
  24. package/dist/cjs/dcr/dcr-authenticator.d.cts +6 -1
  25. package/dist/cjs/dcr/dcr-authenticator.d.ts +6 -1
  26. package/dist/cjs/dcr/dcr-authenticator.js +423 -40
  27. package/dist/cjs/dcr/dcr-authenticator.js.map +1 -1
  28. package/dist/cjs/dcr/dynamic-client-registrar.d.cts +2 -2
  29. package/dist/cjs/dcr/dynamic-client-registrar.d.ts +2 -2
  30. package/dist/cjs/dcr/dynamic-client-registrar.js +10 -11
  31. package/dist/cjs/dcr/dynamic-client-registrar.js.map +1 -1
  32. package/dist/cjs/lib/url-utils.js +2 -2
  33. package/dist/cjs/lib/url-utils.js.map +1 -1
  34. package/dist/cjs/response-wrappers.d.cts +1 -1
  35. package/dist/cjs/response-wrappers.d.ts +1 -1
  36. package/dist/cjs/response-wrappers.js.map +1 -1
  37. package/dist/cjs/search/search.d.cts +1 -1
  38. package/dist/cjs/search/search.d.ts +1 -1
  39. package/dist/cjs/search/search.js.map +1 -1
  40. package/dist/esm/auth/capability-discovery.js +5 -1
  41. package/dist/esm/auth/capability-discovery.js.map +1 -1
  42. package/dist/esm/auth/interactive-oauth-flow.d.ts +9 -2
  43. package/dist/esm/auth/interactive-oauth-flow.js +28 -10
  44. package/dist/esm/auth/interactive-oauth-flow.js.map +1 -1
  45. package/dist/esm/auth/oauth-callback-listener.js +4 -0
  46. package/dist/esm/auth/oauth-callback-listener.js.map +1 -1
  47. package/dist/esm/auth/types.d.ts +18 -4
  48. package/dist/esm/auth/types.js.map +1 -1
  49. package/dist/esm/client-helpers.d.ts +5 -6
  50. package/dist/esm/client-helpers.js +8 -8
  51. package/dist/esm/client-helpers.js.map +1 -1
  52. package/dist/esm/connection/connect-client.d.ts +1 -2
  53. package/dist/esm/connection/connect-client.js +2 -5
  54. package/dist/esm/connection/connect-client.js.map +1 -1
  55. package/dist/esm/connection/existing-process-transport.d.ts +1 -2
  56. package/dist/esm/connection/existing-process-transport.js +1 -1
  57. package/dist/esm/connection/existing-process-transport.js.map +1 -1
  58. package/dist/esm/dcr/dcr-authenticator.d.ts +6 -1
  59. package/dist/esm/dcr/dcr-authenticator.js +79 -35
  60. package/dist/esm/dcr/dcr-authenticator.js.map +1 -1
  61. package/dist/esm/dcr/dynamic-client-registrar.d.ts +2 -2
  62. package/dist/esm/dcr/dynamic-client-registrar.js +7 -6
  63. package/dist/esm/dcr/dynamic-client-registrar.js.map +1 -1
  64. package/dist/esm/lib/url-utils.js +2 -2
  65. package/dist/esm/lib/url-utils.js.map +1 -1
  66. package/dist/esm/response-wrappers.d.ts +1 -1
  67. package/dist/esm/response-wrappers.js.map +1 -1
  68. package/dist/esm/search/search.d.ts +1 -1
  69. package/dist/esm/search/search.js.map +1 -1
  70. package/package.json +4 -3
  71. package/dist/cjs/monkey-patches.d.cts +0 -6
  72. package/dist/cjs/monkey-patches.d.ts +0 -6
  73. package/dist/cjs/monkey-patches.js +0 -233
  74. package/dist/cjs/monkey-patches.js.map +0 -1
  75. package/dist/esm/monkey-patches.d.ts +0 -6
  76. package/dist/esm/monkey-patches.js +0 -32
  77. package/dist/esm/monkey-patches.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/search/search.ts"],"sourcesContent":["/**\n * Search implementation for MCP capability discovery\n *\n * Provides text-based search across tools, prompts, and resources\n * from connected MCP servers.\n */\n\nimport type { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type { PromptArgument } from '../connection/types.ts';\nimport type { CapabilityIndex, CapabilityType, IndexedCapability, IndexedPrompt, IndexedResource, IndexedTool, SearchField, SearchOptions, SearchResponse, SearchResult } from './types.ts';\n\nexport type CapabilityClient = Pick<Client, 'listTools' | 'listPrompts' | 'listResources'>;\n\nconst DEFAULT_LIMIT = 20;\nconst DEFAULT_THRESHOLD = 0;\nconst DEFAULT_TYPES: CapabilityType[] = ['tool', 'prompt', 'resource'];\nconst DEFAULT_SEARCH_FIELDS: SearchField[] = ['name', 'description', 'schema'];\n\n/**\n * Extract searchable text from a JSON Schema's property descriptions\n */\nfunction extractSchemaText(inputSchema: unknown): string {\n if (!inputSchema || typeof inputSchema !== 'object') {\n return '';\n }\n\n const schema = inputSchema as {\n properties?: Record<string, { description?: string; name?: string }>;\n description?: string;\n };\n\n const parts: string[] = [];\n\n // Add schema-level description if present\n if (schema.description) {\n parts.push(schema.description);\n }\n\n // Add property names and descriptions\n if (schema.properties) {\n for (const [propName, prop] of Object.entries(schema.properties)) {\n parts.push(propName);\n if (prop && typeof prop === 'object' && prop.description) {\n parts.push(prop.description);\n }\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Extract searchable text from prompt arguments\n */\nfunction extractArgumentsText(args: PromptArgument[] | undefined): string {\n if (!args || !Array.isArray(args)) {\n return '';\n }\n\n return args\n .map((arg) => {\n const parts = [arg.name];\n if (arg.description) {\n parts.push(arg.description);\n }\n return parts.join(' ');\n })\n .join(' ');\n}\n\n/**\n * Build an index of capabilities from connected MCP clients\n */\nexport async function buildCapabilityIndex(clients: Map<string, CapabilityClient>): Promise<CapabilityIndex> {\n const capabilities: IndexedCapability[] = [];\n const servers: string[] = [];\n\n for (const [serverName, client] of clients) {\n servers.push(serverName);\n\n // Fetch all capabilities in parallel, handling errors gracefully\n const [toolsResult, promptsResult, resourcesResult] = await Promise.all([client.listTools().catch(() => null), client.listPrompts().catch(() => null), client.listResources().catch(() => null)]);\n\n // Index tools\n if (toolsResult?.tools) {\n for (const tool of toolsResult.tools) {\n capabilities.push({\n type: 'tool',\n server: serverName,\n name: tool.name,\n description: tool.description,\n schemaText: extractSchemaText(tool.inputSchema),\n } satisfies IndexedTool);\n }\n }\n\n // Index prompts\n if (promptsResult?.prompts) {\n for (const prompt of promptsResult.prompts) {\n capabilities.push({\n type: 'prompt',\n server: serverName,\n name: prompt.name,\n description: prompt.description,\n argumentsText: extractArgumentsText(prompt.arguments as PromptArgument[] | undefined),\n arguments: prompt.arguments as PromptArgument[] | undefined,\n } satisfies IndexedPrompt);\n }\n }\n\n // Index resources\n if (resourcesResult?.resources) {\n for (const resource of resourcesResult.resources) {\n capabilities.push({\n type: 'resource',\n server: serverName,\n name: resource.name,\n description: resource.description,\n uri: resource.uri,\n mimeType: resource.mimeType,\n } satisfies IndexedResource);\n }\n }\n }\n\n return {\n capabilities,\n servers,\n indexedAt: new Date(),\n };\n}\n\n/**\n * Calculate relevance score and matched fields for a capability against a query\n */\nfunction scoreCapability(capability: IndexedCapability, queryTerms: string[], searchFields: SearchField[]): { score: number; matchedOn: string[] } {\n const matchedOn: string[] = [];\n let totalScore = 0;\n\n // Weights for different match types\n const EXACT_NAME_WEIGHT = 1.0;\n const PARTIAL_NAME_WEIGHT = 0.8;\n const DESCRIPTION_WEIGHT = 0.6;\n const SCHEMA_WEIGHT = 0.4;\n const SERVER_WEIGHT = 0.3;\n\n const nameLower = capability.name.toLowerCase();\n const descLower = (capability.description || '').toLowerCase();\n const serverLower = capability.server.toLowerCase();\n\n // Get schema/arguments text based on type\n let schemaTextLower = '';\n if (capability.type === 'tool') {\n schemaTextLower = capability.schemaText.toLowerCase();\n } else if (capability.type === 'prompt') {\n schemaTextLower = capability.argumentsText.toLowerCase();\n } else if (capability.type === 'resource') {\n // For resources, include URI and mimeType in searchable text\n schemaTextLower = `${capability.uri} ${capability.mimeType || ''}`.toLowerCase();\n }\n\n for (const term of queryTerms) {\n const termLower = term.toLowerCase();\n\n // Check name matches\n if (searchFields.includes('name')) {\n if (nameLower === termLower) {\n totalScore += EXACT_NAME_WEIGHT;\n if (!matchedOn.includes('name')) matchedOn.push('name');\n } else if (nameLower.includes(termLower)) {\n totalScore += PARTIAL_NAME_WEIGHT;\n if (!matchedOn.includes('name')) matchedOn.push('name');\n }\n }\n\n // Check description matches\n if (searchFields.includes('description') && descLower.includes(termLower)) {\n totalScore += DESCRIPTION_WEIGHT;\n if (!matchedOn.includes('description')) matchedOn.push('description');\n }\n\n // Check schema/arguments matches\n if (searchFields.includes('schema') && schemaTextLower.includes(termLower)) {\n totalScore += SCHEMA_WEIGHT;\n const fieldName = capability.type === 'tool' ? 'inputSchema' : capability.type === 'prompt' ? 'arguments' : 'uri';\n if (!matchedOn.includes(fieldName)) matchedOn.push(fieldName);\n }\n\n // Check server name matches\n if (searchFields.includes('server') && serverLower.includes(termLower)) {\n totalScore += SERVER_WEIGHT;\n if (!matchedOn.includes('server')) matchedOn.push('server');\n }\n }\n\n // Normalize score to 0-1 range based on number of terms\n const normalizedScore = queryTerms.length > 0 ? Math.min(1, totalScore / queryTerms.length) : 0;\n\n return { score: normalizedScore, matchedOn };\n}\n\n/**\n * Search for capabilities matching a query string\n */\nexport function searchCapabilities(index: CapabilityIndex, query: string, options: SearchOptions = {}): SearchResponse {\n const { types = DEFAULT_TYPES, servers, searchFields = DEFAULT_SEARCH_FIELDS, limit = DEFAULT_LIMIT, threshold = DEFAULT_THRESHOLD } = options;\n\n // Tokenize query into search terms\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((term) => term.length > 0);\n\n // If empty query, return empty results\n if (queryTerms.length === 0) {\n return { query, results: [], total: 0 };\n }\n\n // Filter and score capabilities\n const scoredResults: Array<{ capability: IndexedCapability; score: number; matchedOn: string[] }> = [];\n\n for (const capability of index.capabilities) {\n // Filter by type\n if (!types.includes(capability.type)) {\n continue;\n }\n\n // Filter by server\n if (servers && servers.length > 0 && !servers.includes(capability.server)) {\n continue;\n }\n\n // Score the capability\n const { score, matchedOn } = scoreCapability(capability, queryTerms, searchFields);\n\n // Apply threshold filter\n if (score >= threshold && matchedOn.length > 0) {\n scoredResults.push({ capability, score, matchedOn });\n }\n }\n\n // Sort by score descending\n scoredResults.sort((a, b) => b.score - a.score);\n\n // Get total before limiting\n const total = scoredResults.length;\n\n // Apply limit and transform to SearchResult\n const results: SearchResult[] = scoredResults.slice(0, limit).map(({ capability, score, matchedOn }) => ({\n type: capability.type,\n server: capability.server,\n name: capability.name,\n description: capability.description,\n matchedOn,\n score,\n }));\n\n return { query, results, total };\n}\n\n/**\n * Convenience function to search directly from connected clients\n * Builds index and performs search in one call\n */\nexport async function search(clients: Map<string, CapabilityClient>, query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n const index = await buildCapabilityIndex(clients);\n return searchCapabilities(index, query, options);\n}\n"],"names":["DEFAULT_LIMIT","DEFAULT_THRESHOLD","DEFAULT_TYPES","DEFAULT_SEARCH_FIELDS","extractSchemaText","inputSchema","schema","parts","description","push","properties","propName","prop","Object","entries","join","extractArgumentsText","args","Array","isArray","map","arg","name","buildCapabilityIndex","clients","capabilities","servers","serverName","client","toolsResult","promptsResult","resourcesResult","Promise","all","listTools","catch","listPrompts","listResources","tools","tool","type","server","schemaText","prompts","prompt","argumentsText","arguments","resources","resource","uri","mimeType","indexedAt","Date","scoreCapability","capability","queryTerms","searchFields","matchedOn","totalScore","EXACT_NAME_WEIGHT","PARTIAL_NAME_WEIGHT","DESCRIPTION_WEIGHT","SCHEMA_WEIGHT","SERVER_WEIGHT","nameLower","toLowerCase","descLower","serverLower","schemaTextLower","term","termLower","includes","fieldName","normalizedScore","length","Math","min","score","searchCapabilities","index","query","options","types","limit","threshold","split","filter","results","total","scoredResults","sort","a","b","slice","search"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/search/search.ts"],"sourcesContent":["/**\n * Search implementation for MCP capability discovery\n *\n * Provides text-based search across tools, prompts, and resources\n * from connected MCP servers.\n */\n\nimport type { Client } from '@modelcontextprotocol/client';\nimport type { PromptArgument } from '../connection/types.ts';\nimport type { CapabilityIndex, CapabilityType, IndexedCapability, IndexedPrompt, IndexedResource, IndexedTool, SearchField, SearchOptions, SearchResponse, SearchResult } from './types.ts';\n\nexport type CapabilityClient = Pick<Client, 'listTools' | 'listPrompts' | 'listResources'>;\n\nconst DEFAULT_LIMIT = 20;\nconst DEFAULT_THRESHOLD = 0;\nconst DEFAULT_TYPES: CapabilityType[] = ['tool', 'prompt', 'resource'];\nconst DEFAULT_SEARCH_FIELDS: SearchField[] = ['name', 'description', 'schema'];\n\n/**\n * Extract searchable text from a JSON Schema's property descriptions\n */\nfunction extractSchemaText(inputSchema: unknown): string {\n if (!inputSchema || typeof inputSchema !== 'object') {\n return '';\n }\n\n const schema = inputSchema as {\n properties?: Record<string, { description?: string; name?: string }>;\n description?: string;\n };\n\n const parts: string[] = [];\n\n // Add schema-level description if present\n if (schema.description) {\n parts.push(schema.description);\n }\n\n // Add property names and descriptions\n if (schema.properties) {\n for (const [propName, prop] of Object.entries(schema.properties)) {\n parts.push(propName);\n if (prop && typeof prop === 'object' && prop.description) {\n parts.push(prop.description);\n }\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Extract searchable text from prompt arguments\n */\nfunction extractArgumentsText(args: PromptArgument[] | undefined): string {\n if (!args || !Array.isArray(args)) {\n return '';\n }\n\n return args\n .map((arg) => {\n const parts = [arg.name];\n if (arg.description) {\n parts.push(arg.description);\n }\n return parts.join(' ');\n })\n .join(' ');\n}\n\n/**\n * Build an index of capabilities from connected MCP clients\n */\nexport async function buildCapabilityIndex(clients: Map<string, CapabilityClient>): Promise<CapabilityIndex> {\n const capabilities: IndexedCapability[] = [];\n const servers: string[] = [];\n\n for (const [serverName, client] of clients) {\n servers.push(serverName);\n\n // Fetch all capabilities in parallel, handling errors gracefully\n const [toolsResult, promptsResult, resourcesResult] = await Promise.all([client.listTools().catch(() => null), client.listPrompts().catch(() => null), client.listResources().catch(() => null)]);\n\n // Index tools\n if (toolsResult?.tools) {\n for (const tool of toolsResult.tools) {\n capabilities.push({\n type: 'tool',\n server: serverName,\n name: tool.name,\n description: tool.description,\n schemaText: extractSchemaText(tool.inputSchema),\n } satisfies IndexedTool);\n }\n }\n\n // Index prompts\n if (promptsResult?.prompts) {\n for (const prompt of promptsResult.prompts) {\n capabilities.push({\n type: 'prompt',\n server: serverName,\n name: prompt.name,\n description: prompt.description,\n argumentsText: extractArgumentsText(prompt.arguments as PromptArgument[] | undefined),\n arguments: prompt.arguments as PromptArgument[] | undefined,\n } satisfies IndexedPrompt);\n }\n }\n\n // Index resources\n if (resourcesResult?.resources) {\n for (const resource of resourcesResult.resources) {\n capabilities.push({\n type: 'resource',\n server: serverName,\n name: resource.name,\n description: resource.description,\n uri: resource.uri,\n mimeType: resource.mimeType,\n } satisfies IndexedResource);\n }\n }\n }\n\n return {\n capabilities,\n servers,\n indexedAt: new Date(),\n };\n}\n\n/**\n * Calculate relevance score and matched fields for a capability against a query\n */\nfunction scoreCapability(capability: IndexedCapability, queryTerms: string[], searchFields: SearchField[]): { score: number; matchedOn: string[] } {\n const matchedOn: string[] = [];\n let totalScore = 0;\n\n // Weights for different match types\n const EXACT_NAME_WEIGHT = 1.0;\n const PARTIAL_NAME_WEIGHT = 0.8;\n const DESCRIPTION_WEIGHT = 0.6;\n const SCHEMA_WEIGHT = 0.4;\n const SERVER_WEIGHT = 0.3;\n\n const nameLower = capability.name.toLowerCase();\n const descLower = (capability.description || '').toLowerCase();\n const serverLower = capability.server.toLowerCase();\n\n // Get schema/arguments text based on type\n let schemaTextLower = '';\n if (capability.type === 'tool') {\n schemaTextLower = capability.schemaText.toLowerCase();\n } else if (capability.type === 'prompt') {\n schemaTextLower = capability.argumentsText.toLowerCase();\n } else if (capability.type === 'resource') {\n // For resources, include URI and mimeType in searchable text\n schemaTextLower = `${capability.uri} ${capability.mimeType || ''}`.toLowerCase();\n }\n\n for (const term of queryTerms) {\n const termLower = term.toLowerCase();\n\n // Check name matches\n if (searchFields.includes('name')) {\n if (nameLower === termLower) {\n totalScore += EXACT_NAME_WEIGHT;\n if (!matchedOn.includes('name')) matchedOn.push('name');\n } else if (nameLower.includes(termLower)) {\n totalScore += PARTIAL_NAME_WEIGHT;\n if (!matchedOn.includes('name')) matchedOn.push('name');\n }\n }\n\n // Check description matches\n if (searchFields.includes('description') && descLower.includes(termLower)) {\n totalScore += DESCRIPTION_WEIGHT;\n if (!matchedOn.includes('description')) matchedOn.push('description');\n }\n\n // Check schema/arguments matches\n if (searchFields.includes('schema') && schemaTextLower.includes(termLower)) {\n totalScore += SCHEMA_WEIGHT;\n const fieldName = capability.type === 'tool' ? 'inputSchema' : capability.type === 'prompt' ? 'arguments' : 'uri';\n if (!matchedOn.includes(fieldName)) matchedOn.push(fieldName);\n }\n\n // Check server name matches\n if (searchFields.includes('server') && serverLower.includes(termLower)) {\n totalScore += SERVER_WEIGHT;\n if (!matchedOn.includes('server')) matchedOn.push('server');\n }\n }\n\n // Normalize score to 0-1 range based on number of terms\n const normalizedScore = queryTerms.length > 0 ? Math.min(1, totalScore / queryTerms.length) : 0;\n\n return { score: normalizedScore, matchedOn };\n}\n\n/**\n * Search for capabilities matching a query string\n */\nexport function searchCapabilities(index: CapabilityIndex, query: string, options: SearchOptions = {}): SearchResponse {\n const { types = DEFAULT_TYPES, servers, searchFields = DEFAULT_SEARCH_FIELDS, limit = DEFAULT_LIMIT, threshold = DEFAULT_THRESHOLD } = options;\n\n // Tokenize query into search terms\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((term) => term.length > 0);\n\n // If empty query, return empty results\n if (queryTerms.length === 0) {\n return { query, results: [], total: 0 };\n }\n\n // Filter and score capabilities\n const scoredResults: Array<{ capability: IndexedCapability; score: number; matchedOn: string[] }> = [];\n\n for (const capability of index.capabilities) {\n // Filter by type\n if (!types.includes(capability.type)) {\n continue;\n }\n\n // Filter by server\n if (servers && servers.length > 0 && !servers.includes(capability.server)) {\n continue;\n }\n\n // Score the capability\n const { score, matchedOn } = scoreCapability(capability, queryTerms, searchFields);\n\n // Apply threshold filter\n if (score >= threshold && matchedOn.length > 0) {\n scoredResults.push({ capability, score, matchedOn });\n }\n }\n\n // Sort by score descending\n scoredResults.sort((a, b) => b.score - a.score);\n\n // Get total before limiting\n const total = scoredResults.length;\n\n // Apply limit and transform to SearchResult\n const results: SearchResult[] = scoredResults.slice(0, limit).map(({ capability, score, matchedOn }) => ({\n type: capability.type,\n server: capability.server,\n name: capability.name,\n description: capability.description,\n matchedOn,\n score,\n }));\n\n return { query, results, total };\n}\n\n/**\n * Convenience function to search directly from connected clients\n * Builds index and performs search in one call\n */\nexport async function search(clients: Map<string, CapabilityClient>, query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n const index = await buildCapabilityIndex(clients);\n return searchCapabilities(index, query, options);\n}\n"],"names":["DEFAULT_LIMIT","DEFAULT_THRESHOLD","DEFAULT_TYPES","DEFAULT_SEARCH_FIELDS","extractSchemaText","inputSchema","schema","parts","description","push","properties","propName","prop","Object","entries","join","extractArgumentsText","args","Array","isArray","map","arg","name","buildCapabilityIndex","clients","capabilities","servers","serverName","client","toolsResult","promptsResult","resourcesResult","Promise","all","listTools","catch","listPrompts","listResources","tools","tool","type","server","schemaText","prompts","prompt","argumentsText","arguments","resources","resource","uri","mimeType","indexedAt","Date","scoreCapability","capability","queryTerms","searchFields","matchedOn","totalScore","EXACT_NAME_WEIGHT","PARTIAL_NAME_WEIGHT","DESCRIPTION_WEIGHT","SCHEMA_WEIGHT","SERVER_WEIGHT","nameLower","toLowerCase","descLower","serverLower","schemaTextLower","term","termLower","includes","fieldName","normalizedScore","length","Math","min","score","searchCapabilities","index","query","options","types","limit","threshold","split","filter","results","total","scoredResults","sort","a","b","slice","search"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-z/client",
3
- "version": "1.2.0",
3
+ "version": "2.0.1",
4
4
  "description": "Programmatic MCP client library for Node.js - connect, discover, and call tools on Model Context Protocol servers.",
5
5
  "keywords": [
6
6
  "mcp",
@@ -53,13 +53,13 @@
53
53
  "format": "tsds format",
54
54
  "generate:types": "json2ts schemas/servers.schema.json schemas/servers.d.ts --bannerComment \"/* eslint-disable */\n/* Auto-generated from schemas/servers.schema.json - DO NOT EDIT */\"",
55
55
  "prepublish:check": "ncp",
56
- "prepublishOnly": "tsds validate",
56
+ "prepublishOnly": "node scripts/require-dist-tag.cjs && tsds validate",
57
57
  "test": "tsds test:node --no-timeouts",
58
58
  "test:engines": "nvu engines tsds test:node --no-timeouts",
59
59
  "version": "tsds version"
60
60
  },
61
61
  "dependencies": {
62
- "@modelcontextprotocol/sdk": "^1.0.0",
62
+ "@modelcontextprotocol/client": "^2.0.0",
63
63
  "ajv": "^8.0.0",
64
64
  "ajv-formats": "^3.0.0",
65
65
  "get-port": "5.1.1",
@@ -69,6 +69,7 @@
69
69
  "module-root-sync": "^2.0.0"
70
70
  },
71
71
  "devDependencies": {
72
+ "@modelcontextprotocol/sdk": "^1.30.0",
72
73
  "@types/express": "^5.0.6",
73
74
  "@types/mocha": "^10.0.10",
74
75
  "@types/node": "^26.2.0",
@@ -1,6 +0,0 @@
1
- /**
2
- * Monkey patches for MCP SDK bugs
3
- *
4
- * These patches fix bugs in dependencies that haven't been fixed upstream yet.
5
- */
6
- export {};
@@ -1,6 +0,0 @@
1
- /**
2
- * Monkey patches for MCP SDK bugs
3
- *
4
- * These patches fix bugs in dependencies that haven't been fixed upstream yet.
5
- */
6
- export {};
@@ -1,233 +0,0 @@
1
- /**
2
- * Monkey patches for MCP SDK bugs
3
- *
4
- * These patches fix bugs in dependencies that haven't been fixed upstream yet.
5
- */ "use strict";
6
- Object.defineProperty(exports, "__esModule", {
7
- value: true
8
- });
9
- var _protocol = require("@modelcontextprotocol/sdk/shared/protocol.js");
10
- function _array_like_to_array(arr, len) {
11
- if (len == null || len > arr.length) len = arr.length;
12
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
13
- return arr2;
14
- }
15
- function _array_with_holes(arr) {
16
- if (Array.isArray(arr)) return arr;
17
- }
18
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
19
- try {
20
- var info = gen[key](arg);
21
- var value = info.value;
22
- } catch (error) {
23
- reject(error);
24
- return;
25
- }
26
- if (info.done) resolve(value);
27
- else Promise.resolve(value).then(_next, _throw);
28
- }
29
- function _async_to_generator(fn) {
30
- return function() {
31
- var self = this, args = arguments;
32
- return new Promise(function(resolve, reject) {
33
- var gen = fn.apply(self, args);
34
- function _next(value) {
35
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
36
- }
37
- function _throw(err) {
38
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
39
- }
40
- _next(undefined);
41
- });
42
- };
43
- }
44
- function _iterable_to_array_limit(arr, i) {
45
- var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
46
- if (_i == null) return;
47
- var _arr = [];
48
- var _n = true;
49
- var _d = false;
50
- var _s, _e;
51
- try {
52
- for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
53
- _arr.push(_s.value);
54
- if (i && _arr.length === i) break;
55
- }
56
- } catch (err) {
57
- _d = true;
58
- _e = err;
59
- } finally{
60
- try {
61
- if (!_n && _i["return"] != null) _i["return"]();
62
- } finally{
63
- if (_d) throw _e;
64
- }
65
- }
66
- return _arr;
67
- }
68
- function _non_iterable_rest() {
69
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
70
- }
71
- function _sliced_to_array(arr, i) {
72
- return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
73
- }
74
- function _ts_generator(thisArg, body) {
75
- var f, y, t, _ = {
76
- label: 0,
77
- sent: function() {
78
- if (t[0] & 1) throw t[1];
79
- return t[1];
80
- },
81
- trys: [],
82
- ops: []
83
- }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
84
- return d(g, "next", {
85
- value: verb(0)
86
- }), d(g, "throw", {
87
- value: verb(1)
88
- }), d(g, "return", {
89
- value: verb(2)
90
- }), typeof Symbol === "function" && d(g, Symbol.iterator, {
91
- value: function() {
92
- return this;
93
- }
94
- }), g;
95
- function verb(n) {
96
- return function(v) {
97
- return step([
98
- n,
99
- v
100
- ]);
101
- };
102
- }
103
- function step(op) {
104
- if (f) throw new TypeError("Generator is already executing.");
105
- while(g && (g = 0, op[0] && (_ = 0)), _)try {
106
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
107
- if (y = 0, t) op = [
108
- op[0] & 2,
109
- t.value
110
- ];
111
- switch(op[0]){
112
- case 0:
113
- case 1:
114
- t = op;
115
- break;
116
- case 4:
117
- _.label++;
118
- return {
119
- value: op[1],
120
- done: false
121
- };
122
- case 5:
123
- _.label++;
124
- y = op[1];
125
- op = [
126
- 0
127
- ];
128
- continue;
129
- case 7:
130
- op = _.ops.pop();
131
- _.trys.pop();
132
- continue;
133
- default:
134
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
135
- _ = 0;
136
- continue;
137
- }
138
- if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
139
- _.label = op[1];
140
- break;
141
- }
142
- if (op[0] === 6 && _.label < t[1]) {
143
- _.label = t[1];
144
- t = op;
145
- break;
146
- }
147
- if (t && _.label < t[2]) {
148
- _.label = t[2];
149
- _.ops.push(op);
150
- break;
151
- }
152
- if (t[2]) _.ops.pop();
153
- _.trys.pop();
154
- continue;
155
- }
156
- op = body.call(thisArg, _);
157
- } catch (e) {
158
- op = [
159
- 6,
160
- e
161
- ];
162
- y = 0;
163
- } finally{
164
- f = t = 0;
165
- }
166
- if (op[0] & 5) throw op[1];
167
- return {
168
- value: op[0] ? op[1] : void 0,
169
- done: true
170
- };
171
- }
172
- }
173
- function _unsupported_iterable_to_array(o, minLen) {
174
- if (!o) return;
175
- if (typeof o === "string") return _array_like_to_array(o, minLen);
176
- var n = Object.prototype.toString.call(o).slice(8, -1);
177
- if (n === "Object" && o.constructor) n = o.constructor.name;
178
- if (n === "Map" || n === "Set") return Array.from(n);
179
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
180
- }
181
- /**
182
- * FIX: Protocol.close() doesn't clear pending timeouts
183
- *
184
- * BUG: The MCP SDK's Protocol.close() only closes the transport but does NOT
185
- * clear pending timeouts from the internal _timeoutInfo Map. This causes Node.js
186
- * to hang until timeouts fire (default 60 seconds).
187
- *
188
- * PATCH: Wrap Protocol.close() to clear all pending timeouts before closing.
189
- *
190
- * TO TEST IF STILL NEEDED:
191
- * 1. Comment out this patch
192
- * 2. Run: npm run test:unit
193
- * 3. If tests hang ~60 seconds after completing, bug still exists
194
- * 4. If tests exit promptly, SDK is fixed and this can be removed
195
- *
196
- * UPSTREAM: https://github.com/modelcontextprotocol/typescript-sdk/issues/XXX
197
- */ var originalClose = _protocol.Protocol.prototype.close;
198
- _protocol.Protocol.prototype.close = function() {
199
- return _async_to_generator(function() {
200
- var self, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, info;
201
- return _ts_generator(this, function(_state) {
202
- self = this;
203
- if (self._timeoutInfo) {
204
- _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
205
- try {
206
- for(_iterator = self._timeoutInfo[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
207
- _step_value = _sliced_to_array(_step.value, 2), info = _step_value[1];
208
- clearTimeout(info.timeoutId);
209
- }
210
- } catch (err) {
211
- _didIteratorError = true;
212
- _iteratorError = err;
213
- } finally{
214
- try {
215
- if (!_iteratorNormalCompletion && _iterator.return != null) {
216
- _iterator.return();
217
- }
218
- } finally{
219
- if (_didIteratorError) {
220
- throw _iteratorError;
221
- }
222
- }
223
- }
224
- self._timeoutInfo.clear();
225
- }
226
- return [
227
- 2,
228
- originalClose.call(this)
229
- ];
230
- });
231
- }).call(this);
232
- };
233
- /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/monkey-patches.ts"],"sourcesContent":["/**\n * Monkey patches for MCP SDK bugs\n *\n * These patches fix bugs in dependencies that haven't been fixed upstream yet.\n */\n\nimport { Protocol } from '@modelcontextprotocol/sdk/shared/protocol.js';\n\n/**\n * FIX: Protocol.close() doesn't clear pending timeouts\n *\n * BUG: The MCP SDK's Protocol.close() only closes the transport but does NOT\n * clear pending timeouts from the internal _timeoutInfo Map. This causes Node.js\n * to hang until timeouts fire (default 60 seconds).\n *\n * PATCH: Wrap Protocol.close() to clear all pending timeouts before closing.\n *\n * TO TEST IF STILL NEEDED:\n * 1. Comment out this patch\n * 2. Run: npm run test:unit\n * 3. If tests hang ~60 seconds after completing, bug still exists\n * 4. If tests exit promptly, SDK is fixed and this can be removed\n *\n * UPSTREAM: https://github.com/modelcontextprotocol/typescript-sdk/issues/XXX\n */\nconst originalClose = Protocol.prototype.close;\nProtocol.prototype.close = async function () {\n const self = this as unknown as { _timeoutInfo?: Map<unknown, { timeoutId: ReturnType<typeof setTimeout> }> };\n if (self._timeoutInfo) {\n for (const [, info] of self._timeoutInfo) {\n clearTimeout(info.timeoutId);\n }\n self._timeoutInfo.clear();\n }\n return originalClose.call(this);\n};\n"],"names":["originalClose","Protocol","prototype","close","self","info","_timeoutInfo","clearTimeout","timeoutId","clear","call"],"mappings":"AAAA;;;;CAIC;;;;wBAEwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEzB;;;;;;;;;;;;;;;;CAgBC,GACD,IAAMA,gBAAgBC,kBAAQ,CAACC,SAAS,CAACC,KAAK;AAC9CF,kBAAQ,CAACC,SAAS,CAACC,KAAK,GAAG;;YACnBC,MAEC,2BAAA,mBAAA,gBAAA,WAAA,oBAASC;;YAFVD,OAAO,IAAI;YACjB,IAAIA,KAAKE,YAAY,EAAE;gBAChB,kCAAA,2BAAA;;oBAAL,IAAK,YAAkBF,KAAKE,YAAY,uBAAnC,6BAAA,QAAA,yBAAA,iCAAqC;uDAArC,iBAASD;wBACZE,aAAaF,KAAKG,SAAS;oBAC7B;;oBAFK;oBAAA;;;6BAAA,6BAAA;4BAAA;;;4BAAA;kCAAA;;;;gBAGLJ,KAAKE,YAAY,CAACG,KAAK;YACzB;YACA;;gBAAOT,cAAcU,IAAI,CAAC,IAAI;;;IAChC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Monkey patches for MCP SDK bugs
3
- *
4
- * These patches fix bugs in dependencies that haven't been fixed upstream yet.
5
- */
6
- export {};
@@ -1,32 +0,0 @@
1
- /**
2
- * Monkey patches for MCP SDK bugs
3
- *
4
- * These patches fix bugs in dependencies that haven't been fixed upstream yet.
5
- */ import { Protocol } from '@modelcontextprotocol/sdk/shared/protocol.js';
6
- /**
7
- * FIX: Protocol.close() doesn't clear pending timeouts
8
- *
9
- * BUG: The MCP SDK's Protocol.close() only closes the transport but does NOT
10
- * clear pending timeouts from the internal _timeoutInfo Map. This causes Node.js
11
- * to hang until timeouts fire (default 60 seconds).
12
- *
13
- * PATCH: Wrap Protocol.close() to clear all pending timeouts before closing.
14
- *
15
- * TO TEST IF STILL NEEDED:
16
- * 1. Comment out this patch
17
- * 2. Run: npm run test:unit
18
- * 3. If tests hang ~60 seconds after completing, bug still exists
19
- * 4. If tests exit promptly, SDK is fixed and this can be removed
20
- *
21
- * UPSTREAM: https://github.com/modelcontextprotocol/typescript-sdk/issues/XXX
22
- */ const originalClose = Protocol.prototype.close;
23
- Protocol.prototype.close = async function() {
24
- const self = this;
25
- if (self._timeoutInfo) {
26
- for (const [, info] of self._timeoutInfo){
27
- clearTimeout(info.timeoutId);
28
- }
29
- self._timeoutInfo.clear();
30
- }
31
- return originalClose.call(this);
32
- };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/monkey-patches.ts"],"sourcesContent":["/**\n * Monkey patches for MCP SDK bugs\n *\n * These patches fix bugs in dependencies that haven't been fixed upstream yet.\n */\n\nimport { Protocol } from '@modelcontextprotocol/sdk/shared/protocol.js';\n\n/**\n * FIX: Protocol.close() doesn't clear pending timeouts\n *\n * BUG: The MCP SDK's Protocol.close() only closes the transport but does NOT\n * clear pending timeouts from the internal _timeoutInfo Map. This causes Node.js\n * to hang until timeouts fire (default 60 seconds).\n *\n * PATCH: Wrap Protocol.close() to clear all pending timeouts before closing.\n *\n * TO TEST IF STILL NEEDED:\n * 1. Comment out this patch\n * 2. Run: npm run test:unit\n * 3. If tests hang ~60 seconds after completing, bug still exists\n * 4. If tests exit promptly, SDK is fixed and this can be removed\n *\n * UPSTREAM: https://github.com/modelcontextprotocol/typescript-sdk/issues/XXX\n */\nconst originalClose = Protocol.prototype.close;\nProtocol.prototype.close = async function () {\n const self = this as unknown as { _timeoutInfo?: Map<unknown, { timeoutId: ReturnType<typeof setTimeout> }> };\n if (self._timeoutInfo) {\n for (const [, info] of self._timeoutInfo) {\n clearTimeout(info.timeoutId);\n }\n self._timeoutInfo.clear();\n }\n return originalClose.call(this);\n};\n"],"names":["Protocol","originalClose","prototype","close","self","_timeoutInfo","info","clearTimeout","timeoutId","clear","call"],"mappings":"AAAA;;;;CAIC,GAED,SAASA,QAAQ,QAAQ,+CAA+C;AAExE;;;;;;;;;;;;;;;;CAgBC,GACD,MAAMC,gBAAgBD,SAASE,SAAS,CAACC,KAAK;AAC9CH,SAASE,SAAS,CAACC,KAAK,GAAG;IACzB,MAAMC,OAAO,IAAI;IACjB,IAAIA,KAAKC,YAAY,EAAE;QACrB,KAAK,MAAM,GAAGC,KAAK,IAAIF,KAAKC,YAAY,CAAE;YACxCE,aAAaD,KAAKE,SAAS;QAC7B;QACAJ,KAAKC,YAAY,CAACI,KAAK;IACzB;IACA,OAAOR,cAAcS,IAAI,CAAC,IAAI;AAChC"}