Skip to content

Commit b649546

Browse files
committed
Use .actor/input_schema.json as input for MCP
1 parent cf4f582 commit b649546

File tree

3 files changed

+16
-31
lines changed

3 files changed

+16
-31
lines changed

.dockerignore

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
apify_storage
66
crawlee_storage
77
storage
8+
dist
89

910
# installed files
1011
node_modules
@@ -14,3 +15,4 @@ node_modules
1415

1516
# data
1617
data
18+
src/storage

src/mcp/server.ts

+10-27
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,19 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
88
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
99
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
1010

11-
import { defaults } from '../const.js';
11+
import inputSchema from '../../.actor/input_schema.json' assert { type: 'json' };
1212
import { handleModelContextProtocol } from '../search.js';
1313
import { Input } from '../types.js';
1414

15-
const TOOL_SEARCH = 'search';
15+
const TOOL_SEARCH = inputSchema.title.toLowerCase().replace(/ /g, '-');
1616

17-
const WebBrowserArgsSchema = {
18-
type: 'object',
19-
properties: {
20-
query: {
21-
type: 'string',
22-
description: 'Google Search keywords or a URL of a specific web page',
23-
},
24-
maxResults: {
25-
type: 'integer',
26-
description: 'The maximum number of top organic Google Search results whose web pages will be extracted (default: 1)',
27-
default: defaults.maxResults,
28-
minimum: 1, // Ensures the number is positive
29-
},
17+
const TOOLS = [
18+
{
19+
name: TOOL_SEARCH,
20+
description: inputSchema.description,
21+
inputSchema,
3022
},
31-
required: ['query'],
32-
};
23+
];
3324

3425
/**
3526
* Create an MCP server with a tool to call RAG Web Browser Actor
@@ -66,23 +57,15 @@ export class RagWebBrowserServer {
6657
private setupToolHandlers(): void {
6758
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
6859
return {
69-
tools: [
70-
{
71-
name: TOOL_SEARCH,
72-
description: 'Search phrase or a URL at Google and return crawled web pages as text or Markdown',
73-
inputSchema: WebBrowserArgsSchema,
74-
},
75-
],
60+
tools: TOOLS,
7661
};
7762
});
7863
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
7964
const { name, arguments: args } = request.params;
8065
switch (name) {
8166
case TOOL_SEARCH: {
8267
const content = await handleModelContextProtocol(args as unknown as Input);
83-
return {
84-
content: [{ type: 'text', text: JSON.stringify(content) }],
85-
};
68+
return { content: content.map((message) => ({ type: 'text', text: JSON.stringify(message) })) };
8669
}
8770
default: {
8871
throw new Error(`Unknown tool: ${name}`);

src/search.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { addPlaywrightCrawlRequest, addSearchRequest, createAndStartCrawlers } f
66
import { UserInputError } from './errors.js';
77
import { processInput } from './input.js';
88
import { createResponsePromise } from './responses.js';
9-
import { Input, PlaywrightScraperSettings } from './types.js';
9+
import { Input, Output, PlaywrightScraperSettings } from './types.js';
1010
import {
1111
addTimeMeasureEvent,
1212
checkAndRemoveExtraParams,
@@ -53,7 +53,7 @@ function prepareRequest(
5353
* Internal function that handles the common logic for search.
5454
* Returns a promise that resolves to the final results array of Output objects.
5555
*/
56-
async function runSearchProcess(params: Partial<Input>): Promise<unknown> {
56+
async function runSearchProcess(params: Partial<Input>): Promise<Output[]> {
5757
// Process the query parameters the same way as normal inputs
5858
const {
5959
input,
@@ -114,14 +114,14 @@ export async function handleSearchRequest(request: IncomingMessage, response: Se
114114
* Handles the model context protocol scenario (non-HTTP scenario).
115115
* Uses the same runSearchProcess function but just returns the results as a promise.
116116
*/
117-
export async function handleModelContextProtocol(params: Partial<Input>) {
117+
export async function handleModelContextProtocol(params: Partial<Input>): Promise<Output[]> {
118118
try {
119119
log.info(`Received parameters: ${JSON.stringify(params)}`);
120120
return await runSearchProcess(params);
121121
} catch (e) {
122122
const error = e as Error;
123123
log.error(`UserInputError occurred: ${error.message}`);
124-
return JSON.stringify({ errorMessage: error.message });
124+
return [{ text: error.message }] as Output[];
125125
}
126126
}
127127

0 commit comments

Comments
 (0)