Skip to content

Commit 5a0b800

Browse files
author
shiraayal-tadata
committed
fix examples
1 parent 0c58451 commit 5a0b800

10 files changed

+209
-18
lines changed

examples/01_basic_usage_example.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1+
from examples.shared.apps.items import app # The FastAPI app
2+
from examples.shared.setup import setup_logging
13

2-
"""
3-
This example shows a simple MCP server created from a FastAPI app.
4-
"""
5-
from examples.shared.items_app import app # The FastAPI app
64
from fastapi_mcp import FastApiMCP
75

6+
setup_logging()
7+
88
# Add MCP server to the FastAPI app
9-
mcp = FastApiMCP(
10-
app,
11-
name="Item API MCP",
12-
description="MCP server for the Item API",
13-
)
9+
mcp = FastApiMCP(app)
1410

1511
# Mount the MCP server to the FastAPI app
1612
mcp.mount()
1713

14+
1815
if __name__ == "__main__":
1916
import uvicorn
20-
uvicorn.run(app, host="0.0.0.0", port=8000)
17+
18+
uvicorn.run(app, host="0.0.0.0", port=8000)

examples/02_full_schema_description_example.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,25 @@
22
"""
33
This example shows how to describe the full response schema instead of just a response example.
44
"""
5-
from examples.shared.items_app import app # The FastAPI app
5+
from examples.shared.apps.items import app # The FastAPI app
6+
from examples.shared.setup import setup_logging
7+
68
from fastapi_mcp import FastApiMCP
79

10+
setup_logging()
11+
12+
# Add MCP server to the FastAPI app
813
mcp = FastApiMCP(
914
app,
10-
describe_full_response_schema=True, # Include all possible response schemas in tool descriptions
11-
describe_all_responses=True, # Include full JSON schema in tool descriptions
15+
name="Item API MCP",
16+
description="MCP server for the Item API",
17+
describe_full_response_schema=True, # Describe the full response JSON-schema instead of just a response example
18+
describe_all_responses=True, # Describe all the possible responses instead of just the success (2XX) response
1219
)
20+
1321
mcp.mount()
1422

1523
if __name__ == "__main__":
1624
import uvicorn
25+
1726
uvicorn.run(app, host="0.0.0.0", port=8000)

examples/03_custom_exposed_endpoints_example.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
- You can combine operation filtering with tag filtering (e.g., use `include_operations` with `include_tags`)
77
- When combining filters, a greedy approach will be taken. Endpoints matching either criteria will be included
88
"""
9-
from examples.shared.items_app import app # The FastAPI app
9+
from examples.shared.apps.items import app # The FastAPI app
10+
from examples.shared.setup import setup_logging
11+
1012
from fastapi_mcp import FastApiMCP
1113

14+
setup_logging()
15+
16+
# Examples demonstrating how to filter MCP tools by operation IDs and tags
1217

1318
# Filter by including specific operation IDs
1419
include_operations_mcp = FastApiMCP(

examples/04_separate_server_example.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
"""
55
from fastapi import FastAPI
66

7-
from examples.shared.items_app import app
7+
from examples.shared.apps.items import app
8+
from examples.shared.setup import setup_logging
89

910
from fastapi_mcp import FastApiMCP
1011

12+
setup_logging()
13+
1114
MCP_SERVER_HOST = "localhost"
1215
MCP_SERVER_PORT = 8000
1316
ITEMS_API_HOST = "localhost"

examples/05_reregister_tools_example.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
"""
22
This example shows how to re-register tools if you add endpoints after the MCP server was created.
33
"""
4-
from examples.shared.items_app import app # The FastAPI app
4+
from examples.shared.apps.items import app # The FastAPI app
5+
from examples.shared.setup import setup_logging
6+
57
from fastapi_mcp import FastApiMCP
68

9+
setup_logging()
710

811
mcp = FastApiMCP(app) # Add MCP server to the FastAPI app
912
mcp.mount() # MCP server
@@ -21,4 +24,5 @@ async def new_endpoint():
2124

2225
if __name__ == "__main__":
2326
import uvicorn
27+
2428
uvicorn.run(app, host="0.0.0.0", port=8000)

examples/06_custom_mcp_router_example.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
"""
22
This example shows how to mount the MCP server to a specific APIRouter, giving a custom mount path.
33
"""
4-
from examples.shared.items_app import app # The FastAPI app
4+
from examples.shared.apps.items import app # The FastAPI app
5+
from examples.shared.setup import setup_logging
6+
57
from fastapi import APIRouter
68
from fastapi_mcp import FastApiMCP
79

10+
setup_logging()
811

912
other_router = APIRouter(prefix="/other/route")
1013
app.include_router(other_router)
@@ -18,4 +21,5 @@
1821

1922
if __name__ == "__main__":
2023
import uvicorn
24+
2125
uvicorn.run(app, host="0.0.0.0", port=8000)

examples/07_configure_http_timeout_example.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22
This example shows how to configure the HTTP client timeout for the MCP server.
33
In case you have API endpoints that take longer than 5 seconds to respond, you can increase the timeout.
44
"""
5+
from examples.shared.apps.items import app # The FastAPI app
6+
from examples.shared.setup import setup_logging
7+
58
import httpx
69

7-
from examples.shared.items_app import app # The FastAPI app
810
from fastapi_mcp import FastApiMCP
911

12+
setup_logging()
13+
1014

1115
mcp = FastApiMCP(
1216
app,
@@ -17,4 +21,5 @@
1721

1822
if __name__ == "__main__":
1923
import uvicorn
24+
2025
uvicorn.run(app, host="0.0.0.0", port=8000)

examples/shared/apps/__init__.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""
2+
Simple example of using FastAPI-MCP to add an MCP server to a FastAPI app.
3+
"""
4+
5+
from fastapi import FastAPI, HTTPException, Query
6+
from pydantic import BaseModel
7+
from typing import List, Optional
8+
9+
10+
router = FastAPI()
11+
12+
13+
class Item(BaseModel):
14+
id: int
15+
name: str
16+
description: Optional[str] = None
17+
price: float
18+
tags: List[str] = []
19+
20+
21+
items_db: dict[int, Item] = {}
22+
23+
24+
@router.get("/items/", response_model=List[Item], tags=["items"], operation_id="list_items")
25+
async def list_items(skip: int = 0, limit: int = 10):
26+
"""
27+
List all items in the database.
28+
29+
Returns a list of items, with pagination support.
30+
"""
31+
return list(items_db.values())[skip : skip + limit]
32+
33+
34+
@router.get("/items/{item_id}", response_model=Item, tags=["items"], operation_id="get_item")
35+
async def read_item(item_id: int):
36+
"""
37+
Get a specific item by its ID.
38+
39+
Raises a 404 error if the item does not exist.
40+
"""
41+
if item_id not in items_db:
42+
raise HTTPException(status_code=404, detail="Item not found")
43+
return items_db[item_id]
44+
45+
46+
@router.post("/items/", response_model=Item, tags=["items"], operation_id="create_item")
47+
async def create_item(item: Item):
48+
"""
49+
Create a new item in the database.
50+
51+
Returns the created item with its assigned ID.
52+
"""
53+
items_db[item.id] = item
54+
return item
55+
56+
57+
@router.put("/items/{item_id}", response_model=Item, tags=["items"], operation_id="update_item")
58+
async def update_item(item_id: int, item: Item):
59+
"""
60+
Update an existing item.
61+
62+
Raises a 404 error if the item does not exist.
63+
"""
64+
if item_id not in items_db:
65+
raise HTTPException(status_code=404, detail="Item not found")
66+
67+
item.id = item_id
68+
items_db[item_id] = item
69+
return item
70+
71+
72+
@router.delete("/items/{item_id}", tags=["items"], operation_id="delete_item")
73+
async def delete_item(item_id: int):
74+
"""
75+
Delete an item from the database.
76+
77+
Raises a 404 error if the item does not exist.
78+
"""
79+
if item_id not in items_db:
80+
raise HTTPException(status_code=404, detail="Item not found")
81+
82+
del items_db[item_id]
83+
return {"message": "Item deleted successfully"}
84+
85+
86+
@router.get("/items/search/", response_model=List[Item], tags=["search"], operation_id="search_items")
87+
async def search_items(
88+
q: Optional[str] = Query(None, description="Search query string"),
89+
min_price: Optional[float] = Query(None, description="Minimum price"),
90+
max_price: Optional[float] = Query(None, description="Maximum price"),
91+
tags: List[str] = Query([], description="Filter by tags"),
92+
):
93+
"""
94+
Search for items with various filters.
95+
96+
Returns a list of items that match the search criteria.
97+
"""
98+
results = list(items_db.values())
99+
100+
if q:
101+
q = q.lower()
102+
results = [
103+
item for item in results if q in item.name.lower() or (item.description and q in item.description.lower())
104+
]
105+
106+
if min_price is not None:
107+
results = [item for item in results if item.price >= min_price]
108+
if max_price is not None:
109+
results = [item for item in results if item.price <= max_price]
110+
111+
if tags:
112+
results = [item for item in results if all(tag in item.tags for tag in tags)]
113+
114+
return results
115+
116+
117+
sample_items = [
118+
Item(id=1, name="Hammer", description="A tool for hammering nails", price=9.99, tags=["tool", "hardware"]),
119+
Item(id=2, name="Screwdriver", description="A tool for driving screws", price=7.99, tags=["tool", "hardware"]),
120+
Item(id=3, name="Wrench", description="A tool for tightening bolts", price=12.99, tags=["tool", "hardware"]),
121+
Item(id=4, name="Saw", description="A tool for cutting wood", price=19.99, tags=["tool", "hardware", "cutting"]),
122+
Item(id=5, name="Drill", description="A tool for drilling holes", price=49.99, tags=["tool", "hardware", "power"]),
123+
]
124+
for item in sample_items:
125+
items_db[item.id] = item
File renamed without changes.

examples/shared/setup.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import logging
2+
3+
from pydantic import BaseModel
4+
5+
6+
class LoggingConfig(BaseModel):
7+
LOGGER_NAME: str = "fastapi_mcp"
8+
LOG_FORMAT: str = "%(levelprefix)s %(asctime)s\t[%(name)s] %(message)s"
9+
LOG_LEVEL: str = logging.getLevelName(logging.DEBUG)
10+
11+
version: int = 1
12+
disable_existing_loggers: bool = False
13+
formatters: dict = {
14+
"default": {
15+
"()": "uvicorn.logging.DefaultFormatter",
16+
"fmt": LOG_FORMAT,
17+
"datefmt": "%Y-%m-%d %H:%M:%S",
18+
},
19+
}
20+
handlers: dict = {
21+
"default": {
22+
"formatter": "default",
23+
"class": "logging.StreamHandler",
24+
"stream": "ext://sys.stdout",
25+
},
26+
}
27+
loggers: dict = {
28+
"": {"handlers": ["default"], "level": LOG_LEVEL}, # Root logger
29+
"uvicorn": {"handlers": ["default"], "level": LOG_LEVEL},
30+
LOGGER_NAME: {"handlers": ["default"], "level": LOG_LEVEL},
31+
}
32+
33+
34+
def setup_logging():
35+
from logging.config import dictConfig
36+
37+
logging_config = LoggingConfig()
38+
dictConfig(logging_config.model_dump())

0 commit comments

Comments
 (0)