@kya-os/mcp-i 1.2.6 → 1.2.8

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.
@@ -15,7 +15,7 @@ class StdioTransport {
15
15
  try {
16
16
  this.mcpServer.connect(this.transport);
17
17
  if (this.debug) {
18
- console.log("[STDIO] MCP Server running with STDIO transport");
18
+ console.error("[STDIO] MCP Server running with STDIO transport");
19
19
  }
20
20
  this.setupShutdownHandlers();
21
21
  }
@@ -29,7 +29,7 @@ class StdioTransport {
29
29
  setupShutdownHandlers() {
30
30
  const shutdownHandler = () => {
31
31
  if (this.debug) {
32
- console.log("[STDIO] Shutting down STDIO transport");
32
+ console.error("[STDIO] Shutting down STDIO transport");
33
33
  }
34
34
  process.exit(0);
35
35
  };
@@ -38,7 +38,7 @@ class StdioTransport {
38
38
  }
39
39
  shutdown() {
40
40
  if (this.debug) {
41
- console.log("[STDIO] Shutting down STDIO transport");
41
+ console.error("[STDIO] Shutting down STDIO transport");
42
42
  }
43
43
  process.exit(0);
44
44
  }
@@ -1,19 +1,21 @@
1
1
  import { Server as McpServer } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { Implementation } from "@modelcontextprotocol/sdk/types.js";
2
3
  export type ToolFile = {
3
4
  metadata: unknown;
4
5
  schema: unknown;
5
6
  default: (args: Record<string, unknown>) => Promise<unknown> | unknown;
6
7
  };
7
8
  export declare const injectedTools: Record<string, () => Promise<ToolFile>>;
8
- export declare const INJECTED_CONFIG: {
9
- readonly name: "MCP Server";
10
- readonly version: "0.0.1";
11
- readonly capabilities: {
12
- readonly tools: {
13
- readonly listChanged: true;
14
- };
9
+ export declare const SERVER_INFO: Implementation;
10
+ export declare const SERVER_CAPABILITIES: {
11
+ capabilities: {
12
+ tools: {};
15
13
  };
16
14
  };
15
+ declare global {
16
+ var __MCPI_SERVER_INSTANCE__: McpServer | undefined;
17
+ var __MCPI_SERVER_CREATED__: boolean | undefined;
18
+ }
17
19
  /** Loads tools and injects them into the server */
18
20
  export declare function configureServer(server: McpServer, toolModules: Map<string, ToolFile>): Promise<McpServer>;
19
21
  export declare function loadTools(): readonly [Promise<void>[], Map<string, ToolFile>];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.INJECTED_CONFIG = exports.injectedTools = void 0;
3
+ exports.SERVER_CAPABILITIES = exports.SERVER_INFO = exports.injectedTools = void 0;
4
4
  exports.configureServer = configureServer;
5
5
  exports.loadTools = loadTools;
6
6
  exports.createServer = createServer;
@@ -8,32 +8,73 @@ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
8
8
  const tools_1 = require("./tools");
9
9
  // @ts-expect-error: injected by compiler
10
10
  exports.injectedTools = INJECTED_TOOLS;
11
- exports.INJECTED_CONFIG = {
12
- // TODO get from project config
11
+ // Parse identity config from injected variable
12
+ // @ts-expect-error: injected by compiler
13
+ const rawIdentityConfig = typeof IDENTITY_CONFIG !== "undefined" ? IDENTITY_CONFIG : undefined;
14
+ const identityConfig = rawIdentityConfig
15
+ ? JSON.parse(rawIdentityConfig)
16
+ : undefined;
17
+ // Server info (first parameter to Server constructor)
18
+ exports.SERVER_INFO = {
13
19
  name: "MCP Server",
14
20
  version: "0.0.1",
21
+ };
22
+ // Server capabilities (second parameter to Server constructor)
23
+ exports.SERVER_CAPABILITIES = {
15
24
  capabilities: {
16
- tools: {
17
- listChanged: true,
18
- },
25
+ tools: {},
19
26
  },
20
27
  };
28
+ if (typeof global !== 'undefined') {
29
+ global.__MCPI_SERVER_CREATED__ = global.__MCPI_SERVER_CREATED__ || false;
30
+ }
21
31
  /** Loads tools and injects them into the server */
22
32
  async function configureServer(server, toolModules) {
23
- (0, tools_1.addToolsToServer)(server, toolModules);
33
+ await (0, tools_1.addToolsToServer)(server, toolModules, identityConfig);
24
34
  // TODO: implement addResourcesToServer, addPromptsToServer
25
35
  return server;
26
36
  }
27
37
  function loadTools() {
28
38
  const toolModules = new Map();
29
- const toolPromises = Object.keys(exports.injectedTools).map((path) => exports.injectedTools[path]().then((toolModule) => {
39
+ // Debug: log what tools are being injected
40
+ const toolPaths = Object.keys(exports.injectedTools);
41
+ console.error("[loadTools] Injected tool paths:", toolPaths);
42
+ const toolPromises = toolPaths.map((path) => exports.injectedTools[path]().then((toolModule) => {
43
+ console.error("[loadTools] Loaded tool from path:", path);
30
44
  toolModules.set(path, toolModule);
31
45
  }));
32
46
  return [toolPromises, toolModules];
33
47
  }
34
48
  async function createServer() {
35
- const server = new index_js_1.Server(exports.INJECTED_CONFIG);
49
+ console.error("[createServer] Starting server creation");
50
+ // Guard against double initialization using global scope
51
+ // This ensures singleton even if webpack creates multiple module instances
52
+ if (typeof global !== 'undefined' && global.__MCPI_SERVER_CREATED__) {
53
+ console.error("[createServer] Server already exists, returning cached instance");
54
+ if (global.__MCPI_SERVER_INSTANCE__) {
55
+ return global.__MCPI_SERVER_INSTANCE__;
56
+ }
57
+ }
58
+ console.error("[createServer] Creating new McpServer");
59
+ console.error("[createServer] SERVER_INFO constant:", JSON.stringify(exports.SERVER_INFO));
60
+ console.error("[createServer] SERVER_CAPABILITIES constant:", JSON.stringify(exports.SERVER_CAPABILITIES));
61
+ console.error("[createServer] Calling: new McpServer(SERVER_INFO, SERVER_CAPABILITIES)");
62
+ const server = new index_js_1.Server(exports.SERVER_INFO, exports.SERVER_CAPABILITIES);
63
+ console.error("[createServer] Server created successfully");
64
+ // Debug: Verify what the server actually received
65
+ const serverAny = server;
66
+ console.error("[createServer] Actual server._serverInfo:", JSON.stringify(serverAny._serverInfo || "undefined"));
67
+ console.error("[createServer] Actual server._capabilities:", JSON.stringify(serverAny._capabilities || "undefined"));
68
+ console.error("[createServer] Loading tools...");
36
69
  const [toolPromises, toolModules] = loadTools();
37
70
  await Promise.all(toolPromises);
38
- return configureServer(server, toolModules);
71
+ console.error("[createServer] Tools loaded, configuring server");
72
+ const configuredServer = await configureServer(server, toolModules);
73
+ console.error("[createServer] Server configured successfully");
74
+ // Store in global scope
75
+ if (typeof global !== 'undefined') {
76
+ global.__MCPI_SERVER_CREATED__ = true;
77
+ global.__MCPI_SERVER_INSTANCE__ = configuredServer;
78
+ }
79
+ return configuredServer;
39
80
  }
@@ -1,8 +1,25 @@
1
1
  import { Server as McpServer } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { ZodTypeAny } from "zod";
3
3
  import { ToolFile } from "./server";
4
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
5
+ import { DetachedProof } from "@kya-os/contracts/proof";
4
6
  export type ZodRawShape = {
5
7
  [k: string]: ZodTypeAny;
6
8
  };
9
+ export type MCPICallToolResult = CallToolResult & {
10
+ _meta?: {
11
+ proof?: DetachedProof;
12
+ [key: string]: unknown;
13
+ };
14
+ };
15
+ declare global {
16
+ var __MCPI_HANDLERS_REGISTERED__: boolean | undefined;
17
+ }
7
18
  /** Loads tools and injects them into the server */
8
- export declare function addToolsToServer(server: McpServer, toolModules: Map<string, ToolFile>): McpServer;
19
+ export declare function addToolsToServer(server: McpServer, toolModules: Map<string, ToolFile>, identityConfig?: {
20
+ enabled: boolean;
21
+ debug?: boolean;
22
+ environment?: string;
23
+ devIdentityPath?: string;
24
+ privacyMode?: boolean;
25
+ }): Promise<McpServer>;
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addToolsToServer = addToolsToServer;
4
4
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
5
+ const proof_1 = require("../proof");
6
+ const identity_1 = require("../identity");
5
7
  /** Validates if a value is a valid Zod schema object */
6
8
  function isZodRawShape(value) {
7
9
  if (typeof value !== "object" || value === null) {
@@ -22,8 +24,43 @@ function pathToName(path) {
22
24
  const fileName = path.split("/").pop() || path;
23
25
  return fileName.replace(/\.[^/.]+$/, "");
24
26
  }
27
+ if (typeof global !== 'undefined') {
28
+ global.__MCPI_HANDLERS_REGISTERED__ = global.__MCPI_HANDLERS_REGISTERED__ || false;
29
+ }
25
30
  /** Loads tools and injects them into the server */
26
- function addToolsToServer(server, toolModules) {
31
+ async function addToolsToServer(server, toolModules, identityConfig) {
32
+ // Guard against double registration using global scope
33
+ // Set this IMMEDIATELY to prevent race conditions
34
+ if (typeof global !== 'undefined') {
35
+ if (global.__MCPI_HANDLERS_REGISTERED__) {
36
+ console.error("[MCPI] Handlers already registered, skipping duplicate registration");
37
+ return server;
38
+ }
39
+ // Mark as registered RIGHT NOW before doing anything else
40
+ global.__MCPI_HANDLERS_REGISTERED__ = true;
41
+ }
42
+ console.error("[MCPI] Registering handlers for the first time");
43
+ // Initialize identity manager if identity is enabled
44
+ let identityManager = null;
45
+ if (identityConfig?.enabled) {
46
+ try {
47
+ identityManager = new identity_1.IdentityManager({
48
+ environment: identityConfig.environment ||
49
+ "development",
50
+ devIdentityPath: identityConfig.devIdentityPath,
51
+ });
52
+ // Ensure identity exists (loads or generates it)
53
+ const identity = await identityManager.ensureIdentity();
54
+ if (identityConfig.debug) {
55
+ console.error(`[MCPI] Identity enabled - DID: ${identity.did}`);
56
+ console.error(`[MCPI] Identity path: ${identityConfig.devIdentityPath || '.mcpi/identity.json'}`);
57
+ }
58
+ }
59
+ catch (error) {
60
+ console.error("[MCPI] Failed to initialize identity:", error);
61
+ // Continue without identity if initialization fails
62
+ }
63
+ }
27
64
  // Collect all tools and their handlers
28
65
  const tools = [];
29
66
  const toolHandlers = new Map();
@@ -67,6 +104,8 @@ function addToolsToServer(server, toolModules) {
67
104
  tools.push(tool);
68
105
  toolHandlers.set(toolConfig.name, handler);
69
106
  });
107
+ // Debug: log server state before registering handler
108
+ console.error("[MCPI] About to register tools/list handler");
70
109
  // Register tools/list handler
71
110
  server.setRequestHandler(types_js_1.ListToolsRequestSchema, async (request) => {
72
111
  return {
@@ -89,8 +128,10 @@ function addToolsToServer(server, toolModules) {
89
128
  };
90
129
  }
91
130
  try {
131
+ // Execute the tool handler
92
132
  const result = await handler(args || {});
93
- return {
133
+ // Build base response
134
+ const baseResponse = {
94
135
  content: [
95
136
  {
96
137
  type: "text",
@@ -98,6 +139,55 @@ function addToolsToServer(server, toolModules) {
98
139
  },
99
140
  ],
100
141
  };
142
+ // If identity is enabled, generate cryptographic proof
143
+ if (identityManager) {
144
+ try {
145
+ // Ensure identity exists
146
+ const identity = await identityManager.ensureIdentity();
147
+ // Create a session context for this request
148
+ const toolRequest = {
149
+ method: name,
150
+ params: args || {},
151
+ };
152
+ const toolResponse = {
153
+ data: result,
154
+ };
155
+ // Create a session context for standalone tool calls
156
+ // In a full implementation, this would use proper handshake
157
+ // TODO: Use proper handshake
158
+ const timestamp = Math.floor(Date.now() / 1000);
159
+ const session = {
160
+ sessionId: `tool-${Date.now()}`,
161
+ nonce: `${Date.now()}`,
162
+ audience: "client",
163
+ createdAt: timestamp,
164
+ timestamp,
165
+ lastActivity: timestamp,
166
+ ttlMinutes: 30,
167
+ };
168
+ // Generate proof using the proof generator
169
+ const proofGen = new proof_1.ProofGenerator(identity);
170
+ const proof = await proofGen.generateProof(toolRequest, toolResponse, session);
171
+ if (identityConfig?.debug) {
172
+ console.error(`[MCPI] Generated proof for tool "${name}" - DID: ${proof.meta.did}`);
173
+ }
174
+ // Return response with proof metadata
175
+ return {
176
+ ...baseResponse,
177
+ _meta: {
178
+ proof,
179
+ },
180
+ };
181
+ }
182
+ catch (proofError) {
183
+ if (identityConfig?.debug) {
184
+ console.error(`[MCPI] Failed to generate proof for tool "${name}":`, proofError);
185
+ }
186
+ // Return base response without proof if generation fails
187
+ return baseResponse;
188
+ }
189
+ }
190
+ return baseResponse;
101
191
  }
102
192
  catch (error) {
103
193
  return {
@@ -111,5 +201,6 @@ function addToolsToServer(server, toolModules) {
111
201
  };
112
202
  }
113
203
  });
204
+ console.error("[MCPI] Handlers registered successfully");
114
205
  return server;
115
206
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/mcp-i",
3
- "version": "1.2.6",
3
+ "version": "1.2.8",
4
4
  "description": "The TypeScript MCP framework with identity features built-in",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",