mirror of
https://github.com/tadata-org/fastapi_mcp.git
synced 2025-04-13 23:32:11 +03:00
WIP
This commit is contained in:
@@ -1,43 +1,66 @@
|
||||
# FastAPI-MCP Examples
|
||||
|
||||
This directory contains examples of using FastAPI-MCP to generate MCP servers from FastAPI applications.
|
||||
This directory contains examples of using FastAPI-MCP to integrate Model Context Protocol (MCP) servers with FastAPI applications.
|
||||
|
||||
## Sample App
|
||||
## Examples
|
||||
|
||||
The `sample_app.py` file contains a simple FastAPI application with CRUD operations for an "Item" resource.
|
||||
### `simple_integration.py`
|
||||
|
||||
To run the FastAPI application:
|
||||
Demonstrates the direct integration approach, where an MCP server is mounted directly to a FastAPI application.
|
||||
|
||||
Features:
|
||||
- FastAPI app with CRUD operations for items
|
||||
- MCP server mounted at `/mcp`
|
||||
- Automatic conversion of API endpoints to MCP tools
|
||||
- Custom MCP tool not based on an API endpoint
|
||||
|
||||
To run this example:
|
||||
|
||||
```bash
|
||||
python sample_app.py
|
||||
# From the examples directory
|
||||
python run_example.py
|
||||
|
||||
# Or directly
|
||||
uvicorn simple_integration:app --reload
|
||||
```
|
||||
|
||||
To generate an MCP server from the sample app:
|
||||
Then visit:
|
||||
- API documentation: http://localhost:8000/docs
|
||||
- MCP server endpoint: http://localhost:8000/mcp
|
||||
|
||||
### `sample_app.py`
|
||||
|
||||
Original example app to demonstrate the legacy code generation approach.
|
||||
|
||||
To use with the CLI:
|
||||
|
||||
```bash
|
||||
cd .. # Go to the root directory
|
||||
python -m fastapi_mcp generate examples/sample_app.py
|
||||
# Generate MCP server
|
||||
fastapi-mcp generate sample_app.py
|
||||
|
||||
# Preview the generated server
|
||||
fastapi-mcp preview
|
||||
|
||||
# Run the sample app
|
||||
uvicorn sample_app:app --reload
|
||||
|
||||
# In another terminal, run the MCP server
|
||||
fastapi-mcp run
|
||||
```
|
||||
|
||||
This will create a `mcp_server` directory with the generated MCP server.
|
||||
## Using with Claude
|
||||
|
||||
To preview the generated MCP server:
|
||||
To connect Claude to your MCP server:
|
||||
|
||||
```bash
|
||||
python -m fastapi_mcp preview
|
||||
```
|
||||
1. Run any of the examples above
|
||||
2. In Claude, use the URL of your MCP server (e.g., `http://localhost:8000/mcp`)
|
||||
3. Claude will discover the available tools and resources automatically
|
||||
|
||||
To run the generated MCP server:
|
||||
## What's Next?
|
||||
|
||||
```bash
|
||||
python -m fastapi_mcp run
|
||||
```
|
||||
These examples demonstrate the basic functionality of FastAPI-MCP. For more advanced use cases, you can:
|
||||
|
||||
## How It Works
|
||||
|
||||
1. FastAPI-MCP discovers all endpoints in the FastAPI application
|
||||
2. It converts the endpoints to MCP tools
|
||||
3. It generates a standalone MCP server
|
||||
4. It preserves documentation and type information
|
||||
|
||||
The generated MCP server can be used with any MCP client, such as Claude.
|
||||
- Add authentication to your API endpoints
|
||||
- Customize the MCP server with additional capabilities
|
||||
- Add custom MCP tools that go beyond your API functionality
|
||||
- Deploy your integrated app to a production environment
|
||||
18
examples/run_example.py
Normal file
18
examples/run_example.py
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Run the FastAPI-MCP example.
|
||||
"""
|
||||
|
||||
import uvicorn
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Starting FastAPI-MCP example...")
|
||||
print("Visit http://localhost:8000/docs to see the API documentation")
|
||||
print("Your MCP server is available at http://localhost:8000/mcp")
|
||||
|
||||
uvicorn.run(
|
||||
"simple_integration:app",
|
||||
host="127.0.0.1",
|
||||
port=8000,
|
||||
reload=True,
|
||||
)
|
||||
164
examples/simple_integration.py
Normal file
164
examples/simple_integration.py
Normal file
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Simple example of using FastAPI-MCP to add an MCP server to a FastAPI app.
|
||||
"""
|
||||
|
||||
from fastapi import FastAPI, Query
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi_mcp import add_mcp_server
|
||||
|
||||
|
||||
# Create a simple FastAPI app
|
||||
app = FastAPI(
|
||||
title="Example API",
|
||||
description="A simple example API with integrated MCP server",
|
||||
version="0.1.0",
|
||||
)
|
||||
|
||||
|
||||
# Define some models
|
||||
class Item(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
price: float
|
||||
tags: List[str] = []
|
||||
|
||||
|
||||
# In-memory database
|
||||
items_db = {}
|
||||
|
||||
|
||||
# Define some endpoints
|
||||
@app.get("/items/", response_model=List[Item], tags=["items"])
|
||||
async def list_items(skip: int = 0, limit: int = 10):
|
||||
"""
|
||||
List all items in the database.
|
||||
|
||||
Returns a list of items, with pagination support.
|
||||
"""
|
||||
return list(items_db.values())[skip : skip + limit]
|
||||
|
||||
|
||||
@app.get("/items/{item_id}", response_model=Item, tags=["items"])
|
||||
async def read_item(item_id: int):
|
||||
"""
|
||||
Get a specific item by its ID.
|
||||
|
||||
Raises a 404 error if the item does not exist.
|
||||
"""
|
||||
if item_id not in items_db:
|
||||
return {"error": "Item not found"}
|
||||
return items_db[item_id]
|
||||
|
||||
|
||||
@app.post("/items/", response_model=Item, tags=["items"])
|
||||
async def create_item(item: Item):
|
||||
"""
|
||||
Create a new item in the database.
|
||||
|
||||
Returns the created item with its assigned ID.
|
||||
"""
|
||||
items_db[item.id] = item
|
||||
return item
|
||||
|
||||
|
||||
@app.put("/items/{item_id}", response_model=Item, tags=["items"])
|
||||
async def update_item(item_id: int, item: Item):
|
||||
"""
|
||||
Update an existing item.
|
||||
|
||||
Raises a 404 error if the item does not exist.
|
||||
"""
|
||||
if item_id not in items_db:
|
||||
return {"error": "Item not found"}
|
||||
|
||||
item.id = item_id
|
||||
items_db[item_id] = item
|
||||
return item
|
||||
|
||||
|
||||
@app.delete("/items/{item_id}", tags=["items"])
|
||||
async def delete_item(item_id: int):
|
||||
"""
|
||||
Delete an item from the database.
|
||||
|
||||
Raises a 404 error if the item does not exist.
|
||||
"""
|
||||
if item_id not in items_db:
|
||||
return {"error": "Item not found"}
|
||||
|
||||
del items_db[item_id]
|
||||
return {"message": "Item deleted successfully"}
|
||||
|
||||
|
||||
@app.get("/items/search/", response_model=List[Item], tags=["search"])
|
||||
async def search_items(
|
||||
q: Optional[str] = Query(None, description="Search query string"),
|
||||
min_price: Optional[float] = Query(None, description="Minimum price"),
|
||||
max_price: Optional[float] = Query(None, description="Maximum price"),
|
||||
tags: List[str] = Query([], description="Filter by tags"),
|
||||
):
|
||||
"""
|
||||
Search for items with various filters.
|
||||
|
||||
Returns a list of items that match the search criteria.
|
||||
"""
|
||||
results = list(items_db.values())
|
||||
|
||||
# Filter by search query
|
||||
if q:
|
||||
q = q.lower()
|
||||
results = [
|
||||
item for item in results if q in item.name.lower() or (item.description and q in item.description.lower())
|
||||
]
|
||||
|
||||
# Filter by price range
|
||||
if min_price is not None:
|
||||
results = [item for item in results if item.price >= min_price]
|
||||
if max_price is not None:
|
||||
results = [item for item in results if item.price <= max_price]
|
||||
|
||||
# Filter by tags
|
||||
if tags:
|
||||
results = [item for item in results if all(tag in item.tags for tag in tags)]
|
||||
|
||||
return results
|
||||
|
||||
|
||||
# Add sample data
|
||||
sample_items = [
|
||||
Item(id=1, name="Hammer", description="A tool for hammering nails", price=9.99, tags=["tool", "hardware"]),
|
||||
Item(id=2, name="Screwdriver", description="A tool for driving screws", price=7.99, tags=["tool", "hardware"]),
|
||||
Item(id=3, name="Wrench", description="A tool for tightening bolts", price=12.99, tags=["tool", "hardware"]),
|
||||
Item(id=4, name="Saw", description="A tool for cutting wood", price=19.99, tags=["tool", "hardware", "cutting"]),
|
||||
Item(id=5, name="Drill", description="A tool for drilling holes", price=49.99, tags=["tool", "hardware", "power"]),
|
||||
]
|
||||
|
||||
for item in sample_items:
|
||||
items_db[item.id] = item
|
||||
|
||||
|
||||
# Add MCP server to the FastAPI app
|
||||
mcp_server = add_mcp_server(
|
||||
app,
|
||||
mount_path="/mcp",
|
||||
name="Item API MCP",
|
||||
description="MCP server for the Item API",
|
||||
base_url="http://localhost:8000",
|
||||
)
|
||||
|
||||
|
||||
# Optionally, you can add custom MCP tools not based on FastAPI endpoints
|
||||
@mcp_server.tool()
|
||||
async def get_item_count() -> int:
|
||||
"""Get the total number of items in the database."""
|
||||
return len(items_db)
|
||||
|
||||
|
||||
# Run the server if this file is executed directly
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(app, host="127.0.0.1", port=8000)
|
||||
Reference in New Issue
Block a user