Skip to content

SDK doesn't support specifying tool metadata? #1224

@johnson7788

Description

@johnson7788

Some mcp tool, i don't want let LLM know, So i want transfer data by metadata, How can it do it? thank you !

Server example:

import datetime
from fastmcp import FastMCP, Context
from mcp.types import CallToolResult

mcp = FastMCP("EchoServer")

@mcp.tool()
async def echo_tool(text: str, ctx: Context) -> CallToolResult:
    # 从 ctx 获取 metadata
    meta_in = ctx.request_meta or {}
    print("[Server] meta_in:", meta_in)

    return CallToolResult(
        content=[{"type": "text", "text": text.upper()}],
        meta={
            "user_id": meta_in.get("user_id", "unknown"),
            "server_timestamp": datetime.datetime.utcnow().isoformat() + "Z"
        }
    )

if __name__ == "__main__":
    mcp.run(transport="sse")

Client Example

# client.py
from mcp.types import CallToolRequest, CallToolRequestParams, RequestParams
import asyncio
from fastmcp import Client
from mcp.types import CallToolRequestParams, RequestParams
import json

def simulate():
    # 构造调用请求,带上 meta 信息
    req = CallToolRequest(
        method="tools/call",
        params=CallToolRequestParams(
            name="echo_tool",
            arguments={"text": "hello MCP"},
            meta=RequestParams.Meta(  # 通过 alias="_meta" 被序列化为 "_meta"
                user_id="alice",
                session_id="sess-123",
            ),
        ),
    )

    # 序列化为 JSON-RPC 并发送
    payload = req.model_dump(by_alias=True)
    print("Sending:", json.dumps(payload, indent=2))
    # 这里你可以用 WebSocket/httpx/aiohttp 发送 payload 到 MCP server


# client_sse.py
async def main():
    # 指定 SSE 地址(在 server.run(transport="sse") 中默认挂载为 http://localhost:8000/sse)
    async with Client("http://localhost:8000/sse") as client:
        # 调用 echo_tool,自动使用 SSE transport
        result = await client.call_tool(
            "echo_tool",
            {"text": "hello MCP"},
            meta=RequestParams.Meta(
                user_id="alice",
                session_id="sess-123"
            )
        )
        print("Response content:", result.content)
        print("Response meta:", result.meta)

if __name__ == "__main__":
    asyncio.run(main())

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Broken core functionality, security issues, critical missing featureenhancementNew feature or requestfeature requestRequest for a new feature that's not currently supportedready for workEnough information for someone to start working on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions