diff --git a/src/context.ts b/src/context.ts index 80930f7..105327c 100644 --- a/src/context.ts +++ b/src/context.ts @@ -58,6 +58,8 @@ export class Context { modalStatesMarkdown(): string[] { const result: string[] = ['### Modal state']; + if (this._modalStates.length === 0) + result.push('- There is no modal state present'); for (const state of this._modalStates) { const tool = this.tools.find(tool => tool.clearsModalState === state.type); result.push(`- [${state.description}]: can be handled by the "${tool?.schema.name}" tool`); diff --git a/src/server.ts b/src/server.ts index c37fa67..0c9e58e 100644 --- a/src/server.ts +++ b/src/server.ts @@ -49,34 +49,25 @@ export function createServerWithTools(serverOptions: MCPServerOptions, config: C }); server.setRequestHandler(CallToolRequestSchema, async request => { + const errorResult = (...messages: string[]) => ({ + content: [{ type: 'text', text: messages.join('\n') }], + isError: true, + }); const tool = tools.find(tool => tool.schema.name === request.params.name); - if (!tool) { - return { - content: [{ type: 'text', text: `Tool "${request.params.name}" not found` }], - isError: true, - }; - } + if (!tool) + return errorResult(`Tool "${request.params.name}" not found`); + const modalStates = context.modalStates().map(state => state.type); - if ((tool.clearsModalState && !modalStates.includes(tool.clearsModalState)) || - (!tool.clearsModalState && modalStates.length)) { - const text = [ - `Tool "${request.params.name}" does not handle the modal state.`, - ...context.modalStatesMarkdown(), - ].join('\n'); - return { - content: [{ type: 'text', text }], - isError: true, - }; - } + if (tool.clearsModalState && !modalStates.includes(tool.clearsModalState)) + return errorResult(`The tool "${request.params.name}" can only be used when there is related modal state present.`, ...context.modalStatesMarkdown()); + if (!tool.clearsModalState && modalStates.length) + return errorResult(`Tool "${request.params.name}" does not handle the modal state.`, ...context.modalStatesMarkdown()); try { return await context.run(tool, request.params.arguments); } catch (error) { - return { - content: [{ type: 'text', text: String(error) }], - isError: true, - }; + return errorResult(String(error)); } }); diff --git a/tests/files.spec.ts b/tests/files.spec.ts index 6e9b797..468f5ff 100644 --- a/tests/files.spec.ts +++ b/tests/files.spec.ts @@ -30,6 +30,17 @@ test('browser_file_upload', async ({ client }) => { - button "Button" [ref=s1e4] \`\`\``); + { + expect(await client.callTool({ + name: 'browser_file_upload', + arguments: { paths: [] }, + })).toHaveTextContent(` +The tool "browser_file_upload" can only be used when there is related modal state present. +### Modal state +- There is no modal state present + `.trim()); + } + expect(await client.callTool({ name: 'browser_click', arguments: {