@@ -5,6 +5,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5
5
import type { JsonSchema7ObjectType } from "zod-to-json-schema" ;
6
6
7
7
import { thinkTool } from "../agent/agent.js" ;
8
+ import { Model } from "../llm/model.js" ;
8
9
import {
9
10
logMcpEnd ,
10
11
logMcpEndError ,
@@ -16,6 +17,7 @@ import { McpServersConfig } from "./config.js";
16
17
17
18
export const createMcpTools = async (
18
19
config : McpServersConfig ,
20
+ model : Model ,
19
21
options : { thinkTool : boolean ; reasoning : boolean ; tempDir : string } ,
20
22
) : Promise < {
21
23
tools : StructuredToolInterface [ ] ;
@@ -27,7 +29,7 @@ export const createMcpTools = async (
27
29
Object . entries ( config ) . map ( async ( [ name , serverConfig ] ) => {
28
30
const client = await createMcpClient ( name , serverConfig , options ) ;
29
31
clients . push ( client ) ;
30
- return await createTools ( name , client , options ) ;
32
+ return await createTools ( name , client , model , options ) ;
31
33
} ) ,
32
34
)
33
35
) . flat ( ) ;
@@ -46,6 +48,7 @@ export const createMcpTools = async (
46
48
const createTools = async (
47
49
name : string ,
48
50
client : Client ,
51
+ model : Model ,
49
52
options : { reasoning ?: boolean } = { } ,
50
53
) : Promise < StructuredToolInterface [ ] > => {
51
54
const mcpTools = await loadMcpTools ( name , client , {
@@ -54,20 +57,27 @@ const createTools = async (
54
57
additionalToolNamePrefix : "" ,
55
58
} ) ;
56
59
return mcpTools . map ( ( tool ) => {
57
- patchToolInvoke ( tool ) ;
60
+ patchToolInvoke ( tool , model ) ;
58
61
if ( options . reasoning ) patchToolSchemaReasoning ( tool ) ;
59
62
return tool ;
60
63
} ) ;
61
64
} ;
62
65
63
66
// Patch tool.invoke for better logging.
64
- const patchToolInvoke = ( tool : StructuredToolInterface ) => {
67
+ const patchToolInvoke = ( tool : StructuredToolInterface , model : Model ) => {
65
68
const originalInvoke = tool . invoke . bind ( tool ) ;
66
69
tool . invoke = async ( ...args ) => {
67
70
const start = logMcpStart ( tool , args ) ;
68
71
try {
69
72
const result = ( await originalInvoke ( ...args ) ) as ToolMessage ;
70
73
logMcpEnd ( tool , start , result ) ;
74
+ // Workaround for the models that reject non-string content.
75
+ // The same workaround is used by OpenAI client.
76
+ if ( model . provider === "ollama" )
77
+ result . content =
78
+ typeof result . content === "string"
79
+ ? result . content
80
+ : JSON . stringify ( result . content ) ;
71
81
return result ;
72
82
} catch ( error ) {
73
83
logMcpEndError ( tool , start , error ) ;
0 commit comments