diff --git a/docs/docs.json b/docs/docs.json index a4c24b519..cb6f4062b 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -68,6 +68,7 @@ "servers/composition", { "group": "Deployment", + "icon": "network-wired", "pages": [ "deployment/running-server", "deployment/asgi", @@ -92,18 +93,20 @@ "clients/advanced-features" ] }, + { + "group": "Integrations", + "pages": [ + "integrations/openai", + "integrations/contrib" + ] + }, { "group": "Patterns", "pages": [ "patterns/decorating-methods", "patterns/http-requests", - "patterns/contrib", "patterns/testing" ] - }, - { - "group": "Deployment", - "pages": [] } ] }, diff --git a/docs/patterns/contrib.mdx b/docs/integrations/contrib.mdx similarity index 100% rename from docs/patterns/contrib.mdx rename to docs/integrations/contrib.mdx diff --git a/docs/integrations/openai.mdx b/docs/integrations/openai.mdx new file mode 100644 index 000000000..4aab943be --- /dev/null +++ b/docs/integrations/openai.mdx @@ -0,0 +1,221 @@ +--- +title: OpenAI +sidebarTitle: OpenAI +description: Integrate FastMCP servers with the OpenAI API +icon: "); -webkit-mask-image: url('https://upload.wikimedia.org/wikipedia/commons/6/66/OpenAI_logo_2025_%28symbol%29.svg');/*" +--- + +import { VersionBadge } from "/snippets/version-badge.mdx" + + +OpenAI recently announced support for MCP servers in the Responses API. Note that at this time, MCP is not supported in ChatGPT. + +## MCP in the Responses API + +OpenAI's [Responses API](https://platform.openai.com/docs/api-reference/responses) supports [MCP servers](https://platform.openai.com/docs/guides/tools-remote-mcp) as remote tool sources, allowing you to extend AI capabilities with custom functions. + + +The Responses API is a distinct API from OpenAI's Completions API, Assistants API, or ChatGPT. At this time, only the Responses API supports MCP. + + + +Currently, the Responses API only accesses **tools** from MCP servers—it queries the `list_tools` endpoint and exposes those functions to the AI agent. 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 OpenAI to access it. + +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 Responses API, you'll need to install the OpenAI Python SDK (not included with FastMCP): + +```bash +pip install openai +``` + +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, 11-16} +from openai import OpenAI + +# Your server URL (replace with your actual URL) +url = 'https://your-server-url.com' + +client = OpenAI() + +resp = client.responses.create( + model="gpt-4.1", + tools=[ + { + "type": "mcp", + "server_label": "dice_server", + "server_url": f"{url}/sse", + "require_approval": "never", + }, + ], + input="Roll a few dice!", +) + +print(resp.output_text) +``` +If you run this code, you'll see something like the following output: + +```text +You rolled 3 dice and got the following results: 6, 4, and 2! +``` + +### Authentication + + + +The Responses API can include headers to authenticate the request, which means you don't have to worry about your server being publicly accessible. + +#### 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") +``` + +This will generate a new RSA key pair and a corresponding access token. + +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, 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 OpenAI code we wrote earlier, you'll get an error like this: + +```python +pythonAPIStatusError: Error code: 424 - { + "error": { + "message": "Error retrieving tool list from MCP server: 'dice_server'. Http status code: 401 (Unauthorized)", + "type": "external_connector_error", + "param": "tools", + "code": "http_error" + } +} +``` + +As expected, the server is rejecting the request because it's not authenticated. + +To authenticate the client, you can pass the token in the `Authorization` header with the `Bearer` scheme: + + +```python {4, 7, 19-21} [expandable] +from openai import OpenAI + +# 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 = OpenAI() + +resp = client.responses.create( + model="gpt-4.1", + tools=[ + { + "type": "mcp", + "server_label": "dice_server", + "server_url": f"{url}/sse", + "require_approval": "never", + "headers": { + "Authorization": f"Bearer {access_token}" + } + }, + ], + input="Roll a few dice!", +) + +print(resp.output_text) +``` + +You should now see the dice roll results in the output. \ No newline at end of file diff --git a/docs/patterns/fastapi.mdx b/docs/patterns/fastapi.mdx deleted file mode 100644 index 09f7e298c..000000000 --- a/docs/patterns/fastapi.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: FastAPI Integration -sidebarTitle: FastAPI -description: Generate MCP servers from FastAPI apps -icon: square-bolt ---- -import { VersionBadge } from '/snippets/version-badge.mdx' - - - - -**Documentation Moved**: The comprehensive FastAPI integration documentation has been moved to the [OpenAPI Integration](/patterns/openapi#fastapi-integration) page, where it's covered alongside all other OpenAPI features including route mapping and tags support. - - -## Quick Start - -FastMCP can automatically convert FastAPI applications into MCP servers: - -```python -from fastapi import FastAPI -from fastmcp import FastMCP - -# A FastAPI app -app = FastAPI() - -@app.get("/items") -def list_items(): - return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}] - -@app.get("/items/{item_id}") -def get_item(item_id: int): - return {"id": item_id, "name": f"Item {item_id}"} - -@app.post("/items") -def create_item(name: str): - return {"id": 3, "name": name} - -# Create an MCP server from your FastAPI app -mcp = FastMCP.from_fastapi(app=app) - -if __name__ == "__main__": - mcp.run() # Start the MCP server -``` - - -For complete documentation including tag-based routing, route mapping configuration, timeout settings, authentication examples, and advanced configuration options, see the comprehensive [OpenAPI Integration documentation](/patterns/openapi#fastapi-integration). - \ No newline at end of file