Spaces:
Running
Running
Merge pull request #674 from jlowin/anthropic
Browse filesAdd Anthropic + Claude desktop integration guides
- docs/clients/auth/bearer.mdx +12 -8
- docs/docs.json +5 -3
- docs/integrations/anthropic.mdx +225 -0
- docs/integrations/claude-desktop.mdx +221 -0
- docs/integrations/openai.mdx +4 -2
- docs/{deployment → patterns}/cli.mdx +15 -12
- server.py +26 -0
docs/clients/auth/bearer.mdx
CHANGED
|
@@ -30,23 +30,25 @@ The most straightforward way to use a pre-existing Bearer token is to provide it
|
|
| 30 |
If you're using a string token, do not include the `Bearer` prefix. FastMCP will add it for you.
|
| 31 |
</Tip>
|
| 32 |
|
| 33 |
-
```python {
|
| 34 |
from fastmcp import Client
|
| 35 |
|
| 36 |
async with Client(
|
| 37 |
-
"https://fastmcp.cloud/mcp",
|
|
|
|
| 38 |
) as client:
|
| 39 |
await client.ping()
|
| 40 |
```
|
| 41 |
|
| 42 |
You can also supply a Bearer token to a transport instance, such as `StreamableHttpTransport` or `SSETransport`:
|
| 43 |
|
| 44 |
-
```python {
|
| 45 |
from fastmcp import Client
|
| 46 |
from fastmcp.client.transports import StreamableHttpTransport
|
| 47 |
|
| 48 |
transport = StreamableHttpTransport(
|
| 49 |
-
"http://fastmcp.cloud/mcp",
|
|
|
|
| 50 |
)
|
| 51 |
|
| 52 |
async with Client(transport) as client:
|
|
@@ -57,12 +59,13 @@ async with Client(transport) as client:
|
|
| 57 |
|
| 58 |
If you prefer to be more explicit and not rely on FastMCP to transform your string token, you can use the `BearerAuth` class yourself, which implements the `httpx.Auth` interface.
|
| 59 |
|
| 60 |
-
```python {
|
| 61 |
from fastmcp import Client
|
| 62 |
from fastmcp.client.auth import BearerAuth
|
| 63 |
|
| 64 |
async with Client(
|
| 65 |
-
"https://fastmcp.cloud/mcp",
|
|
|
|
| 66 |
) as client:
|
| 67 |
await client.ping()
|
| 68 |
```
|
|
@@ -71,11 +74,12 @@ async with Client(
|
|
| 71 |
|
| 72 |
If the MCP server expects a custom header or token scheme, you can manually set the client's `headers` instead of using the `auth` parameter:
|
| 73 |
|
| 74 |
-
```python {
|
| 75 |
from fastmcp import Client
|
| 76 |
|
| 77 |
async with Client(
|
| 78 |
-
"https://fastmcp.cloud/mcp",
|
|
|
|
| 79 |
) as client:
|
| 80 |
await client.ping()
|
| 81 |
```
|
|
|
|
| 30 |
If you're using a string token, do not include the `Bearer` prefix. FastMCP will add it for you.
|
| 31 |
</Tip>
|
| 32 |
|
| 33 |
+
```python {5}
|
| 34 |
from fastmcp import Client
|
| 35 |
|
| 36 |
async with Client(
|
| 37 |
+
"https://fastmcp.cloud/mcp",
|
| 38 |
+
auth="<your-token>",
|
| 39 |
) as client:
|
| 40 |
await client.ping()
|
| 41 |
```
|
| 42 |
|
| 43 |
You can also supply a Bearer token to a transport instance, such as `StreamableHttpTransport` or `SSETransport`:
|
| 44 |
|
| 45 |
+
```python {6}
|
| 46 |
from fastmcp import Client
|
| 47 |
from fastmcp.client.transports import StreamableHttpTransport
|
| 48 |
|
| 49 |
transport = StreamableHttpTransport(
|
| 50 |
+
"http://fastmcp.cloud/mcp",
|
| 51 |
+
auth="<your-token>",
|
| 52 |
)
|
| 53 |
|
| 54 |
async with Client(transport) as client:
|
|
|
|
| 59 |
|
| 60 |
If you prefer to be more explicit and not rely on FastMCP to transform your string token, you can use the `BearerAuth` class yourself, which implements the `httpx.Auth` interface.
|
| 61 |
|
| 62 |
+
```python {6}
|
| 63 |
from fastmcp import Client
|
| 64 |
from fastmcp.client.auth import BearerAuth
|
| 65 |
|
| 66 |
async with Client(
|
| 67 |
+
"https://fastmcp.cloud/mcp",
|
| 68 |
+
auth=BearerAuth(token="<your-token>"),
|
| 69 |
) as client:
|
| 70 |
await client.ping()
|
| 71 |
```
|
|
|
|
| 74 |
|
| 75 |
If the MCP server expects a custom header or token scheme, you can manually set the client's `headers` instead of using the `auth` parameter:
|
| 76 |
|
| 77 |
+
```python {5}
|
| 78 |
from fastmcp import Client
|
| 79 |
|
| 80 |
async with Client(
|
| 81 |
+
"https://fastmcp.cloud/mcp",
|
| 82 |
+
headers={"X-API-Key": "<your-token>"},
|
| 83 |
) as client:
|
| 84 |
await client.ping()
|
| 85 |
```
|
docs/docs.json
CHANGED
|
@@ -71,8 +71,7 @@
|
|
| 71 |
"icon": "upload",
|
| 72 |
"pages": [
|
| 73 |
"deployment/running-server",
|
| 74 |
-
"deployment/asgi"
|
| 75 |
-
"deployment/cli"
|
| 76 |
]
|
| 77 |
}
|
| 78 |
]
|
|
@@ -96,6 +95,8 @@
|
|
| 96 |
{
|
| 97 |
"group": "Integrations",
|
| 98 |
"pages": [
|
|
|
|
|
|
|
| 99 |
"integrations/openai",
|
| 100 |
"integrations/contrib"
|
| 101 |
]
|
|
@@ -105,7 +106,8 @@
|
|
| 105 |
"pages": [
|
| 106 |
"patterns/decorating-methods",
|
| 107 |
"patterns/http-requests",
|
| 108 |
-
"patterns/testing"
|
|
|
|
| 109 |
]
|
| 110 |
}
|
| 111 |
]
|
|
|
|
| 71 |
"icon": "upload",
|
| 72 |
"pages": [
|
| 73 |
"deployment/running-server",
|
| 74 |
+
"deployment/asgi"
|
|
|
|
| 75 |
]
|
| 76 |
}
|
| 77 |
]
|
|
|
|
| 95 |
{
|
| 96 |
"group": "Integrations",
|
| 97 |
"pages": [
|
| 98 |
+
"integrations/anthropic",
|
| 99 |
+
"integrations/claude-desktop",
|
| 100 |
"integrations/openai",
|
| 101 |
"integrations/contrib"
|
| 102 |
]
|
|
|
|
| 106 |
"pages": [
|
| 107 |
"patterns/decorating-methods",
|
| 108 |
"patterns/http-requests",
|
| 109 |
+
"patterns/testing",
|
| 110 |
+
"patterns/cli"
|
| 111 |
]
|
| 112 |
}
|
| 113 |
]
|
docs/integrations/anthropic.mdx
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Anthropic
|
| 3 |
+
sidebarTitle: Anthropic
|
| 4 |
+
description: Access FastMCP servers from the Anthropic Messages API
|
| 5 |
+
icon: message-smile
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
import { VersionBadge } from "/snippets/version-badge.mdx"
|
| 9 |
+
|
| 10 |
+
Anthropic supports MCP servers through the [MCP connector](https://docs.anthropic.com/en/docs/agents-and-tools/mcp-connector) feature in the Messages API, allowing you to extend AI capabilities with custom tools from remote MCP servers.
|
| 11 |
+
|
| 12 |
+
## Messages API
|
| 13 |
+
|
| 14 |
+
Anthropic's [Messages API](https://docs.anthropic.com/en/api/messages) supports MCP servers as remote tool sources. This tutorial will show you how to create a FastMCP server and deploy it to a public URL, then how to call it from the Messages API.
|
| 15 |
+
|
| 16 |
+
<Tip>
|
| 17 |
+
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. You can read more about the MCP connector in the [Anthropic documentation](https://docs.anthropic.com/en/docs/agents-and-tools/mcp-connector).
|
| 18 |
+
</Tip>
|
| 19 |
+
|
| 20 |
+
### Create a Server
|
| 21 |
+
|
| 22 |
+
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.
|
| 23 |
+
|
| 24 |
+
```python server.py
|
| 25 |
+
import random
|
| 26 |
+
from fastmcp import FastMCP
|
| 27 |
+
|
| 28 |
+
mcp = FastMCP(name="Dice Roller")
|
| 29 |
+
|
| 30 |
+
@mcp.tool()
|
| 31 |
+
def roll_dice(n_dice: int) -> list[int]:
|
| 32 |
+
"""Roll `n_dice` 6-sided dice and return the results."""
|
| 33 |
+
return [random.randint(1, 6) for _ in range(n_dice)]
|
| 34 |
+
|
| 35 |
+
if __name__ == "__main__":
|
| 36 |
+
mcp.run(transport="sse", port=8000)
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
### Deploy the Server
|
| 40 |
+
|
| 41 |
+
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.
|
| 42 |
+
|
| 43 |
+
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.
|
| 44 |
+
|
| 45 |
+
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:
|
| 46 |
+
|
| 47 |
+
<CodeGroup>
|
| 48 |
+
```bash FastMCP server
|
| 49 |
+
python server.py
|
| 50 |
+
```
|
| 51 |
+
|
| 52 |
+
```bash ngrok
|
| 53 |
+
ngrok http 8000
|
| 54 |
+
```
|
| 55 |
+
</CodeGroup>
|
| 56 |
+
|
| 57 |
+
<Warning>
|
| 58 |
+
This exposes your unauthenticated server to the internet. Only run this command in a safe environment if you understand the risks.
|
| 59 |
+
</Warning>
|
| 60 |
+
|
| 61 |
+
### Call the Server
|
| 62 |
+
|
| 63 |
+
To use the Messages API with MCP servers, you'll need to install the Anthropic Python SDK (not included with FastMCP):
|
| 64 |
+
|
| 65 |
+
```bash
|
| 66 |
+
pip install anthropic
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
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. **At this time you must also include the `extra_headers` parameter with the `anthropic-beta` header.**
|
| 70 |
+
|
| 71 |
+
```python {5, 13-22}
|
| 72 |
+
import anthropic
|
| 73 |
+
from rich import print
|
| 74 |
+
|
| 75 |
+
# Your server URL (replace with your actual URL)
|
| 76 |
+
url = 'https://your-server-url.com'
|
| 77 |
+
|
| 78 |
+
client = anthropic.Anthropic()
|
| 79 |
+
|
| 80 |
+
response = client.beta.messages.create(
|
| 81 |
+
model="claude-sonnet-4-20250514",
|
| 82 |
+
max_tokens=1000,
|
| 83 |
+
messages=[{"role": "user", "content": "Roll a few dice!"}],
|
| 84 |
+
mcp_servers=[
|
| 85 |
+
{
|
| 86 |
+
"type": "url",
|
| 87 |
+
"url": f"{url}/sse",
|
| 88 |
+
"name": "dice-server",
|
| 89 |
+
}
|
| 90 |
+
],
|
| 91 |
+
extra_headers={
|
| 92 |
+
"anthropic-beta": "mcp-client-2025-04-04"
|
| 93 |
+
}
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
print(response.content)
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
If you run this code, you'll see something like the following output:
|
| 100 |
+
|
| 101 |
+
```text
|
| 102 |
+
I'll roll some dice for you! Let me use the dice rolling tool.
|
| 103 |
+
|
| 104 |
+
I rolled 3 dice and got: 4, 2, 6
|
| 105 |
+
|
| 106 |
+
The results were 4, 2, and 6. Would you like me to roll again or roll a different number of dice?
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
### Authentication
|
| 111 |
+
|
| 112 |
+
<VersionBadge version="2.6.0" />
|
| 113 |
+
|
| 114 |
+
The MCP connector supports OAuth authentication through authorization tokens, which means you can secure your server while still allowing Anthropic to access it.
|
| 115 |
+
|
| 116 |
+
#### Server Authentication
|
| 117 |
+
|
| 118 |
+
The simplest way to add authentication to the server is to use a bearer token scheme.
|
| 119 |
+
|
| 120 |
+
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.
|
| 121 |
+
|
| 122 |
+
We'll start by creating an RSA key pair to sign and verify tokens.
|
| 123 |
+
|
| 124 |
+
```python
|
| 125 |
+
from fastmcp.server.auth.providers.bearer import RSAKeyPair
|
| 126 |
+
|
| 127 |
+
key_pair = RSAKeyPair.generate()
|
| 128 |
+
access_token = key_pair.create_token(audience="dice-server")
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
<Warning>
|
| 132 |
+
FastMCP's `RSAKeyPair` utility is for development and testing only.
|
| 133 |
+
</Warning>
|
| 134 |
+
|
| 135 |
+
Next, we'll create a `BearerAuthProvider` to authenticate the server.
|
| 136 |
+
|
| 137 |
+
```python
|
| 138 |
+
from fastmcp import FastMCP
|
| 139 |
+
from fastmcp.server.auth import BearerAuthProvider
|
| 140 |
+
|
| 141 |
+
auth = BearerAuthProvider(
|
| 142 |
+
public_key=key_pair.public_key,
|
| 143 |
+
audience="dice-server",
|
| 144 |
+
)
|
| 145 |
+
|
| 146 |
+
mcp = FastMCP(name="Dice Roller", auth=auth)
|
| 147 |
+
```
|
| 148 |
+
|
| 149 |
+
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!**
|
| 150 |
+
|
| 151 |
+
```python server.py [expandable]
|
| 152 |
+
from fastmcp import FastMCP
|
| 153 |
+
from fastmcp.server.auth import BearerAuthProvider
|
| 154 |
+
from fastmcp.server.auth.providers.bearer import RSAKeyPair
|
| 155 |
+
import random
|
| 156 |
+
|
| 157 |
+
key_pair = RSAKeyPair.generate()
|
| 158 |
+
access_token = key_pair.create_token(audience="dice-server")
|
| 159 |
+
|
| 160 |
+
auth = BearerAuthProvider(
|
| 161 |
+
public_key=key_pair.public_key,
|
| 162 |
+
audience="dice-server",
|
| 163 |
+
)
|
| 164 |
+
|
| 165 |
+
mcp = FastMCP(name="Dice Roller", auth=auth)
|
| 166 |
+
|
| 167 |
+
@mcp.tool()
|
| 168 |
+
def roll_dice(n_dice: int) -> list[int]:
|
| 169 |
+
"""Roll `n_dice` 6-sided dice and return the results."""
|
| 170 |
+
return [random.randint(1, 6) for _ in range(n_dice)]
|
| 171 |
+
|
| 172 |
+
if __name__ == "__main__":
|
| 173 |
+
print(f"\n---\n\n🔑 Dice Roller access token:\n\n{access_token}\n\n---\n")
|
| 174 |
+
mcp.run(transport="sse", port=8000)
|
| 175 |
+
```
|
| 176 |
+
|
| 177 |
+
#### Client Authentication
|
| 178 |
+
|
| 179 |
+
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.
|
| 180 |
+
|
| 181 |
+
```python
|
| 182 |
+
Error code: 400 - {
|
| 183 |
+
"type": "error",
|
| 184 |
+
"error": {
|
| 185 |
+
"type": "invalid_request_error",
|
| 186 |
+
"message": "MCP server 'dice-server' requires authentication. Please provide an authorization_token.",
|
| 187 |
+
},
|
| 188 |
+
}
|
| 189 |
+
```
|
| 190 |
+
|
| 191 |
+
To authenticate the client, you can pass the token using the `authorization_token` parameter in your MCP server configuration:
|
| 192 |
+
|
| 193 |
+
```python {8, 21}
|
| 194 |
+
import anthropic
|
| 195 |
+
from rich import print
|
| 196 |
+
|
| 197 |
+
# Your server URL (replace with your actual URL)
|
| 198 |
+
url = 'https://your-server-url.com'
|
| 199 |
+
|
| 200 |
+
# Your access token (replace with your actual token)
|
| 201 |
+
access_token = 'your-access-token'
|
| 202 |
+
|
| 203 |
+
client = anthropic.Anthropic()
|
| 204 |
+
|
| 205 |
+
response = client.beta.messages.create(
|
| 206 |
+
model="claude-sonnet-4-20250514",
|
| 207 |
+
max_tokens=1000,
|
| 208 |
+
messages=[{"role": "user", "content": "Roll a few dice!"}],
|
| 209 |
+
mcp_servers=[
|
| 210 |
+
{
|
| 211 |
+
"type": "url",
|
| 212 |
+
"url": f"{url}/sse",
|
| 213 |
+
"name": "dice-server",
|
| 214 |
+
"authorization_token": access_token
|
| 215 |
+
}
|
| 216 |
+
],
|
| 217 |
+
extra_headers={
|
| 218 |
+
"anthropic-beta": "mcp-client-2025-04-04"
|
| 219 |
+
}
|
| 220 |
+
)
|
| 221 |
+
|
| 222 |
+
print(response.content)
|
| 223 |
+
```
|
| 224 |
+
|
| 225 |
+
You should now see the dice roll results in the output.
|
docs/integrations/claude-desktop.mdx
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Claude Desktop
|
| 3 |
+
sidebarTitle: Claude Desktop
|
| 4 |
+
description: Integrate FastMCP servers with Claude Desktop
|
| 5 |
+
icon: desktop
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
Claude Desktop supports MCP servers through local STDIO connections, allowing you to extend Claude's capabilities with custom tools, resources, and prompts from your FastMCP servers.
|
| 10 |
+
|
| 11 |
+
<Note>
|
| 12 |
+
This guide focuses specifically on using FastMCP servers with Claude Desktop. For general Claude Desktop MCP setup and official examples, see the [official Claude Desktop quickstart guide](https://modelcontextprotocol.io/quickstart/user).
|
| 13 |
+
</Note>
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
## Requirements
|
| 17 |
+
|
| 18 |
+
Claude Desktop requires MCP servers to run locally using STDIO transport. This means your server will communicate with Claude through standard input/output rather than HTTP.
|
| 19 |
+
|
| 20 |
+
<Tip>
|
| 21 |
+
If you need to connect to remote servers, you can create a **proxy server** that runs locally via STDIO and forwards requests to remote HTTP servers. See the [Proxy Servers](#proxy-servers) section below.
|
| 22 |
+
</Tip>
|
| 23 |
+
|
| 24 |
+
## Create a Server
|
| 25 |
+
|
| 26 |
+
The examples in this guide will use the following simple dice-rolling server, saved as `server.py`.
|
| 27 |
+
|
| 28 |
+
```python server.py
|
| 29 |
+
import random
|
| 30 |
+
from fastmcp import FastMCP
|
| 31 |
+
|
| 32 |
+
mcp = FastMCP(name="Dice Roller")
|
| 33 |
+
|
| 34 |
+
@mcp.tool()
|
| 35 |
+
def roll_dice(n_dice: int) -> list[int]:
|
| 36 |
+
"""Roll `n_dice` 6-sided dice and return the results."""
|
| 37 |
+
return [random.randint(1, 6) for _ in range(n_dice)]
|
| 38 |
+
|
| 39 |
+
if __name__ == "__main__":
|
| 40 |
+
mcp.run()
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
## Install the Server
|
| 44 |
+
|
| 45 |
+
### FastMCP CLI
|
| 46 |
+
|
| 47 |
+
The easiest way to install a FastMCP server in Claude Desktop is using the `fastmcp install` command. This automatically handles the configuration and dependency management.
|
| 48 |
+
|
| 49 |
+
```bash
|
| 50 |
+
fastmcp install server.py
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
The install command supports the same `file.py:object` notation as the `run` command. If no object is specified, it will automatically look for a FastMCP server object named `mcp`, `server`, or `app` in your file:
|
| 54 |
+
|
| 55 |
+
```bash
|
| 56 |
+
# These are equivalent if your server object is named 'mcp'
|
| 57 |
+
fastmcp install server.py
|
| 58 |
+
fastmcp install server.py:mcp
|
| 59 |
+
|
| 60 |
+
# Use explicit object name if your server has a different name
|
| 61 |
+
fastmcp install server.py:my_custom_server
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
After installation, restart Claude Desktop completely. You should see a hammer icon (🔨) in the bottom left of the input box, indicating that MCP tools are available.
|
| 65 |
+
|
| 66 |
+
#### Dependencies
|
| 67 |
+
|
| 68 |
+
If your server has dependencies, include them with the `--with` flag:
|
| 69 |
+
|
| 70 |
+
```bash
|
| 71 |
+
fastmcp install server.py --with pandas --with requests
|
| 72 |
+
```
|
| 73 |
+
|
| 74 |
+
Alternatively, you can specify dependencies directly in your server code:
|
| 75 |
+
|
| 76 |
+
```python server.py
|
| 77 |
+
from fastmcp import FastMCP
|
| 78 |
+
|
| 79 |
+
mcp = FastMCP(
|
| 80 |
+
name="Dice Roller",
|
| 81 |
+
dependencies=["pandas", "requests"]
|
| 82 |
+
)
|
| 83 |
+
```
|
| 84 |
+
|
| 85 |
+
#### Environment Variables
|
| 86 |
+
|
| 87 |
+
<Warning>
|
| 88 |
+
Claude Desktop runs servers in a completely isolated environment with no access to your shell environment or locally installed applications. You must explicitly pass any environment variables your server needs.
|
| 89 |
+
</Warning>
|
| 90 |
+
|
| 91 |
+
If your server needs environment variables (like API keys), you must include them:
|
| 92 |
+
|
| 93 |
+
```bash
|
| 94 |
+
fastmcp install server.py --name "Weather Server" \
|
| 95 |
+
--env-var API_KEY=your-api-key \
|
| 96 |
+
--env-var DEBUG=true
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
Or load them from a `.env` file:
|
| 100 |
+
|
| 101 |
+
```bash
|
| 102 |
+
fastmcp install server.py --name "Weather Server" --env-file .env
|
| 103 |
+
```
|
| 104 |
+
<Warning>
|
| 105 |
+
- **`uv` must be installed and available in your system PATH**. Claude Desktop runs in its own isolated environment and needs `uv` to manage dependencies.
|
| 106 |
+
- **On macOS, it is recommended to install `uv` globally with Homebrew** so that Claude Desktop will detect it: `brew install uv`. Installing `uv` with other methods may not make it accessible to Claude Desktop.
|
| 107 |
+
</Warning>
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
### Manual Configuration
|
| 111 |
+
|
| 112 |
+
For more control over the configuration, you can manually edit Claude Desktop's configuration file. You can open the configuration file from Claude's developer settings, or find it in the following locations:
|
| 113 |
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
| 114 |
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
| 115 |
+
|
| 116 |
+
The configuration file is a JSON object with a `mcpServers` key, which contains the configuration for each MCP server.
|
| 117 |
+
|
| 118 |
+
```json
|
| 119 |
+
{
|
| 120 |
+
"mcpServers": {
|
| 121 |
+
"dice-roller": {
|
| 122 |
+
"command": "python",
|
| 123 |
+
"args": ["path/to/your/server.py"]
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
```
|
| 128 |
+
|
| 129 |
+
After updating the configuration file, restart Claude Desktop completely. Look for the hammer icon (🔨) to confirm your server is loaded.
|
| 130 |
+
|
| 131 |
+
#### Dependencies
|
| 132 |
+
|
| 133 |
+
If your server has dependencies, you can use `uv` or another package manager to set up the environment.
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
```json
|
| 137 |
+
{
|
| 138 |
+
"mcpServers": {
|
| 139 |
+
"dice-roller": {
|
| 140 |
+
"command": "uv",
|
| 141 |
+
"args": [
|
| 142 |
+
"run",
|
| 143 |
+
"--with", "pandas",
|
| 144 |
+
"--with", "requests",
|
| 145 |
+
"python",
|
| 146 |
+
"path/to/your/server.py"
|
| 147 |
+
]
|
| 148 |
+
}
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
<Warning>
|
| 154 |
+
- **`uv` must be installed and available in your system PATH**. Claude Desktop runs in its own isolated environment and needs `uv` to manage dependencies.
|
| 155 |
+
- **On macOS, it is recommended to install `uv` globally with Homebrew** so that Claude Desktop will detect it: `brew install uv`. Installing `uv` with other methods may not make it accessible to Claude Desktop.
|
| 156 |
+
</Warning>
|
| 157 |
+
|
| 158 |
+
#### Environment Variables
|
| 159 |
+
|
| 160 |
+
You can also specify environment variables in the configuration:
|
| 161 |
+
|
| 162 |
+
```json
|
| 163 |
+
{
|
| 164 |
+
"mcpServers": {
|
| 165 |
+
"weather-server": {
|
| 166 |
+
"command": "python",
|
| 167 |
+
"args": ["path/to/weather_server.py"],
|
| 168 |
+
"env": {
|
| 169 |
+
"API_KEY": "your-api-key",
|
| 170 |
+
"DEBUG": "true"
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
```
|
| 176 |
+
<Warning>
|
| 177 |
+
Claude Desktop runs servers in a completely isolated environment with no access to your shell environment or locally installed applications. You must explicitly pass any environment variables your server needs.
|
| 178 |
+
</Warning>
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
## Remote Servers
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
Claude Desktop only supports local STDIO servers, but FastMCP can create a proxy server that forwards requests to a remote HTTP server. You can install the proxy server in Claude Desktop.
|
| 185 |
+
|
| 186 |
+
Create a proxy server that connects to a remote HTTP server:
|
| 187 |
+
|
| 188 |
+
```python proxy_server.py
|
| 189 |
+
from fastmcp import FastMCP
|
| 190 |
+
|
| 191 |
+
# Create a proxy to a remote server
|
| 192 |
+
proxy = FastMCP.as_proxy(
|
| 193 |
+
"https://example.com/mcp/sse",
|
| 194 |
+
name="Remote Server Proxy"
|
| 195 |
+
)
|
| 196 |
+
|
| 197 |
+
if __name__ == "__main__":
|
| 198 |
+
proxy.run() # Runs via STDIO for Claude Desktop
|
| 199 |
+
```
|
| 200 |
+
|
| 201 |
+
### Authentication
|
| 202 |
+
|
| 203 |
+
For authenticated remote servers, create an authenticated client following the guidance in the [client auth documentation](/clients/auth/bearer) and pass it to the proxy:
|
| 204 |
+
|
| 205 |
+
```python auth_proxy_server.py {7}
|
| 206 |
+
from fastmcp import FastMCP, Client
|
| 207 |
+
from fastmcp.client.auth import BearerAuth
|
| 208 |
+
|
| 209 |
+
# Create authenticated client
|
| 210 |
+
client = Client(
|
| 211 |
+
"https://api.example.com/mcp/sse",
|
| 212 |
+
auth=BearerAuth(token="your-access-token")
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
# Create proxy using the authenticated client
|
| 216 |
+
proxy = FastMCP.as_proxy(client, name="Authenticated Proxy")
|
| 217 |
+
|
| 218 |
+
if __name__ == "__main__":
|
| 219 |
+
proxy.run()
|
| 220 |
+
```
|
| 221 |
+
|
docs/integrations/openai.mdx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
---
|
| 2 |
title: OpenAI
|
| 3 |
sidebarTitle: OpenAI
|
| 4 |
-
description:
|
| 5 |
icon: message-smile
|
| 6 |
---
|
| 7 |
|
|
@@ -123,7 +123,9 @@ key_pair = RSAKeyPair.generate()
|
|
| 123 |
access_token = key_pair.create_token(audience="dice-server")
|
| 124 |
```
|
| 125 |
|
| 126 |
-
|
|
|
|
|
|
|
| 127 |
|
| 128 |
Next, we'll create a `BearerAuthProvider` to authenticate the server.
|
| 129 |
|
|
|
|
| 1 |
---
|
| 2 |
title: OpenAI
|
| 3 |
sidebarTitle: OpenAI
|
| 4 |
+
description: Access FastMCP servers from the OpenAI API
|
| 5 |
icon: message-smile
|
| 6 |
---
|
| 7 |
|
|
|
|
| 123 |
access_token = key_pair.create_token(audience="dice-server")
|
| 124 |
```
|
| 125 |
|
| 126 |
+
<Warning>
|
| 127 |
+
FastMCP's `RSAKeyPair` utility is for development and testing only.
|
| 128 |
+
</Warning>
|
| 129 |
|
| 130 |
Next, we'll create a `BearerAuthProvider` to authenticate the server.
|
| 131 |
|
docs/{deployment → patterns}/cli.mdx
RENAMED
|
@@ -148,8 +148,8 @@ Install a MCP server in the Claude desktop app.
|
|
| 148 |
fastmcp install server.py
|
| 149 |
```
|
| 150 |
|
| 151 |
-
|
| 152 |
Note that for security reasons, Claude runs every MCP server in a completely isolated environment. Therefore, all dependencies must be explicitly specified using the `--with` and/or `--with-editable` options (following `uv` conventions) or by attaching them to your server in code via the `dependencies` parameter.
|
|
|
|
| 153 |
<Warning>
|
| 154 |
- **`uv` must be installed and available in your system PATH**. Claude Desktop runs in its own isolated environment and needs `uv` to manage dependencies.
|
| 155 |
- **On macOS, it is recommended to install `uv` globally with Homebrew** so that Claude Desktop will detect it: `brew install uv`. Installing `uv` with other methods may not make it accessible to Claude Desktop.
|
|
@@ -159,21 +159,24 @@ Note that for security reasons, Claude runs every MCP server in a completely iso
|
|
| 159 |
The `install` command currently only sets up servers for STDIO transport. When installed in the Claude desktop app, your server will be run using STDIO regardless of any transport configuration in your code.
|
| 160 |
</Warning>
|
| 161 |
|
| 162 |
-
####
|
| 163 |
|
| 164 |
-
|
| 165 |
-
| ------ | ---- | ----------- |
|
| 166 |
-
| Server Name | `--name`, `-n` | Custom name for the server |
|
| 167 |
-
| Editable Package | `--with-editable`, `-e` | Directory containing pyproject.toml to install in editable mode |
|
| 168 |
-
| Additional Packages | `--with` | Additional packages to install (can be used multiple times) |
|
| 169 |
-
| Environment Variables | `--env-var`, `-v` | Environment variables in KEY=VALUE format (can be used multiple times) |
|
| 170 |
-
| Environment File | `--env-file`, `-f` | Load environment variables from a .env file |
|
| 171 |
|
| 172 |
-
|
|
|
|
|
|
|
|
|
|
| 173 |
|
| 174 |
```bash
|
| 175 |
-
#
|
| 176 |
-
fastmcp install server.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
```
|
| 178 |
|
| 179 |
### `version`
|
|
|
|
| 148 |
fastmcp install server.py
|
| 149 |
```
|
| 150 |
|
|
|
|
| 151 |
Note that for security reasons, Claude runs every MCP server in a completely isolated environment. Therefore, all dependencies must be explicitly specified using the `--with` and/or `--with-editable` options (following `uv` conventions) or by attaching them to your server in code via the `dependencies` parameter.
|
| 152 |
+
|
| 153 |
<Warning>
|
| 154 |
- **`uv` must be installed and available in your system PATH**. Claude Desktop runs in its own isolated environment and needs `uv` to manage dependencies.
|
| 155 |
- **On macOS, it is recommended to install `uv` globally with Homebrew** so that Claude Desktop will detect it: `brew install uv`. Installing `uv` with other methods may not make it accessible to Claude Desktop.
|
|
|
|
| 159 |
The `install` command currently only sets up servers for STDIO transport. When installed in the Claude desktop app, your server will be run using STDIO regardless of any transport configuration in your code.
|
| 160 |
</Warning>
|
| 161 |
|
| 162 |
+
#### Server Specification
|
| 163 |
|
| 164 |
+
The `install` command supports the same `file.py:object` notation as the `run` command:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
|
| 166 |
+
1. `server.py` - imports the module and looks for a FastMCP object named `mcp`, `server`, or `app`. Errors if no such object is found.
|
| 167 |
+
2. `server.py:custom_name` - imports and uses the specified server object
|
| 168 |
+
|
| 169 |
+
**Examples**
|
| 170 |
|
| 171 |
```bash
|
| 172 |
+
# Auto-detects server object (looks for 'mcp', 'server', or 'app')
|
| 173 |
+
fastmcp install server.py
|
| 174 |
+
|
| 175 |
+
# Uses specific server object
|
| 176 |
+
fastmcp install server.py:my_server
|
| 177 |
+
|
| 178 |
+
# With custom name and dependencies
|
| 179 |
+
fastmcp install server.py:my_server -n "My Analysis Server" --with pandas
|
| 180 |
```
|
| 181 |
|
| 182 |
### `version`
|
server.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
|
| 3 |
+
from fastmcp import FastMCP
|
| 4 |
+
from fastmcp.server.auth import BearerAuthProvider
|
| 5 |
+
from fastmcp.server.auth.providers.bearer import RSAKeyPair
|
| 6 |
+
|
| 7 |
+
key_pair = RSAKeyPair.generate()
|
| 8 |
+
access_token = key_pair.create_token(audience="dice-server")
|
| 9 |
+
|
| 10 |
+
auth = BearerAuthProvider(
|
| 11 |
+
public_key=key_pair.public_key,
|
| 12 |
+
audience="dice-server",
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
mcp = FastMCP(name="Dice Roller", auth=auth)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
@mcp.tool()
|
| 19 |
+
def roll_dice(n_dice: int) -> list[int]:
|
| 20 |
+
"""Roll `n_dice` 6-sided dice and return the results."""
|
| 21 |
+
return [random.randint(1, 6) for _ in range(n_dice)]
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
if __name__ == "__main__":
|
| 25 |
+
print(f"\n---\n\n🔑 Dice Roller access token:\n\n{access_token}\n\n---\n")
|
| 26 |
+
mcp.run(transport="sse", port=8000)
|