Skip to content

Commit 9e22895

Browse files
committed
refactor: align tool types with MCP SDK schema and extract McpInputSchema type
1 parent bfc820d commit 9e22895

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

src/mcp/server.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,10 @@ export class ActorsMcpServer {
272272
const clonedWrap = cloneToolEntry(wrap);
273273

274274
// Add Skyfire instructions to description if not already present
275-
if (!clonedWrap.tool.description.includes(SKYFIRE_TOOL_INSTRUCTIONS)) {
275+
if (clonedWrap.tool.description && !clonedWrap.tool.description.includes(SKYFIRE_TOOL_INSTRUCTIONS)) {
276276
clonedWrap.tool.description += `\n\n${SKYFIRE_TOOL_INSTRUCTIONS}`;
277+
} else if (!clonedWrap.tool.description) {
278+
clonedWrap.tool.description = SKYFIRE_TOOL_INSTRUCTIONS;
277279
}
278280
// Add skyfire-pay-id property if not present
279281
if (clonedWrap.tool.inputSchema && 'properties' in clonedWrap.tool.inputSchema) {

src/tools/actor.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { getActorMCPServerPath, getActorMCPServerURL } from '../mcp/actors.js';
1919
import { connectMCPClient } from '../mcp/client.js';
2020
import { getMCPServerTools } from '../mcp/proxy.js';
2121
import { actorDefinitionPrunedCache } from '../state.js';
22-
import type { ActorDefinitionStorage, ActorInfo, ApifyToken, DatasetItem, ToolEntry } from '../types.js';
22+
import type { ActorDefinitionStorage, ActorInfo, ApifyToken, DatasetItem, McpInputSchema, ToolEntry } from '../types.js';
2323
import { ensureOutputWithinCharLimit, getActorDefinitionStorageFieldNames, getActorMcpUrlCached } from '../utils/actor.js';
2424
import { fetchActorDetails } from '../utils/actor-details.js';
2525
import { buildActorResponseContent } from '../utils/actor-response.js';
@@ -196,7 +196,7 @@ Actor description: ${actorDefinitionPruned.description}`;
196196
name: actorNameToToolName(actorDefinitionPruned.actorFullName),
197197
actorFullName: actorDefinitionPruned.actorFullName,
198198
description,
199-
inputSchema,
199+
inputSchema: inputSchema as McpInputSchema,
200200
ajvValidate,
201201
memoryMbytes,
202202
},
@@ -358,7 +358,7 @@ Step 2: Call Actor (step="call")
358358
359359
EXAMPLES:
360360
- user_input: Get instagram posts using apify/instagram-scraper`,
361-
inputSchema: zodToJsonSchema(callActorArgs),
361+
inputSchema: zodToJsonSchema(callActorArgs) as McpInputSchema,
362362
ajvValidate: ajv.compile({
363363
...zodToJsonSchema(callActorArgs),
364364
// Additional props true to allow skyfire-pay-id

src/types.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
22
import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';
3-
import type { Notification, Prompt, Request } from '@modelcontextprotocol/sdk/types.js';
3+
import type { Notification, Prompt, Request, ToolSchema } from '@modelcontextprotocol/sdk/types.js';
44
import type { ValidateFunction } from 'ajv';
55
import type { ActorDefaultRunOptions, ActorDefinition, ActorStoreList, PricingInfo } from 'apify-client';
66

77
import type { ACTOR_PRICING_MODEL } from './const.js';
88
import type { ActorsMcpServer } from './mcp/server.js';
99
import type { toolCategories } from './tools/index.js';
1010
import type { ProgressTracker } from './utils/progress.js';
11+
import z from 'zod';
1112

1213
export interface ISchemaProperties {
1314
type: string;
@@ -60,19 +61,22 @@ export type ActorDefinitionPruned = Pick<ActorDefinitionWithDesc,
6061

6162
/**
6263
* Base interface for all tools in the MCP server.
63-
* Contains common properties shared by all tool types.
64+
* Extends the MCP SDK's Tool schema, which requires inputSchema to have type: "object".
65+
* Adds ajvValidate for runtime validation.
6466
*/
65-
export interface ToolBase {
66-
/** Unique name/identifier for the tool */
67-
name: string;
68-
/** Description of what the tool does */
69-
description: string;
70-
/** JSON schema defining the tool's input parameters */
71-
inputSchema: object;
67+
export interface ToolBase extends z.infer<typeof ToolSchema> {
7268
/** AJV validation function for the input schema */
7369
ajvValidate: ValidateFunction;
7470
}
7571

72+
/**
73+
* Type for MCP SDK's inputSchema constraint.
74+
* Extracted directly from the MCP SDK's ToolSchema to ensure alignment with the specification.
75+
* The MCP SDK requires inputSchema to have type: "object" (literal) at the top level.
76+
* Use this type when casting schemas that have type: string to the strict MCP format.
77+
*/
78+
export type McpInputSchema = z.infer<typeof ToolSchema>['inputSchema'];
79+
7680
/**
7781
* Interface for Actor-based tools - tools that wrap Apify Actors.
7882
* Extends ToolBase with Actor-specific properties.

0 commit comments

Comments
 (0)