AI & LLM APIs cookbook · Advanced

Use MCP server tools from your own app

Connect to an MCP server, offer its tools to the model, and run the calls the model makes.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Open a client session to the server, list its tools and convert them to the Messages API tool format (name, description, input schema). When the model requests a tool, call it through the MCP client and return the text content as the tool result, keeping is_error in sync.

Solution

import asyncio

import anthropic
from mcp import Client

claude = anthropic.AsyncAnthropic()


async def ask(question: str, server_url: str = "http://localhost:8000/mcp", max_steps: int = 6) -> str:
    async with Client(server_url) as mcp_client:
        tools = [{"name": t.name, "description": t.description or "", "input_schema": t.input_schema}
                 for t in (await mcp_client.list_tools()).tools]
        messages = [{"role": "user", "content": question}]
        for _ in range(max_steps):
            response = await claude.messages.create(model="claude-sonnet-5-5", max_tokens=1024,
                                                    tools=tools, messages=messages)
            messages.append({"role": "assistant", "content": response.content})
            if response.stop_reason != "tool_use":
                return "".join(b.text for b in response.content if b.type == "text")
            results = []
            for block in (b for b in response.content if b.type == "tool_use"):
                result = await mcp_client.call_tool(block.name, block.input)
                text = "\n".join(c.text for c in result.content if c.type == "text")
                results.append({"type": "tool_result", "tool_use_id": block.id, "content": text,
                                "is_error": bool(result.is_error)})
            messages.append({"role": "user", "content": results})
    return "Stopped after too many steps."


print(asyncio.run(ask("Which products with 'cable' in the name are out of stock?")))

Pitfalls

  • Connecting to servers you haven't reviewed: tool descriptions are instructions to your model.
  • Auto-running tools annotated as destructive; ask a human first.
  • Dropping is_error, so the model treats failures as data.

Variations

  • Filter the tool list per user or task instead of offering every tool.
  • Use the Messages API MCP connector when the server is reachable from the API.

Further reading: Model Context Protocol

Reference: https://modelcontextprotocol.io/docs/getting-started/intro

More AI & LLM APIs recipes

Was this page helpful?