@kortyx/mcp 0.2.9 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.0](https://github.com/kortyx-io/kortyx/compare/mcp-v0.2.10...mcp-v0.3.0) (2026-10-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * add shared SDK and Studio usage telemetry ([#313](https://github.com/kortyx-io/kortyx/issues/313)) ([7d5f0c0](https://github.com/kortyx-io/kortyx/commit/7d5f0c005bd7721dc6a529554e75c14573d76a0f))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **website:** reconcile credibility branch with current main ([60199f9](https://github.com/kortyx-io/kortyx/commit/60199f992242eb7c409a95bc7a6898d31bac601d))
14
+
15
+
16
+ ### Dependencies
17
+
18
+ * The following workspace dependencies were updated
19
+ * dependencies
20
+ * @kortyx/providers bumped to 0.9.2
21
+ * @kortyx/usage-telemetry bumped to 0.2.0
22
+
23
+ ## [0.2.10](https://github.com/kortyx-io/kortyx/compare/mcp-v0.2.9...mcp-v0.2.10) (2026-10-09)
24
+
25
+
26
+ ### Dependencies
27
+
28
+ * The following workspace dependencies were updated
29
+ * dependencies
30
+ * @kortyx/providers bumped to 0.9.1
31
+
3
32
  ## [0.2.9](https://github.com/kortyx-io/kortyx/compare/mcp-v0.2.8...mcp-v0.2.9) (2026-10-08)
4
33
 
5
34
 
package/dist/index.js CHANGED
@@ -26,6 +26,86 @@ var import_client = require("@modelcontextprotocol/sdk/client/index.js");
26
26
  var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
27
27
  var import_stdio = require("@modelcontextprotocol/sdk/client/stdio.js");
28
28
  var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
29
+
30
+ // src/usage.ts
31
+ var import_node = require("@kortyx/usage-telemetry/node");
32
+
33
+ // package.json
34
+ var package_default = {
35
+ name: "@kortyx/mcp",
36
+ version: "0.3.0",
37
+ private: false,
38
+ description: "MCP client tools for Kortyx.",
39
+ keywords: [
40
+ "ai",
41
+ "agent",
42
+ "agents",
43
+ "mcp",
44
+ "model-context-protocol",
45
+ "tools",
46
+ "kortyx"
47
+ ],
48
+ license: "Apache-2.0",
49
+ homepage: "https://kortyx.io/",
50
+ bugs: {
51
+ url: "https://github.com/kortyx-io/kortyx/issues"
52
+ },
53
+ author: "Kortyx (https://github.com/kortyx-io)",
54
+ main: "./dist/index.js",
55
+ types: "./dist/index.d.ts",
56
+ exports: {
57
+ ".": {
58
+ types: "./dist/index.d.ts",
59
+ default: "./dist/index.js"
60
+ }
61
+ },
62
+ files: [
63
+ "dist/**",
64
+ "README.md",
65
+ "CHANGELOG.md"
66
+ ],
67
+ scripts: {
68
+ build: "tsup",
69
+ predev: "tsc -p tsconfig.build.json",
70
+ dev: "tsc --watch",
71
+ lint: "biome check src test",
72
+ test: "vitest run --passWithNoTests && pnpm -s type-check",
73
+ coverage: "vitest run --coverage --passWithNoTests && pnpm -s type-check",
74
+ "type-check": "tsc --noEmit -p tsconfig.test.json"
75
+ },
76
+ dependencies: {
77
+ "@kortyx/providers": "workspace:*",
78
+ "@modelcontextprotocol/sdk": "catalog:",
79
+ "@kortyx/usage-telemetry": "workspace:*"
80
+ },
81
+ devDependencies: {
82
+ "@types/node": "catalog:",
83
+ turbo: "catalog:",
84
+ typescript: "catalog:",
85
+ tsup: "catalog:",
86
+ vitest: "catalog:"
87
+ },
88
+ sideEffects: false,
89
+ repository: {
90
+ type: "git",
91
+ url: "https://github.com/kortyx-io/kortyx.git",
92
+ directory: "packages/mcp"
93
+ },
94
+ publishConfig: {
95
+ access: "public"
96
+ }
97
+ };
98
+
99
+ // src/usage.ts
100
+ var client = () => (0, import_node.getUsageTelemetry)("mcp", package_default.version);
101
+ var usage = {
102
+ start: (...args) => client().start(...args),
103
+ feature: (...args) => client().feature(...args),
104
+ measure: (...args) => client().measure(...args),
105
+ flush: () => client().flush()
106
+ };
107
+
108
+ // src/index.ts
29
109
  var isTransport = (value) => typeof value.start === "function" && typeof value.send === "function";
30
110
  var createTransport = (transport) => {
31
111
  if (isTransport(transport)) return transport;
@@ -74,17 +154,19 @@ var stringifyContent = (content) => {
74
154
  }
75
155
  };
76
156
  var createMCPClient = async (args) => {
77
- const client = new import_client.Client({
157
+ const client2 = new import_client.Client({
78
158
  name: args.name ?? "kortyx",
79
159
  version: args.version ?? "0.1.0"
80
160
  });
81
161
  const transport = createTransport(args.transport);
82
- await client.connect(transport);
162
+ await usage.measure("sdk.mcp.connect", () => client2.connect(transport), {
163
+ transport: isTransport(args.transport) ? "custom" : args.transport.type
164
+ });
83
165
  let closed = false;
84
166
  const close = async () => {
85
167
  if (closed) return;
86
168
  closed = true;
87
- await client.close();
169
+ await usage.measure("sdk.mcp.close", () => client2.close());
88
170
  };
89
171
  return {
90
172
  async tools(toolArgs = {}) {
@@ -94,7 +176,10 @@ var createMCPClient = async (args) => {
94
176
  );
95
177
  }
96
178
  const include = new Set(toolArgs.include ?? []);
97
- const listed = await client.listTools();
179
+ const listed = await usage.measure(
180
+ "sdk.mcp.discover",
181
+ () => client2.listTools()
182
+ );
98
183
  const closeAfterUse = toolArgs.closeAfterUse ?? true;
99
184
  return listed.tools.filter((tool) => include.size === 0 || include.has(tool.name)).map(
100
185
  (mcpTool) => ({
@@ -117,7 +202,7 @@ var createMCPClient = async (args) => {
117
202
  `MCP client for tool "${mcpTool.name}" is already closed.`
118
203
  );
119
204
  }
120
- const result = await client.callTool(
205
+ const result = await client2.callTool(
121
206
  {
122
207
  name: mcpTool.name,
123
208
  arguments: input && typeof input === "object" && !Array.isArray(input) ? input : {}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { KortyxExecutableTool, KortyxToolResult } from \"@kortyx/providers\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\n\nexport type McpHttpTransportConfig = {\n type: \"http\";\n url: string | URL;\n headers?: Record<string, string> | undefined;\n fetch?: typeof fetch | undefined;\n};\n\nexport type McpSseTransportConfig = {\n type: \"sse\";\n url: string | URL;\n headers?: Record<string, string> | undefined;\n fetch?: typeof fetch | undefined;\n};\n\nexport type McpStdioTransportConfig = {\n type: \"stdio\";\n command: string;\n args?: string[] | undefined;\n env?: Record<string, string> | undefined;\n cwd?: string | undefined;\n};\n\nexport type McpTransportConfig =\n | McpHttpTransportConfig\n | McpSseTransportConfig\n | McpStdioTransportConfig\n | Transport;\n\nexport type CreateMCPClientArgs = {\n name?: string | undefined;\n version?: string | undefined;\n transport: McpTransportConfig;\n};\n\nexport type McpToolsArgs = {\n include?: string[] | undefined;\n closeAfterUse?: boolean | undefined;\n};\n\ntype McpToolExecutionContext = {\n toolCallId: string;\n abortSignal?: AbortSignal | undefined;\n};\n\nexport type MCPClient = {\n tools: (args?: McpToolsArgs) => Promise<KortyxExecutableTool[]>;\n close: () => Promise<void>;\n};\n\nconst isTransport = (value: McpTransportConfig): value is Transport =>\n typeof (value as Transport).start === \"function\" &&\n typeof (value as Transport).send === \"function\";\n\nconst createTransport = (transport: McpTransportConfig): Transport => {\n if (isTransport(transport)) return transport;\n\n if (transport.type === \"http\") {\n return new StreamableHTTPClientTransport(new URL(String(transport.url)), {\n ...(transport.headers || transport.fetch\n ? {\n requestInit: {\n ...(transport.headers ? { headers: transport.headers } : {}),\n },\n ...(transport.fetch ? { fetch: transport.fetch } : {}),\n }\n : {}),\n }) as unknown as Transport;\n }\n\n if (transport.type === \"sse\") {\n return new SSEClientTransport(new URL(String(transport.url)), {\n ...(transport.headers\n ? { requestInit: { headers: transport.headers } }\n : {}),\n ...(transport.fetch ? { fetch: transport.fetch } : {}),\n }) as unknown as Transport;\n }\n\n return new StdioClientTransport({\n command: transport.command,\n ...(transport.args ? { args: transport.args } : {}),\n ...(transport.env ? { env: transport.env } : {}),\n ...(transport.cwd ? { cwd: transport.cwd } : {}),\n }) as unknown as Transport;\n};\n\nconst stringifyContent = (content: unknown): string => {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .map((item) => {\n if (\n item &&\n typeof item === \"object\" &&\n \"type\" in item &&\n (item as { type?: unknown }).type === \"text\" &&\n typeof (item as { text?: unknown }).text === \"string\"\n ) {\n return (item as { text: string }).text;\n }\n try {\n return JSON.stringify(item);\n } catch {\n return String(item);\n }\n })\n .join(\"\\n\");\n }\n if (content === undefined || content === null) return \"\";\n try {\n return JSON.stringify(content);\n } catch {\n return String(content);\n }\n};\n\nexport const createMCPClient = async (\n args: CreateMCPClientArgs,\n): Promise<MCPClient> => {\n const client = new Client({\n name: args.name ?? \"kortyx\",\n version: args.version ?? \"0.1.0\",\n });\n const transport = createTransport(args.transport);\n await client.connect(transport);\n\n let closed = false;\n const close = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n await client.close();\n };\n\n return {\n async tools(toolArgs = {}) {\n if (closed) {\n throw new Error(\n \"MCP client is already closed. Create a new client before listing tools.\",\n );\n }\n\n const include = new Set(toolArgs.include ?? []);\n const listed = await client.listTools();\n const closeAfterUse = toolArgs.closeAfterUse ?? true;\n\n return listed.tools\n .filter((tool) => include.size === 0 || include.has(tool.name))\n .map(\n (mcpTool): KortyxExecutableTool => ({\n name: mcpTool.name,\n ...(mcpTool.title ? { title: mcpTool.title } : {}),\n ...(mcpTool.description\n ? { description: mcpTool.description }\n : {}),\n inputSchema: mcpTool.inputSchema,\n ...(mcpTool.outputSchema\n ? { outputSchema: mcpTool.outputSchema }\n : {}),\n ...(mcpTool.annotations\n ? { annotations: mcpTool.annotations }\n : {}),\n metadata: {\n source: \"mcp\",\n ...(mcpTool._meta ? { mcp: mcpTool._meta } : {}),\n },\n closeAfterUse,\n source: \"mcp\",\n close,\n execute: async (\n input: unknown,\n context: McpToolExecutionContext,\n ): Promise<KortyxToolResult> => {\n if (closed) {\n throw new Error(\n `MCP client for tool \"${mcpTool.name}\" is already closed.`,\n );\n }\n const result = await client.callTool(\n {\n name: mcpTool.name,\n arguments:\n input && typeof input === \"object\" && !Array.isArray(input)\n ? (input as Record<string, unknown>)\n : {},\n },\n undefined,\n context.abortSignal\n ? { signal: context.abortSignal }\n : undefined,\n );\n\n const isError =\n \"isError\" in result && typeof result.isError === \"boolean\"\n ? result.isError\n : undefined;\n\n return {\n toolCallId: context.toolCallId,\n name: mcpTool.name,\n content: stringifyContent(\n \"content\" in result ? result.content : result,\n ),\n ...(\"structuredContent\" in result &&\n result.structuredContent !== undefined\n ? { structuredContent: result.structuredContent }\n : {}),\n ...(isError !== undefined ? { isError } : {}),\n raw: result,\n };\n },\n }),\n );\n },\n close,\n };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/usage.ts","../package.json"],"sourcesContent":["import type { KortyxExecutableTool, KortyxToolResult } from \"@kortyx/providers\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { usage } from \"./usage\";\n\nexport type McpHttpTransportConfig = {\n type: \"http\";\n url: string | URL;\n headers?: Record<string, string> | undefined;\n fetch?: typeof fetch | undefined;\n};\n\nexport type McpSseTransportConfig = {\n type: \"sse\";\n url: string | URL;\n headers?: Record<string, string> | undefined;\n fetch?: typeof fetch | undefined;\n};\n\nexport type McpStdioTransportConfig = {\n type: \"stdio\";\n command: string;\n args?: string[] | undefined;\n env?: Record<string, string> | undefined;\n cwd?: string | undefined;\n};\n\nexport type McpTransportConfig =\n | McpHttpTransportConfig\n | McpSseTransportConfig\n | McpStdioTransportConfig\n | Transport;\n\nexport type CreateMCPClientArgs = {\n name?: string | undefined;\n version?: string | undefined;\n transport: McpTransportConfig;\n};\n\nexport type McpToolsArgs = {\n include?: string[] | undefined;\n closeAfterUse?: boolean | undefined;\n};\n\ntype McpToolExecutionContext = {\n toolCallId: string;\n abortSignal?: AbortSignal | undefined;\n};\n\nexport type MCPClient = {\n tools: (args?: McpToolsArgs) => Promise<KortyxExecutableTool[]>;\n close: () => Promise<void>;\n};\n\nconst isTransport = (value: McpTransportConfig): value is Transport =>\n typeof (value as Transport).start === \"function\" &&\n typeof (value as Transport).send === \"function\";\n\nconst createTransport = (transport: McpTransportConfig): Transport => {\n if (isTransport(transport)) return transport;\n\n if (transport.type === \"http\") {\n return new StreamableHTTPClientTransport(new URL(String(transport.url)), {\n ...(transport.headers || transport.fetch\n ? {\n requestInit: {\n ...(transport.headers ? { headers: transport.headers } : {}),\n },\n ...(transport.fetch ? { fetch: transport.fetch } : {}),\n }\n : {}),\n }) as unknown as Transport;\n }\n\n if (transport.type === \"sse\") {\n return new SSEClientTransport(new URL(String(transport.url)), {\n ...(transport.headers\n ? { requestInit: { headers: transport.headers } }\n : {}),\n ...(transport.fetch ? { fetch: transport.fetch } : {}),\n }) as unknown as Transport;\n }\n\n return new StdioClientTransport({\n command: transport.command,\n ...(transport.args ? { args: transport.args } : {}),\n ...(transport.env ? { env: transport.env } : {}),\n ...(transport.cwd ? { cwd: transport.cwd } : {}),\n }) as unknown as Transport;\n};\n\nconst stringifyContent = (content: unknown): string => {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .map((item) => {\n if (\n item &&\n typeof item === \"object\" &&\n \"type\" in item &&\n (item as { type?: unknown }).type === \"text\" &&\n typeof (item as { text?: unknown }).text === \"string\"\n ) {\n return (item as { text: string }).text;\n }\n try {\n return JSON.stringify(item);\n } catch {\n return String(item);\n }\n })\n .join(\"\\n\");\n }\n if (content === undefined || content === null) return \"\";\n try {\n return JSON.stringify(content);\n } catch {\n return String(content);\n }\n};\n\nexport const createMCPClient = async (\n args: CreateMCPClientArgs,\n): Promise<MCPClient> => {\n const client = new Client({\n name: args.name ?? \"kortyx\",\n version: args.version ?? \"0.1.0\",\n });\n const transport = createTransport(args.transport);\n await usage.measure(\"sdk.mcp.connect\", () => client.connect(transport), {\n transport: isTransport(args.transport) ? \"custom\" : args.transport.type,\n });\n\n let closed = false;\n const close = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n await usage.measure(\"sdk.mcp.close\", () => client.close());\n };\n\n return {\n async tools(toolArgs = {}) {\n if (closed) {\n throw new Error(\n \"MCP client is already closed. Create a new client before listing tools.\",\n );\n }\n\n const include = new Set(toolArgs.include ?? []);\n const listed = await usage.measure(\"sdk.mcp.discover\", () =>\n client.listTools(),\n );\n const closeAfterUse = toolArgs.closeAfterUse ?? true;\n\n return listed.tools\n .filter((tool) => include.size === 0 || include.has(tool.name))\n .map(\n (mcpTool): KortyxExecutableTool => ({\n name: mcpTool.name,\n ...(mcpTool.title ? { title: mcpTool.title } : {}),\n ...(mcpTool.description\n ? { description: mcpTool.description }\n : {}),\n inputSchema: mcpTool.inputSchema,\n ...(mcpTool.outputSchema\n ? { outputSchema: mcpTool.outputSchema }\n : {}),\n ...(mcpTool.annotations\n ? { annotations: mcpTool.annotations }\n : {}),\n metadata: {\n source: \"mcp\",\n ...(mcpTool._meta ? { mcp: mcpTool._meta } : {}),\n },\n closeAfterUse,\n source: \"mcp\",\n close,\n execute: async (\n input: unknown,\n context: McpToolExecutionContext,\n ): Promise<KortyxToolResult> => {\n if (closed) {\n throw new Error(\n `MCP client for tool \"${mcpTool.name}\" is already closed.`,\n );\n }\n const result = await client.callTool(\n {\n name: mcpTool.name,\n arguments:\n input && typeof input === \"object\" && !Array.isArray(input)\n ? (input as Record<string, unknown>)\n : {},\n },\n undefined,\n context.abortSignal\n ? { signal: context.abortSignal }\n : undefined,\n );\n\n const isError =\n \"isError\" in result && typeof result.isError === \"boolean\"\n ? result.isError\n : undefined;\n\n return {\n toolCallId: context.toolCallId,\n name: mcpTool.name,\n content: stringifyContent(\n \"content\" in result ? result.content : result,\n ),\n ...(\"structuredContent\" in result &&\n result.structuredContent !== undefined\n ? { structuredContent: result.structuredContent }\n : {}),\n ...(isError !== undefined ? { isError } : {}),\n raw: result,\n };\n },\n }),\n );\n },\n close,\n };\n};\n","import type { UsageTelemetry } from \"@kortyx/usage-telemetry\";\nimport { getUsageTelemetry } from \"@kortyx/usage-telemetry/node\";\nimport packageJson from \"../package.json\";\n\nconst client = () => getUsageTelemetry(\"mcp\", packageJson.version);\nexport const usage: Pick<\n UsageTelemetry,\n \"start\" | \"feature\" | \"measure\" | \"flush\"\n> = {\n start: (...args) => client().start(...args),\n feature: (...args) => client().feature(...args),\n measure: (...args) => client().measure(...args),\n flush: () => client().flush(),\n};\n","{\n \"name\": \"@kortyx/mcp\",\n \"version\": \"0.3.0\",\n \"private\": false,\n \"description\": \"MCP client tools for Kortyx.\",\n \"keywords\": [\n \"ai\",\n \"agent\",\n \"agents\",\n \"mcp\",\n \"model-context-protocol\",\n \"tools\",\n \"kortyx\"\n ],\n \"license\": \"Apache-2.0\",\n \"homepage\": \"https://kortyx.io/\",\n \"bugs\": {\n \"url\": \"https://github.com/kortyx-io/kortyx/issues\"\n },\n \"author\": \"Kortyx (https://github.com/kortyx-io)\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist/**\",\n \"README.md\",\n \"CHANGELOG.md\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"predev\": \"tsc -p tsconfig.build.json\",\n \"dev\": \"tsc --watch\",\n \"lint\": \"biome check src test\",\n \"test\": \"vitest run --passWithNoTests && pnpm -s type-check\",\n \"coverage\": \"vitest run --coverage --passWithNoTests && pnpm -s type-check\",\n \"type-check\": \"tsc --noEmit -p tsconfig.test.json\"\n },\n \"dependencies\": {\n \"@kortyx/providers\": \"workspace:*\",\n \"@modelcontextprotocol/sdk\": \"catalog:\",\n \"@kortyx/usage-telemetry\": \"workspace:*\"\n },\n \"devDependencies\": {\n \"@types/node\": \"catalog:\",\n \"turbo\": \"catalog:\",\n \"typescript\": \"catalog:\",\n \"tsup\": \"catalog:\",\n \"vitest\": \"catalog:\"\n },\n \"sideEffects\": false,\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/kortyx-io/kortyx.git\",\n \"directory\": \"packages/mcp\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n"],"mappings":"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","names":["client"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kortyx/mcp",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "MCP client tools for Kortyx.",
6
6
  "keywords": [
@@ -33,7 +33,8 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.31.0",
36
- "@kortyx/providers": "0.9.0"
36
+ "@kortyx/providers": "0.9.2",
37
+ "@kortyx/usage-telemetry": "0.2.0"
37
38
  },
38
39
  "devDependencies": {
39
40
  "@types/node": "^20",