@phake/mcp 0.0.5 → 0.0.7

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",
@@ -1277,7 +1304,7 @@ function registerTools(server, contextResolver) {
1277
1304
  }
1278
1305
 
1279
1306
  // src/shared/mcp/dispatcher.ts
1280
- import { z as z3 } from "zod";
1307
+ import { z as z4 } from "zod";
1281
1308
 
1282
1309
  // src/runtime/node/capabilities.ts
1283
1310
  function buildCapabilities() {
@@ -1350,9 +1377,9 @@ async function handleToolsList(ctx) {
1350
1377
  const tools = (ctx.tools ?? sharedTools).map((tool) => ({
1351
1378
  name: tool.name,
1352
1379
  description: tool.description,
1353
- inputSchema: z3.toJSONSchema(tool.inputSchema),
1380
+ inputSchema: z4.toJSONSchema(tool.inputSchema),
1354
1381
  ...tool.outputSchema && {
1355
- outputSchema: z3.toJSONSchema(z3.object(tool.outputSchema))
1382
+ outputSchema: z4.toJSONSchema(z4.object(tool.outputSchema))
1356
1383
  },
1357
1384
  ...tool.annotations && { annotations: tool.annotations }
1358
1385
  }));
@@ -1759,7 +1786,7 @@ function buildUnauthorizedChallenge(args) {
1759
1786
  return {
1760
1787
  status: 401,
1761
1788
  headers: {
1762
- "WWW-Authenticate": `Bearer realm="MCP", authorization_uri="${resourceMd}"`,
1789
+ "WWW-Authenticate": `Bearer realm="MCP", resource_metadata="${resourceMd}"`,
1763
1790
  "Mcp-Session-Id": args.sid
1764
1791
  },
1765
1792
  body: {
@@ -1924,17 +1951,17 @@ function assertSsrfSafe(urlString, options) {
1924
1951
  }
1925
1952
 
1926
1953
  // 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()
1954
+ import { z as z5 } from "zod";
1955
+ var ClientMetadataSchema = z5.object({
1956
+ client_id: z5.string().url(),
1957
+ client_name: z5.string().optional(),
1958
+ redirect_uris: z5.array(z5.string().url()),
1959
+ client_uri: z5.string().url().optional(),
1960
+ logo_uri: z5.string().url().optional(),
1961
+ tos_uri: z5.string().url().optional(),
1962
+ policy_uri: z5.string().url().optional(),
1963
+ jwks_uri: z5.string().url().optional(),
1964
+ software_statement: z5.string().optional()
1938
1965
  });
1939
1966
  function isClientIdUrl(clientId) {
1940
1967
  if (!clientId.startsWith("https://")) {
@@ -2941,6 +2968,12 @@ function attachDiscoveryRoutes(router, config) {
2941
2968
  const metadata = protectedResourceMetadata(here, sid);
2942
2969
  return jsonResponse(metadata);
2943
2970
  });
2971
+ router.get("/.well-known/oauth-protected-resource/*", async (request) => {
2972
+ const here = new URL(request.url);
2973
+ const sid = here.searchParams.get("sid") ?? undefined;
2974
+ const metadata = protectedResourceMetadata(here, sid);
2975
+ return jsonResponse(metadata);
2976
+ });
2944
2977
  }
2945
2978
 
2946
2979
  // src/adapters/http-worker/routes.oauth.ts
@@ -3146,4 +3179,4 @@ function shimProcessEnv(env) {
3146
3179
  };
3147
3180
  }
3148
3181
 
3149
- 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 };
3182
+ 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-zhw318hb.js";
86
+ } from "./index-3q8aj7k6.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
@@ -2,7 +2,7 @@ import {
2
2
  createWorkerRouter,
3
3
  initializeWorkerStorage,
4
4
  shimProcessEnv
5
- } from "../../index-zhw318hb.js";
5
+ } from "../../index-3q8aj7k6.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.5",
3
+ "version": "0.0.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/fuongz/phake-mcp"