tools/list の出し方
Forecall が採点する JSON、受け付ける形と上限、forecall dump や公式の SDK で MCP サーバーから取り出す方法を説明します。
このページの内容
Forecall が採点するのは、MCP サーバーが tools/list の要求に返すツールの一覧です。各ツールの name、description、inputSchema と、あれば outputSchema と annotations を読みます。AI エージェントがツールを選ぶ前に読むのがこの内容なので、点数もこれについて付けます。
受け付ける形
Web のリンターと CLI は、同じ 3 つの形を同じ上限で読みます。
- ツールの配列
[{ "name": … }, …]- tools の配列を持つオブジェクト
{ "tools": [ … ] }- JSON-RPC の応答
{ "result": { "tools": [ … ] } }
上限は 1 MB(1,048,576 バイト)、200 ツールです。
キーは MCP の通信形式の名前(camelCase)で書きます。inputSchema、outputSchema、annotations.readOnlyHint などです。input_schema のような snake_case のキーがあると、その場所と直し方を一覧にして断ります。Forecall は自動では直しません。採点するのは、サーバーが実際に送る内容そのものだからです。
サーバーから取り出す
いちばん手早いのは forecall dump です。サーバーを起動するかサーバーにつなぎ、その tools/list を上の形で書き出します。
npx forecall dump -o tools.json -- npx -y @modelcontextprotocol/server-filesystem .
npx forecall dump -o tools.json https://example.com/mcp --header "Authorization: Bearer $TOKEN"
オプションはCLI で採点するにあります。自分のクライアントを使うなら、MCP の SDK でサーバーにつなぎ、tools/list の結果を出力します。次の例は stdio でサーバーを起動します。命令と引数は、あなたのサーバーのものに置き換えてください。どちらも {"tools": [...]} を出力するので、ファイルに保存できます。
TypeScript
公式の SDK(@modelcontextprotocol/client)では、listTools() が一覧のすべてのページを読みます。
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
const client = new Client({ name: "dump-tools", version: "1.0.0" });
await client.connect(
new StdioClientTransport({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
}),
);
const { tools } = await client.listTools();
console.log(JSON.stringify({ tools }, null, 2));
await client.close();
Python
公式の SDK(mcp 2.x)の list_tools() は 1 ページずつ読むので、next_cursor をたどります。ツールは by_alias=True を付けて書き出してください。付けないと input_schema のような snake_case のキーで書き出され、Forecall はそれを断ります。
import asyncio
import json
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from mcp.types import PaginatedRequestParams
async def main():
server = StdioServerParameters(
command="npx", args=["-y", "@modelcontextprotocol/server-filesystem", "."]
)
async with stdio_client(server) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools, cursor = [], None
while True:
params = PaginatedRequestParams(cursor=cursor) if cursor else None
result = await session.list_tools(params=params)
# by_alias=True writes the MCP names (inputSchema, not input_schema).
tools += [t.model_dump(mode="json", by_alias=True, exclude_none=True) for t in result.tools]
cursor = result.next_cursor
if cursor is None:
break
print(json.dumps({"tools": tools}, indent=2, ensure_ascii=False))
asyncio.run(main())
採点する
JSON をリンターに貼るか、CLI で手元のファイルを採点します。
npx forecall lint tools.json
まだ公開していないツール定義は貼らないでください。結果は URL を知っている人なら誰でも見られます。forecall lint はどこにも送りません。