From 8da1f295b815fe12af356fef53d163c08d209690 Mon Sep 17 00:00:00 2001 From: arlo Date: Wed, 15 Jul 2026 20:43:51 +0800 Subject: [PATCH 1/2] fix(mcp): return structured content for tools with output schemas --- .../devframe/src/adapters/mcp/__tests__/mcp-server.test.ts | 7 +++++++ packages/devframe/src/adapters/mcp/build-server.ts | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts b/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts index a69a9430..aff31ff3 100644 --- a/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts +++ b/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts @@ -67,13 +67,20 @@ describe('mcp adapter (in-memory)', () => { ctx.agent.registerTool({ id: 'echo', description: 'Echo.', + outputSchema: { + type: 'object', + properties: { echoed: { type: 'object' } }, + required: ['echoed'], + }, handler: args => ({ echoed: args }), }) + await client.listTools() const result = await client.callTool({ name: 'echo', arguments: { foo: 'bar' } }) const content = result.content as Array<{ type: string, text: string }> expect(content[0]!.type).toBe('text') expect(JSON.parse(content[0]!.text)).toEqual({ echoed: { foo: 'bar' } }) + expect(result.structuredContent).toEqual({ echoed: { foo: 'bar' } }) } finally { await cleanup() diff --git a/packages/devframe/src/adapters/mcp/build-server.ts b/packages/devframe/src/adapters/mcp/build-server.ts index 822deb07..1888571d 100644 --- a/packages/devframe/src/adapters/mcp/build-server.ts +++ b/packages/devframe/src/adapters/mcp/build-server.ts @@ -154,6 +154,10 @@ function registerToolHandlers(server: Server, ctx: DevframeNodeContext): void { server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params try { + const tool = ctx.agent.getTool(name) + const outputSchema = tool + ? tool.outputSchema ?? computeOutputSchema(tool, ctx) + : undefined const result = await ctx.agent.invoke(name, args ?? {}) return { content: [ @@ -162,6 +166,7 @@ function registerToolHandlers(server: Server, ctx: DevframeNodeContext): void { text: stringifyForMcp(result), }, ], + ...(outputSchema ? { structuredContent: result as Record } : {}), } } catch (error) { From b7c2f150052e8a8131cc0eddf9f13e3ba8b00df4 Mon Sep 17 00:00:00 2001 From: arlo Date: Wed, 15 Jul 2026 20:54:38 +0800 Subject: [PATCH 2/2] chore: update --- packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts b/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts index aff31ff3..c6751aaf 100644 --- a/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts +++ b/packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts @@ -61,7 +61,7 @@ describe('mcp adapter (in-memory)', () => { } }) - it('calls a tool and returns the text content', async () => { + it('returns text and structured content for a tool with an output schema', async () => { const { ctx, client, cleanup } = await bootPair() try { ctx.agent.registerTool({