@phake/mcp 0.0.6 → 0.0.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.
package/README.md CHANGED
@@ -125,20 +125,16 @@ const greetTool = defineTool({
125
125
  inputSchema: z.object({
126
126
  name: z.string().describe("Name to greet"),
127
127
  }),
128
- outputSchema: {
128
+ outputSchema: z.object({
129
129
  message: z.string().describe("The greeting message"),
130
- },
130
+ }),
131
131
  annotations: {
132
132
  readOnlyHint: true,
133
133
  destructiveHint: false,
134
134
  idempotentHint: true,
135
135
  },
136
- handler: async (args, context) => {
137
- const message = `Hello, ${args.name}!`;
138
- return {
139
- content: [{ type: "text", text: message }],
140
- structuredContent: { message },
141
- };
136
+ handler: async (args) => {
137
+ return { message: `Hello, ${args.name}!` };
142
138
  },
143
139
  });
144
140
  ```
@@ -150,8 +146,8 @@ const greetTool = defineTool({
150
146
  | `name` | `string` | Yes | Unique tool identifier |
151
147
  | `description` | `string` | Yes | Description shown to the LLM |
152
148
  | `inputSchema` | `ZodObject` | Yes | Zod schema for input validation |
153
- | `outputSchema` | `ZodRawShape` | No | Zod schema for structured output |
154
- | `handler` | `function` | Yes | `(args, context) => Promise<ToolResult>` |
149
+ | `outputSchema` | `ZodRawShape \| ZodObject` | No | Zod schema for structured output |
150
+ | `handler` | `function` | Yes | `(args, context) => Promise<ToolResult \| Record<string, unknown>>` |
155
151
  | `requiresAuth` | `boolean` | No | Reject calls without a provider token |
156
152
  | `title` | `string` | No | Human-readable display title |
157
153
  | `annotations` | `object` | No | MCP hints (`readOnlyHint`, `destructiveHint`, etc.) |
@@ -170,10 +166,7 @@ const profileTool = defineTool({
170
166
  const response = await fetch("https://api.example.com/me", {
171
167
  headers: context.resolvedHeaders,
172
168
  });
173
- const data = await response.json();
174
- return {
175
- content: [{ type: "text", text: JSON.stringify(data) }],
176
- };
169
+ return await response.json();
177
170
  },
178
171
  });
179
172
  ```
@@ -976,20 +976,47 @@ function toProviderTokens(info) {
976
976
  }
977
977
 
978
978
  // src/shared/tools/types.ts
979
+ import { z } from "zod";
979
980
  function assertProviderToken(context) {
980
981
  if (!context.providerToken) {
981
982
  throw new Error("Authentication required");
982
983
  }
983
984
  }
985
+ function normalizeOutputSchema(schema) {
986
+ if (schema instanceof z.ZodObject) {
987
+ return schema.shape;
988
+ }
989
+ return schema;
990
+ }
991
+ function isToolResult(value) {
992
+ return typeof value === "object" && value !== null && "content" in value && Array.isArray(value.content);
993
+ }
984
994
  function defineTool(def) {
985
- return def;
995
+ if (def.outputSchema) {
996
+ def.outputSchema = normalizeOutputSchema(def.outputSchema);
997
+ }
998
+ const originalHandler = def.handler;
999
+ return {
1000
+ ...def,
1001
+ handler: async (args, context) => {
1002
+ const result = await originalHandler(args, context);
1003
+ if (isToolResult(result))
1004
+ return result;
1005
+ return {
1006
+ content: [
1007
+ { type: "text", text: JSON.stringify(result, null, 2) }
1008
+ ],
1009
+ structuredContent: result
1010
+ };
1011
+ }
1012
+ };
986
1013
  }
987
1014
 
988
1015
  // src/shared/tools/echo.ts
989
- import { z } from "zod";
990
- var echoInputSchema = z.object({
991
- message: z.string().min(1).describe("Message to echo back"),
992
- uppercase: z.boolean().optional().describe("Convert message to uppercase")
1016
+ import { z as z2 } from "zod";
1017
+ var echoInputSchema = z2.object({
1018
+ message: z2.string().min(1).describe("Message to echo back"),
1019
+ uppercase: z2.boolean().optional().describe("Convert message to uppercase")
993
1020
  });
994
1021
  var echoTool = defineTool({
995
1022
  name: "echo",
@@ -997,8 +1024,8 @@ var echoTool = defineTool({
997
1024
  description: "Echo back a message, optionally transformed",
998
1025
  inputSchema: echoInputSchema,
999
1026
  outputSchema: {
1000
- echoed: z.string().describe("The echoed message"),
1001
- length: z.number().describe("Message length")
1027
+ echoed: z2.string().describe("The echoed message"),
1028
+ length: z2.number().describe("Message length")
1002
1029
  },
1003
1030
  annotations: {
1004
1031
  title: "Echo Message",
@@ -1022,9 +1049,9 @@ var echoTool = defineTool({
1022
1049
  });
1023
1050
 
1024
1051
  // src/shared/tools/health.ts
1025
- import { z as z2 } from "zod";
1026
- var healthInputSchema = z2.object({
1027
- verbose: z2.boolean().optional().describe("Include additional runtime details")
1052
+ import { z as z3 } from "zod";
1053
+ var healthInputSchema = z3.object({
1054
+ verbose: z3.boolean().optional().describe("Include additional runtime details")
1028
1055
  });
1029
1056
  var healthTool = defineTool({
1030
1057
  name: "health",
@@ -1032,10 +1059,10 @@ var healthTool = defineTool({
1032
1059
  description: "Check server health, uptime, and runtime information",
1033
1060
  inputSchema: healthInputSchema,
1034
1061
  outputSchema: {
1035
- status: z2.string().describe("Server status"),
1036
- timestamp: z2.number().describe("Current timestamp"),
1037
- runtime: z2.string().describe("Runtime environment"),
1038
- uptime: z2.number().optional().describe("Uptime in seconds (if available)")
1062
+ status: z3.string().describe("Server status"),
1063
+ timestamp: z3.number().describe("Current timestamp"),
1064
+ runtime: z3.string().describe("Runtime environment"),
1065
+ uptime: z3.number().optional().describe("Uptime in seconds (if available)")
1039
1066
  },
1040
1067
  annotations: {
1041
1068
  title: "Server Health Check",
@@ -1159,8 +1186,8 @@ function getSchemaShape(schema) {
1159
1186
  if ("shape" in schema && typeof schema.shape === "object") {
1160
1187
  return schema.shape;
1161
1188
  }
1162
- if ("_def" in schema && schema._def && typeof schema._def === "object") {
1163
- const def = schema._def;
1189
+ if ("def" in schema && schema.def && typeof schema.def === "object") {
1190
+ const def = schema.def;
1164
1191
  if (def.schema) {
1165
1192
  return getSchemaShape(def.schema);
1166
1193
  }
@@ -1229,10 +1256,16 @@ async function executeSharedTool(name, args, context, tools) {
1229
1256
  isError: true
1230
1257
  };
1231
1258
  }
1259
+ const err = error instanceof Error ? error : new Error(String(error));
1260
+ logger.error("execute_tool", {
1261
+ message: `Tool execution failed: ${err.message}`,
1262
+ tool: name,
1263
+ stack: err.stack
1264
+ });
1265
+ const message = `${err.name}: ${err.message}${err.stack ? `
1266
+ ${err.stack}` : ""}`;
1232
1267
  return {
1233
- content: [
1234
- { type: "text", text: `Tool error: ${error.message}` }
1235
- ],
1268
+ content: [{ type: "text", text: `Tool error: ${message}` }],
1236
1269
  isError: true
1237
1270
  };
1238
1271
  }
@@ -1277,7 +1310,7 @@ function registerTools(server, contextResolver) {
1277
1310
  }
1278
1311
 
1279
1312
  // src/shared/mcp/dispatcher.ts
1280
- import { z as z3 } from "zod";
1313
+ import { z as z4 } from "zod";
1281
1314
 
1282
1315
  // src/runtime/node/capabilities.ts
1283
1316
  function buildCapabilities() {
@@ -1350,12 +1383,13 @@ async function handleToolsList(ctx) {
1350
1383
  const tools = (ctx.tools ?? sharedTools).map((tool) => ({
1351
1384
  name: tool.name,
1352
1385
  description: tool.description,
1353
- inputSchema: z3.toJSONSchema(tool.inputSchema),
1386
+ inputSchema: z4.toJSONSchema(tool.inputSchema),
1354
1387
  ...tool.outputSchema && {
1355
- outputSchema: z3.toJSONSchema(z3.object(tool.outputSchema))
1388
+ outputSchema: z4.toJSONSchema(z4.object(tool.outputSchema))
1356
1389
  },
1357
1390
  ...tool.annotations && { annotations: tool.annotations }
1358
1391
  }));
1392
+ sharedLogger.info("[tools/list]", { message: `Exposing ${tools.length} tools`, tools: tools.map((t) => t.name) });
1359
1393
  return { result: { tools } };
1360
1394
  }
1361
1395
  async function handleToolsCall(params, ctx, requestId) {
@@ -1409,15 +1443,17 @@ async function handleToolsCall(params, ctx, requestId) {
1409
1443
  }
1410
1444
  };
1411
1445
  }
1446
+ const err = error instanceof Error ? error : new Error(String(error));
1412
1447
  sharedLogger.error("mcp_dispatch", {
1413
1448
  message: "Tool execution failed",
1414
1449
  tool: toolName,
1415
- error: error.message
1450
+ error: err.message,
1451
+ stack: err.stack
1416
1452
  });
1417
1453
  return {
1418
1454
  error: {
1419
1455
  code: JsonRpcErrorCode2.InternalError,
1420
- message: `Tool execution failed: ${error.message}`
1456
+ message: `Tool execution failed: ${err.name}: ${err.message}`
1421
1457
  }
1422
1458
  };
1423
1459
  } finally {
@@ -1924,17 +1960,17 @@ function assertSsrfSafe(urlString, options) {
1924
1960
  }
1925
1961
 
1926
1962
  // src/shared/oauth/cimd.ts
1927
- import { z as z4 } from "zod";
1928
- var ClientMetadataSchema = z4.object({
1929
- client_id: z4.string().url(),
1930
- client_name: z4.string().optional(),
1931
- redirect_uris: z4.array(z4.string().url()),
1932
- client_uri: z4.string().url().optional(),
1933
- logo_uri: z4.string().url().optional(),
1934
- tos_uri: z4.string().url().optional(),
1935
- policy_uri: z4.string().url().optional(),
1936
- jwks_uri: z4.string().url().optional(),
1937
- software_statement: z4.string().optional()
1963
+ import { z as z5 } from "zod";
1964
+ var ClientMetadataSchema = z5.object({
1965
+ client_id: z5.string().url(),
1966
+ client_name: z5.string().optional(),
1967
+ redirect_uris: z5.array(z5.string().url()),
1968
+ client_uri: z5.string().url().optional(),
1969
+ logo_uri: z5.string().url().optional(),
1970
+ tos_uri: z5.string().url().optional(),
1971
+ policy_uri: z5.string().url().optional(),
1972
+ jwks_uri: z5.string().url().optional(),
1973
+ software_statement: z5.string().optional()
1938
1974
  });
1939
1975
  function isClientIdUrl(clientId) {
1940
1976
  if (!clientId.startsWith("https://")) {
@@ -3152,4 +3188,4 @@ function shimProcessEnv(env) {
3152
3188
  };
3153
3189
  }
3154
3190
 
3155
- export { base64Encode, base64Decode, base64UrlEncode, base64UrlDecode, base64UrlEncodeString, base64UrlDecodeString, base64UrlEncodeJson, base64UrlDecodeJson, encrypt, decrypt, generateKey, createEncryptor, withCors, corsPreflightResponse, buildCorsHeaders, MAX_SESSIONS_PER_API_KEY, MemoryTokenStore, MemorySessionStore, KvTokenStore, KvSessionStore, initializeStorage, getTokenStore, getSessionStore, sharedLogger, logger, JsonRpcErrorCode, CancellationError, CancellationToken, createCancellationToken, withCancellation, toProviderInfo, toProviderTokens, assertProviderToken, defineTool, echoInputSchema, echoTool, healthInputSchema, healthTool, sharedTools, getSharedTool, getSharedToolNames, executeSharedTool, registerTools, LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, getLogLevel, dispatchMcpMethod, handleMcpNotification, buildProviderRefreshConfig, refreshProviderToken, isTokenExpiredOrExpiring, ensureFreshToken, validateOrigin, validateProtocolVersion, buildUnauthorizedChallenge, buildAuthorizationServerMetadata, buildProtectedResourceMetadata, createDiscoveryHandlers, workerDiscoveryStrategy, nodeDiscoveryStrategy, checkSsrfSafe, isSsrfSafe, assertSsrfSafe, ClientMetadataSchema, isClientIdUrl, fetchClientMetadata, validateRedirectUri, generateOpaqueToken, handleAuthorize, handleProviderCallback, handleToken, handleRegister, handleRevoke, parseAuthorizeInput, parseCallbackInput, parseTokenInput, buildTokenInput, buildProviderConfig, buildOAuthConfig, buildFlowOptions, initializeWorkerStorage, createWorkerRouter, shimProcessEnv };
3191
+ export { base64Encode, base64Decode, base64UrlEncode, base64UrlDecode, base64UrlEncodeString, base64UrlDecodeString, base64UrlEncodeJson, base64UrlDecodeJson, encrypt, decrypt, generateKey, createEncryptor, withCors, corsPreflightResponse, buildCorsHeaders, MAX_SESSIONS_PER_API_KEY, MemoryTokenStore, MemorySessionStore, KvTokenStore, KvSessionStore, initializeStorage, getTokenStore, getSessionStore, sharedLogger, logger, JsonRpcErrorCode, CancellationError, CancellationToken, createCancellationToken, withCancellation, toProviderInfo, toProviderTokens, assertProviderToken, normalizeOutputSchema, defineTool, echoInputSchema, echoTool, healthInputSchema, healthTool, sharedTools, getSharedTool, getSharedToolNames, executeSharedTool, registerTools, LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, getLogLevel, dispatchMcpMethod, handleMcpNotification, buildProviderRefreshConfig, refreshProviderToken, isTokenExpiredOrExpiring, ensureFreshToken, validateOrigin, validateProtocolVersion, buildUnauthorizedChallenge, buildAuthorizationServerMetadata, buildProtectedResourceMetadata, createDiscoveryHandlers, workerDiscoveryStrategy, nodeDiscoveryStrategy, checkSsrfSafe, isSsrfSafe, assertSsrfSafe, ClientMetadataSchema, isClientIdUrl, fetchClientMetadata, validateRedirectUri, generateOpaqueToken, handleAuthorize, handleProviderCallback, handleToken, handleRegister, handleRevoke, parseAuthorizeInput, parseCallbackInput, parseTokenInput, buildTokenInput, buildProviderConfig, buildOAuthConfig, buildFlowOptions, initializeWorkerStorage, createWorkerRouter, shimProcessEnv };
package/dist/index.js CHANGED
@@ -66,6 +66,7 @@ import {
66
66
  isTokenExpiredOrExpiring,
67
67
  logger,
68
68
  nodeDiscoveryStrategy,
69
+ normalizeOutputSchema,
69
70
  parseAuthorizeInput,
70
71
  parseCallbackInput,
71
72
  parseTokenInput,
@@ -82,7 +83,7 @@ import {
82
83
  withCancellation,
83
84
  withCors,
84
85
  workerDiscoveryStrategy
85
- } from "./index-qmejk5tj.js";
86
+ } from "./index-5jbpj7e0.js";
86
87
  // src/shared/config/env.ts
87
88
  function parseBoolean(value) {
88
89
  return String(value || "false").toLowerCase() === "true";
@@ -976,6 +977,7 @@ export {
976
977
  parseAuthStrategy2 as parseAuthStrategy,
977
978
  paginateArray,
978
979
  notifyElicitationComplete,
980
+ normalizeOutputSchema,
979
981
  nodeDiscoveryStrategy,
980
982
  mergeAuthHeaders,
981
983
  makeTokenBucket,
@@ -29324,8 +29324,34 @@ function toProviderInfo(tokens) {
29324
29324
  }
29325
29325
 
29326
29326
  // src/shared/tools/types.ts
29327
+ function normalizeOutputSchema(schema) {
29328
+ if (schema instanceof exports_external.ZodObject) {
29329
+ return schema.shape;
29330
+ }
29331
+ return schema;
29332
+ }
29333
+ function isToolResult(value) {
29334
+ return typeof value === "object" && value !== null && "content" in value && Array.isArray(value.content);
29335
+ }
29327
29336
  function defineTool(def) {
29328
- return def;
29337
+ if (def.outputSchema) {
29338
+ def.outputSchema = normalizeOutputSchema(def.outputSchema);
29339
+ }
29340
+ const originalHandler = def.handler;
29341
+ return {
29342
+ ...def,
29343
+ handler: async (args, context) => {
29344
+ const result = await originalHandler(args, context);
29345
+ if (isToolResult(result))
29346
+ return result;
29347
+ return {
29348
+ content: [
29349
+ { type: "text", text: JSON.stringify(result, null, 2) }
29350
+ ],
29351
+ structuredContent: result
29352
+ };
29353
+ }
29354
+ };
29329
29355
  }
29330
29356
 
29331
29357
  // src/shared/tools/echo.ts
@@ -29414,8 +29440,8 @@ function getSchemaShape(schema) {
29414
29440
  if ("shape" in schema && typeof schema.shape === "object") {
29415
29441
  return schema.shape;
29416
29442
  }
29417
- if ("_def" in schema && schema._def && typeof schema._def === "object") {
29418
- const def = schema._def;
29443
+ if ("def" in schema && schema.def && typeof schema.def === "object") {
29444
+ const def = schema.def;
29419
29445
  if (def.schema) {
29420
29446
  return getSchemaShape(def.schema);
29421
29447
  }
@@ -29478,10 +29504,16 @@ async function executeSharedTool(name, args, context, tools) {
29478
29504
  isError: true
29479
29505
  };
29480
29506
  }
29507
+ const err = error48 instanceof Error ? error48 : new Error(String(error48));
29508
+ logger.error("execute_tool", {
29509
+ message: `Tool execution failed: ${err.message}`,
29510
+ tool: name,
29511
+ stack: err.stack
29512
+ });
29513
+ const message = `${err.name}: ${err.message}${err.stack ? `
29514
+ ${err.stack}` : ""}`;
29481
29515
  return {
29482
- content: [
29483
- { type: "text", text: `Tool error: ${error48.message}` }
29484
- ],
29516
+ content: [{ type: "text", text: `Tool error: ${message}` }],
29485
29517
  isError: true
29486
29518
  };
29487
29519
  }
@@ -2,7 +2,7 @@ import {
2
2
  createWorkerRouter,
3
3
  initializeWorkerStorage,
4
4
  shimProcessEnv
5
- } from "../../index-qmejk5tj.js";
5
+ } from "../../index-5jbpj7e0.js";
6
6
  export {
7
7
  shimProcessEnv,
8
8
  initializeWorkerStorage,
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Uses Zod for schema validation (works in both runtimes).
6
6
  */
7
- import type { ZodObject, ZodRawShape, z } from "zod";
7
+ import { type ZodObject, type ZodRawShape, z } from "zod";
8
8
  import type { AuthStrategy } from "../types/auth.js";
9
9
  import type { ProviderInfo } from "../types/provider.js";
10
10
  export type { AuthStrategy } from "../types/auth.js";
@@ -129,8 +129,8 @@ export interface SharedToolDefinition<TShape extends ZodRawShape = ZodRawShape>
129
129
  description: string;
130
130
  /** Zod schema for input validation */
131
131
  inputSchema: ZodObject<TShape>;
132
- /** Optional Zod schema for structured output */
133
- outputSchema?: ZodRawShape;
132
+ /** Optional Zod schema for structured output (ZodRawShape or ZodObject) */
133
+ outputSchema?: ZodRawShape | ZodObject<ZodRawShape>;
134
134
  /** Tool handler function */
135
135
  handler: (args: z.infer<ZodObject<TShape>>, context: ToolContext) => Promise<ToolResult>;
136
136
  /**
@@ -155,7 +155,18 @@ export interface SharedToolDefinition<TShape extends ZodRawShape = ZodRawShape>
155
155
  openWorldHint?: boolean;
156
156
  };
157
157
  }
158
+ /**
159
+ * Normalizes outputSchema to ZodRawShape.
160
+ * Accepts either ZodRawShape or ZodObject<ZodRawShape> and returns ZodRawShape.
161
+ */
162
+ export declare function normalizeOutputSchema(schema: ZodRawShape | ZodObject<ZodRawShape>): ZodRawShape;
163
+ /** Input type for defineTool — handler may return a plain object instead of ToolResult */
164
+ type ToolDefinitionInput<TShape extends ZodRawShape> = Omit<SharedToolDefinition<TShape>, "handler"> & {
165
+ handler: (args: z.infer<ZodObject<TShape>>, context: ToolContext) => Promise<ToolResult | Record<string, unknown>>;
166
+ };
158
167
  /**
159
168
  * Helper to create a type-safe tool definition.
169
+ * Handlers can return either a ToolResult or a plain object — plain objects are
170
+ * automatically wrapped as { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result }.
160
171
  */
161
- export declare function defineTool<TShape extends ZodRawShape>(def: SharedToolDefinition<TShape>): SharedToolDefinition<TShape>;
172
+ export declare function defineTool<TShape extends ZodRawShape>(def: ToolDefinitionInput<TShape>): SharedToolDefinition<TShape>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phake/mcp",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/fuongz/phake-mcp"