Skip to content

Commit eb14a70

Browse files
committed
feat: add listToolCallbacks method to McpClient interface and update related implementations
1 parent bce01a7 commit eb14a70

4 files changed

Lines changed: 53 additions & 13 deletions

File tree

packages/core/src/mcpclient.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
2525

2626
const dbg = genaiscriptDebug("mcp:client");
2727

28-
export interface McpClientProxy extends McpClient {
29-
listToolCallbacks(): Promise<ToolCallback[]>;
30-
}
31-
28+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3229
function toolResultContentToText(res: any) {
3330
const content = res.content as (TextContent | ImageContent | EmbeddedResource)[];
3431
let text = arrayify(content)
@@ -56,24 +53,24 @@ function resolveMcpEnv(_env: Record<string, string>) {
5653
if (!_env) return _env;
5754
const res = structuredClone(_env);
5855
Object.entries(res)
59-
.filter(([k, v]) => v === "")
60-
.forEach(([key, value]) => {
56+
.filter(([, v]) => v === "")
57+
.forEach(([key]) => {
6158
dbg(`filling env var: %s`, key);
6259
res[key] = process.env[key] || "";
6360
});
6461
return res;
6562
}
6663

6764
export class McpClientManager extends EventTarget implements AsyncDisposable {
68-
private _clients: McpClientProxy[] = [];
65+
private _clients: McpClient[] = [];
6966
constructor() {
7067
super();
7168
}
7269

7370
async startMcpServer(
7471
serverConfig: McpServerConfig,
7572
options: Required<TraceOptions> & CancellationOptions,
76-
): Promise<McpClientProxy> {
73+
): Promise<McpClient> {
7774
const { cancellationToken } = options || {};
7875
logVerbose(`mcp: starting ` + serverConfig.id);
7976
const signal = toSignal(cancellationToken);
@@ -137,11 +134,12 @@ export class McpClientManager extends EventTarget implements AsyncDisposable {
137134
({
138135
name: t.name,
139136
description: t.description,
137+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
140138
inputSchema: t.inputSchema as any,
141139
}) satisfies McpToolReference,
142140
);
143141
};
144-
const listToolCallbacks: McpClientProxy["listToolCallbacks"] = async () => {
142+
const listToolCallbacks: McpClient["listToolCallbacks"] = async () => {
145143
// list tools
146144
dbgc(`listing tools`);
147145
let { tools: toolDefinitions } = await client.listTools(
@@ -207,11 +205,13 @@ export class McpClientManager extends EventTarget implements AsyncDisposable {
207205
spec: {
208206
name: `${id}_${name}`,
209207
description,
208+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
210209
parameters: inputSchema as any,
211210
},
212211
options: toolOptions,
213212
generator,
214-
impl: async (args: any) => {
213+
impl: async (args) => {
214+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
215215
const { context, ...restArgs } = args;
216216
const res = await client.callTool(
217217
{
@@ -251,7 +251,8 @@ export class McpClientManager extends EventTarget implements AsyncDisposable {
251251
content: content.text
252252
? String(content.text)
253253
: content.blob
254-
? Buffer.from(content.blob as any).toString("base64")
254+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
255+
Buffer.from(content.blob as any).toString("base64")
255256
: undefined,
256257
encoding: content.blob ? "base64" : undefined,
257258
filename: content.uri,
@@ -297,6 +298,7 @@ export class McpClientManager extends EventTarget implements AsyncDisposable {
297298
name: toolId,
298299
arguments: args,
299300
},
301+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
300302
responseSchema as any,
301303
{
302304
signal,
@@ -320,15 +322,15 @@ export class McpClientManager extends EventTarget implements AsyncDisposable {
320322
readResource,
321323
dispose,
322324
[Symbol.asyncDispose]: dispose,
323-
} satisfies McpClientProxy);
325+
} satisfies McpClient);
324326
this._clients.push(res);
325327
return res;
326328
} finally {
327329
trace?.endDetails();
328330
}
329331
}
330332

331-
get clients(): McpClientProxy[] {
333+
get clients(): McpClient[] {
332334
return this._clients.slice(0);
333335
}
334336

packages/core/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5888,11 +5888,17 @@ export interface McpClient extends AsyncDisposable {
58885888
* Pings the server
58895889
*/
58905890
ping(): Promise<void>;
5891+
58915892
/**
58925893
* List all available MCP tools
58935894
*/
58945895
listTools(): Promise<McpToolReference[]>;
58955896

5897+
/**
5898+
* Returns a list of tools that can be used in a chat session
5899+
*/
5900+
listToolCallbacks(): Promise<ToolCallback[]>;
5901+
58965902
/**
58975903
* List resources available in the server
58985904
*/
@@ -5908,6 +5914,7 @@ export interface McpClient extends AsyncDisposable {
59085914
* @param name Call the MCP tool
59095915
* @param args
59105916
*/
5917+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
59115918
callTool(name: string, args: Record<string, any>): Promise<McpServerToolResult>;
59125919

59135920
/**

packages/core/src/types/prompt_template.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5871,11 +5871,17 @@ interface McpClient extends AsyncDisposable {
58715871
* Pings the server
58725872
*/
58735873
ping(): Promise<void>;
5874+
58745875
/**
58755876
* List all available MCP tools
58765877
*/
58775878
listTools(): Promise<McpToolReference[]>;
58785879

5880+
/**
5881+
* Returns a list of tools that can be used in a chat session
5882+
*/
5883+
listToolCallbacks(): Promise<ToolCallback[]>;
5884+
58795885
/**
58805886
* List resources available in the server
58815887
*/
@@ -5891,6 +5897,7 @@ interface McpClient extends AsyncDisposable {
58915897
* @param name Call the MCP tool
58925898
* @param args
58935899
*/
5900+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
58945901
callTool(name: string, args: Record<string, any>): Promise<McpServerToolResult>;
58955902

58965903
/**
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
script({ tests: {} });
2+
const { output } = env;
3+
const fetchClient = await host.mcpServer({
4+
id: "fetch",
5+
command: "docker",
6+
args: ["run", "-i", "--rm", "mcp/fetch"],
7+
});
8+
const fetchTools = await fetchClient.listToolCallbacks();
9+
output.itemValue(`tools`, fetchTools.map((t) => t.spec.name).join(", "));
10+
const fetchTool = await (
11+
await fetchClient.listToolCallbacks()
12+
).find((t) => t.spec.name === "fetch_fetch");
13+
if (!fetchTool) cancel("fetch tool not found");
14+
const urls = [
15+
"https://raw.githubusercontent.com/microsoft/genaiscript/refs/heads/main/SUPPORT.md",
16+
"https://raw.githubusercontent.com/microsoft/genaiscript/refs/heads/main/README.md",
17+
];
18+
for (const url of urls) {
19+
const res = await runPrompt((ctx) => {
20+
ctx.defTool(fetchTool);
21+
ctx.$`summarize ${url} in one emoji.`;
22+
});
23+
output.itemValue(url, res.text);
24+
}

0 commit comments

Comments
 (0)