This guide shows how to build a Claude AI agent with MCP tools: an agent that runs on Anthropic's Claude models and calls tools from a Model Context Protocol server. It is for developers who already know what they want the agent to do and need the Anthropic setup to be right: the key, the model id, the settings that current Claude models accept, and the errors you will see when something is off. You will end with one small file you can point at any MCP server.
How do you use Claude with Promptise?
Install promptise, put your Anthropic key in ANTHROPIC_API_KEY, and pass a Claude model to build_agent(), either as the string "anthropic:claude-opus-5-5" or as Model("claude-opus-5-5", provider="anthropic"). Promptise reaches Claude through LangChain's native ChatAnthropic integration, which is part of the core install. Add your MCP servers in servers=. The agent discovers their tools, sends them to Claude as tool definitions, runs the calls Claude asks for, and loops until Claude gives a final answer.
Nothing extra to install. langchain-anthropic is a core dependency of Promptise, so pip install promptise is the whole setup.
One prefix, two spellings. anthropic: and claude: select the same provider.
Don't set `temperature` on current Claude models. Claude Opus 5.5, Sonnet 5.5, Haiku 5.5 and the Fable models reject sampling parameters at non-default values. Use effort instead.
Check before you spend.
promptise models check claude:<model>tells you what is missing without calling the model. --ping makes one real call.Claude never talks to your MCP server directly. Promptise is the MCP client. Claude only sees tool definitions and tool results.
[02]
Set up Anthropic
You need Python 3.10 or later, an Anthropic API key from the Claude Console, and Promptise Foundry 1.4.2 or later:
pip install "promptise>=1.4.2"Put the key in a .env file next to your script. Promptise loads the nearest .env file automatically (from the working directory up to the project root), and a variable already exported in your shell wins over the file. promptise models env anthropic prints the line to fill in:
# Anthropic Claude — model string example: anthropic:claude-sonnet-4-5
export ANTHROPIC_API_KEY=sk-ant-...
# ↳ console.anthropic.com → API keysThen check the configuration. Nothing set yet:
$ promptise models check claude:claude-opus-5-5
claude:claude-opus-5-5 → anthropic:claude-opus-5-5 (Anthropic Claude)
model part: claude-opus-5-5 — the model name
route: native integration (core)
ANTHROPIC_API_KEY: MISSING — console.anthropic.com → API keys
Not usable yet.
- ANTHROPIC_API_KEY is not set — console.anthropic.com → API keys (e.g. sk-ant-...)
- put ANTHROPIC_API_KEY in a .env file next to your script (loaded automatically; a variable already exported with a non-empty value wins, an empty one is filled from the file), export it, or pass it in code: Model(..., api_key=) — see promptise
models env anthropicWith the key in place, the same command reports the route and stops before calling anything:
$ promptise models check claude:claude-opus-5-5
claude:claude-opus-5-5 → anthropic:claude-opus-5-5 (Anthropic Claude)
model part: claude-opus-5-5 — the model name
route: native integration (core)
ANTHROPIC_API_KEY: set — console.anthropic.com → API keys
Configuration OK — every required setting is in place; nothing was called. Add --ping to make a real one-token call to the model."Configuration OK" means the variable is set, not that the key works. Add --ping for a one-token call that proves the key and the model id are accepted.
Which model id to use
Use the exact ids from Anthropic's models overview. At the time of writing, the current models include:
Model | Model id | Good for |
|---|---|---|
---|---|--- | ||
Claude Opus 5.5 | claude-opus-5-5 | The default for agents that plan and use many tools |
Claude Sonnet 5.5 | claude-sonnet-5-5 | Everyday agent work where speed matters more |
Claude Haiku 5.5 | claude-haiku-5-5 | Routing, classification and high-volume simple steps |
Use the ids as written, without date suffixes. Model lists change, so check the overview page before you pin one in production. For choosing between providers, see the best LLM for AI agents.
[03]
Build a minimal Claude AI agent
The agent below answers questions about a shop's products. The model is configured once, at the top of the file, so the rest of the code doesn't depend on the provider:
import asyncio
import sys
from promptise import Model, build_agent
from promptise.config import StdioServerSpec
# The key comes from ANTHROPIC_API_KEY (environment or .env).
CLAUDE = Model("claude-opus-5-5", provider="anthropic", max_tokens=16000, extra={"effort": "medium"})
async def make_agent(model=CLAUDE):
return await build_agent(
model=model,
servers={"shop": StdioServerSpec(command=sys.executable, args=["shop_server.py"])},
instructions="You answer questions about the shop's products. "
"Use the tools for stock and prices. Never guess them.",
max_agent_iterations=10,
)
async def main():
agent = await make_agent()
try:
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "Is KB-101 in stock, and what does it cost?"}]}
)
calls = [c["name"] for m in result["messages"] for c in getattr(m, "tool_calls", None) or []]
print("tool calls:", ", ".join(calls) or "none")
print(result["messages"][-1].text)
finally:
await agent.shutdown()
if __name__ == "__main__":
asyncio.run(main())What each part does:
`Model("claude-opus-5-5", provider="anthropic", ...)` names the model and the provider. The key isn't in the code: it comes from ANTHROPIC_API_KEY. You can pass api_key= instead when the key comes from a secret store.
`max_tokens=16000` caps each response. Without it, LangChain uses the model's maximum output length, which is far more than an agent turn needs.
`extra={"effort": "medium"}` is passed straight through to ChatAnthropic, which sends it as output_config.effort. Effort is how you trade thoroughness against tokens on current Claude models. low suits simple lookups, and high suits multi-step planning.
`max_agent_iterations=10` stops a run that keeps calling tools without converging.
`result["messages"][-1].text` reads the answer. Claude's replies can contain several content blocks (thinking and text), so .text is safer than .content, which may be a list.
Run it with python claude_agent.py. With a valid key, the script prints the names of the tools Claude called and then its answer.
[04]
Use MCP tools with Claude
The tools come from a small MCP server that the agent starts as a subprocess over stdio:
"""A small MCP tool server: product stock and prices for a shop."""
from promptise.mcp.server import MCPServer
server = MCPServer("shop")
STOCK = {"KB-101": 14, "MS-220": 0, "HD-350": 3}
PRICES = {"KB-101": 89.00, "MS-220": 39.50, "HD-350": 129.00}
@server.tool()
async def check_stock(sku: str) -> dict:
"""How many units of a product (by SKU) are in stock."""
if sku not in STOCK:
return {"sku": sku, "error": "unknown SKU"}
return {"sku": sku, "in_stock": STOCK[sku]}
@server.tool()
async def get_price(sku: str) -> dict:
"""The current price of a product (by SKU), in USD."""
if sku not in PRICES:
return {"sku": sku, "error": "unknown SKU"}
return {"sku": sku, "price_usd": PRICES[sku]}
if __name__ == "__main__":
server.run() # stdio by defaultHere is what happens on each run:
your code ──ainvoke──▶ Promptise agent ──tool definitions + messages──▶ Claude (Anthropic API)
│ ▲ │
│ └──────── tool_use: check_stock(KB-101) ◀┘
▼
MCP client ──stdio──▶ shop_server.py
│
└── tool result ──▶ next Claude call ──▶ final answerWhen the agent is built, Promptise connects to every server in servers=, lists its tools and turns each one into a LangChain tool with the MCP input schema. On every model call, those tools go to Claude as tool definitions. When Claude replies with a tool_use block, Promptise calls the MCP tool, adds the result to the conversation and calls Claude again. Promptise keeps Claude's reply message as returned, thinking blocks included, in the conversation between tool calls, which current Claude models expect.
To use a remote MCP server instead of a local script, replace the stdio spec with HTTPServerSpec(url="https://tools.example.com/mcp", bearer_token="...") from promptise.config. Nothing about the Claude side changes. The MCP connection guide covers transports, authentication and many servers at once.
Anthropic also offers a server-side MCP connector, where the Claude API itself connects to a remote MCP server. It is a different design: the API, not your process, holds the connection, so it only reaches servers that are publicly reachable. With Promptise, tool calls run in your process, so private servers, approval gates and guardrails all work.
[05]
Claude-specific notes
Settings current models accept
Claude Opus 5.5, Sonnet 5.5, Haiku 5.5 and the Fable models reject temperature, top_p and top_k at non-default values. Leave temperature out of Model(...) for these models. Thinking is adaptive and on by default, so you don't need a thinking setting. Control depth and cost with effort (low, medium, high, xhigh, max). On Opus 5.5 the default effort is medium, so set it explicitly if you want something else. Anthropic's models overview lists which settings each model supports.
Tool choice
Promptise binds tools with automatic tool choice: Claude decides whether to call a tool. This matters because the newest Claude models return an error for forced tool choice. Put "use the tools for stock and prices" in the instructions, as the example does, rather than forcing a call.
Prompt caching
An agent resends its system prompt and tool definitions on every turn. Anthropic's prompt caching makes repeated prefixes cheaper. You can turn on automatic caching through the same pass-through:
CLAUDE = Model(
"claude-opus-5-5",
provider="anthropic",
max_tokens=16000,
extra={"effort": "medium", "cache_control": {"type": "ephemeral"}},
)ChatAnthropic sends cache_control as a top-level request field, which tells the API to cache up to the last cacheable block. Caching only applies above a minimum prefix length, so a tiny agent like the example may see no cache reads. Check usage_metadata on the reply, or turn on agent observability, to confirm hits.
Limits and pricing
Rate limits depend on your organization's usage tier and are listed on Anthropic's rate limits page. Prices per million input and output tokens are on the pricing page. Prices differ a lot between Opus, Sonnet and Haiku, so put a budget on the agent before you run it on real traffic. The cost control guide shows how.
Claude through a gateway or a cloud provider
The endpoint= word overrides the base URL, for example for a corporate gateway that speaks the Anthropic API. For Claude on Amazon Bedrock, use the bedrock provider with a Bedrock model id instead. Bedrock's prices and limits are set by AWS.
Falling back to another provider
A FallbackChain tries models in order, so an Anthropic outage doesn't take the agent down:
from promptise import FallbackChain
model = FallbackChain(
[CLAUDE, "openai:gpt-5-mini"],
timeout_per_model=60,
)
agent = await make_agent(model=model)Keep the instructions provider-neutral if you do this, and test the agent with both models. More patterns are in the semantic cache and fallback guide.
[06]
Common problems and fixes
Symptom | Cause | Fix |
|---|---|---|
---|---|--- | ||
| The key isn't in the environment or in a .env file Promptise can find | Add it to .env next to the script, export it, or pass api_key= |
| The key is wrong, revoked or from another organization | Create a new key in the Claude Console and replace it |
A ValueError from LangChain saying temperature is not supported at non-default values, or a 400 about sampling parameters from the API | temperature, top_p or top_k set for a model that doesn't accept them | Remove them and use effort |
A 400 about tool_choice | A forced tool choice (any or a named tool), for example on a chat model you built yourself and passed in | Use automatic tool choice and steer the model with instructions |
A 404 not_found_error for the model | A typo in the id, or an id with a date suffix | Copy the id from the models overview page |
429 rate_limit_error | Your usage tier's request or token limit | Back off and retry, lower concurrency, or add a FallbackChain |
The agent answers without calling a tool | The instructions don't tell Claude when to use the tools | Say which questions need which tools, and check the tool descriptions on the server |
This is the real output of the ping with a key that isn't valid:
$ promptise models check claude:claude-opus-5-5 --ping
Pinging… failed
AnthropicAuthenticationError: Error code: 401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}, 'request_id': 'req_011Cg9mdnJ3S2ztDcLzirkwK'}
→ the provider rejected the credential — check ANTHROPIC_API_KEY (console.anthropic.com → API keys)[07]
Frequently asked questions
Do I need the Anthropic Python SDK to build a Claude agent with Promptise?
No separate install is needed. Promptise depends on langchain-anthropic, which depends on the official anthropic SDK, so both are installed with pip install promptise. You don't call the SDK directly: build_agent() builds the ChatAnthropic client from your Model settings and runs the tool loop for you.
Can a Claude agent use MCP servers that run on my own network?
Yes. Promptise is the MCP client, and it runs in your process, so it can reach a stdio server on the same machine or an HTTP server on a private network. Claude receives only the tool definitions and the tool results. This differs from a server-side MCP connector, which needs a server the Claude API can reach over the internet.
Which Claude model should I use for an AI agent?
Start with Claude Opus 5.5 for agents that plan across several tools, and move steps to Sonnet 5.5 or Haiku 5.5 when you can show they hold up on your own tasks. The way to decide is an evaluation on your real tool calls, which the best LLM for AI agents guide walks through.
How do I control how much Claude thinks?
Use effort. Pass it through Model(..., extra={"effort": "low"}), and Promptise forwards it to the Anthropic API as output_config.effort. Lower effort uses fewer tokens and fewer, more consolidated tool calls. Higher effort helps on hard multi-step tasks. Current models choose how much to think on their own within that setting.
Can I switch an existing agent from OpenAI to Claude?
Yes. Change the model string or Model(...) and keep the rest. Remove temperature if you set it, because current Claude models reject it. Then rerun your tests, because two models given the same tools and instructions won't make the same choices.
[08]
Next steps
Build the full agent step by step: how to build an AI agent.
Write the tool side properly: build a production MCP server.
Compare models on your own tasks: best LLM for AI agents.
Learn what MCP is and isn't: what is the Model Context Protocol.
Every provider setting in one place: Models and providers reference.