diff --git a/docs/docs.json b/docs/docs.json
index d97de5dfc..2007456f5 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -97,6 +97,7 @@
"group": "Integrations",
"pages": [
"integrations/openai",
+ "integrations/anthropic",
"integrations/contrib"
]
},
diff --git a/docs/integrations/anthropic.mdx b/docs/integrations/anthropic.mdx
new file mode 100644
index 000000000..f452a334c
--- /dev/null
+++ b/docs/integrations/anthropic.mdx
@@ -0,0 +1,226 @@
+---
+title: Anthropic
+sidebarTitle: Anthropic
+description: Integrate FastMCP servers with the Anthropic Messages API
+icon: message-smile
+---
+
+import { VersionBadge } from "/snippets/version-badge.mdx"
+
+Anthropic's Claude supports MCP servers through the MCP connector feature in the Messages API, allowing you to extend AI capabilities with custom tools from remote MCP servers.
+
+## Messages API
+
+Anthropic's [Messages API](https://docs.anthropic.com/en/api/messages) supports [MCP servers](https://docs.anthropic.com/en/docs/agents-and-tools/mcp-connector) as remote tool sources through the MCP connector feature.
+
+
+
+Currently, the MCP connector only accesses **tools** from MCP servers—it queries the `list_tools` endpoint and exposes those functions to Claude. Other MCP features like resources and prompts are not currently supported.
+
+
+### Create a Server
+
+First, create a FastMCP server with the tools you want to expose. For this example, we'll create a server with a single tool that rolls dice.
+
+```python server.py
+import random
+from fastmcp import FastMCP
+
+mcp = FastMCP(name="Dice Roller")
+
+@mcp.tool()
+def roll_dice(n_dice: int) -> list[int]:
+ """Roll `n_dice` 6-sided dice and return the results."""
+ return [random.randint(1, 6) for _ in range(n_dice)]
+
+if __name__ == "__main__":
+ mcp.run(transport="sse", port=8000)
+```
+
+### Deploy the Server
+
+Your server must be deployed to a public URL in order for Anthropic to access it. The MCP connector supports both SSE and Streamable HTTP transports.
+
+For development, you can use tools like `ngrok` to temporarily expose a locally-running server to the internet. We'll do that for this example (you may need to install `ngrok` and create a free account), but you can use any other method to deploy your server.
+
+Assuming you saved the above code as `server.py`, you can run the following two commands in two separate terminals to deploy your server and expose it to the internet:
+
+
+```bash FastMCP server
+python server.py
+```
+
+```bash ngrok
+ngrok http 8000
+```
+
+
+
+This exposes your unauthenticated server to the internet. Only run this command in a safe environment if you understand the risks.
+
+
+### Call the Server
+
+To use the Messages API with MCP servers, you'll need to install the Anthropic Python SDK (not included with FastMCP):
+
+```bash
+pip install anthropic
+```
+
+Here is an example of how to call your server from Python. Note that you'll need to replace `https://your-server-url.com` with the actual URL of your server. In addition, we use `/sse` as the endpoint because we deployed an SSE server with the default path; you may need to use a different endpoint if you customized your server's deployment.
+
+```python {4, 12-19}
+import anthropic
+from rich import print
+
+# Your server URL (replace with your actual URL)
+url = 'https://your-server-url.com'
+
+client = anthropic.Anthropic()
+
+response = client.beta.messages.create(
+ model="claude-sonnet-4-20250514",
+ max_tokens=1000,
+ messages=[{"role": "user", "content": "Roll a few dice!"}],
+ mcp_servers=[
+ {
+ "type": "url",
+ "url": f"{url}/sse",
+ "name": "dice-server",
+ }
+ ],
+ extra_headers={
+ "anthropic-beta": "mcp-client-2025-04-04"
+ }
+)
+
+print(response.content)
+```
+
+If you run this code, you'll see something like the following output:
+
+```text
+I'll roll some dice for you! Let me use the dice rolling tool.
+
+I rolled 3 dice and got: 4, 2, 6
+
+The results were 4, 2, and 6. Would you like me to roll again or roll a different number of dice?
+```
+
+
+### Authentication
+
+
+
+The MCP connector supports OAuth authentication through authorization tokens, which means you can secure your server while still allowing Anthropic to access it.
+
+#### Server Authentication
+
+The simplest way to add authentication to the server is to use a bearer token scheme.
+
+For this example, we'll quickly generate our own tokens with FastMCP's `RSAKeyPair` utility, but this may not be appropriate for production use. For more details, see the complete server-side [Bearer Auth](/servers/auth/bearer) documentation.
+
+We'll start by creating an RSA key pair to sign and verify tokens.
+
+```python
+from fastmcp.server.auth.providers.bearer import RSAKeyPair
+
+key_pair = RSAKeyPair.generate()
+access_token = key_pair.create_token(audience="dice-server")
+```
+
+
+FastMCP's `RSAKeyPair` utility is for development and testing only.
+
+
+Next, we'll create a `BearerAuthProvider` to authenticate the server.
+
+```python
+from fastmcp import FastMCP
+from fastmcp.server.auth import BearerAuthProvider
+
+auth = BearerAuthProvider(
+ public_key=key_pair.public_key,
+ audience="dice-server",
+)
+
+mcp = FastMCP(name="Dice Roller", auth=auth)
+```
+
+Here is a complete example that you can copy/paste. For simplicity and the purposes of this example only, it will print the token to the console. **Do NOT do this in production!**
+
+```python server.py [expandable]
+from fastmcp import FastMCP
+from fastmcp.server.auth import BearerAuthProvider
+from fastmcp.server.auth.providers.bearer import RSAKeyPair
+import random
+
+key_pair = RSAKeyPair.generate()
+access_token = key_pair.create_token(audience="dice-server")
+
+auth = BearerAuthProvider(
+ public_key=key_pair.public_key,
+ audience="dice-server",
+)
+
+mcp = FastMCP(name="Dice Roller", auth=auth)
+
+@mcp.tool()
+def roll_dice(n_dice: int) -> list[int]:
+ """Roll `n_dice` 6-sided dice and return the results."""
+ return [random.randint(1, 6) for _ in range(n_dice)]
+
+if __name__ == "__main__":
+ print(f"\n---\n\n🔑 Dice Roller access token:\n\n{access_token}\n\n---\n")
+ mcp.run(transport="sse", port=8000)
+```
+
+#### Client Authentication
+
+If you try to call the authenticated server with the same Anthropic code we wrote earlier, you'll get an error indicating that the server rejected the request because it's not authenticated.
+
+```python
+Error code: 400 - {
+ "type": "error",
+ "error": {
+ "type": "invalid_request_error",
+ "message": "MCP server 'dice-server' requires authentication. Please provide an authorization_token.",
+ },
+}
+```
+
+To authenticate the client, you can pass the token using the `authorization_token` parameter in your MCP server configuration:
+
+```python {7, 17}
+import anthropic
+from rich import print
+
+# Your server URL (replace with your actual URL)
+url = 'https://your-server-url.com'
+
+# Your access token (replace with your actual token)
+access_token = 'your-access-token'
+
+client = anthropic.Anthropic()
+
+response = client.beta.messages.create(
+ model="claude-sonnet-4-20250514",
+ max_tokens=1000,
+ messages=[{"role": "user", "content": "Roll a few dice!"}],
+ mcp_servers=[
+ {
+ "type": "url",
+ "url": f"{url}/sse",
+ "name": "dice-server",
+ "authorization_token": access_token
+ }
+ ],
+ extra_headers={
+ "anthropic-beta": "mcp-client-2025-04-04"
+ }
+)
+
+print(response.content)
+```
+
+You should now see the dice roll results in the output.
diff --git a/docs/integrations/openai.mdx b/docs/integrations/openai.mdx
index cad473d5e..4830c6804 100644
--- a/docs/integrations/openai.mdx
+++ b/docs/integrations/openai.mdx
@@ -123,7 +123,9 @@ key_pair = RSAKeyPair.generate()
access_token = key_pair.create_token(audience="dice-server")
```
-This will generate a new RSA key pair and a corresponding access token.
+
+FastMCP's `RSAKeyPair` utility is for development and testing only.
+
Next, we'll create a `BearerAuthProvider` to authenticate the server.
diff --git a/server.py b/server.py
new file mode 100644
index 000000000..0ddc68740
--- /dev/null
+++ b/server.py
@@ -0,0 +1,26 @@
+import random
+
+from fastmcp import FastMCP
+from fastmcp.server.auth import BearerAuthProvider
+from fastmcp.server.auth.providers.bearer import RSAKeyPair
+
+key_pair = RSAKeyPair.generate()
+access_token = key_pair.create_token(audience="dice-server")
+
+auth = BearerAuthProvider(
+ public_key=key_pair.public_key,
+ audience="dice-server",
+)
+
+mcp = FastMCP(name="Dice Roller", auth=auth)
+
+
+@mcp.tool()
+def roll_dice(n_dice: int) -> list[int]:
+ """Roll `n_dice` 6-sided dice and return the results."""
+ return [random.randint(1, 6) for _ in range(n_dice)]
+
+
+if __name__ == "__main__":
+ print(f"\n---\n\n🔑 Dice Roller access token:\n\n{access_token}\n\n---\n")
+ mcp.run(transport="sse", port=8000)