Skip to content

Latest commit

 

History

History
150 lines (103 loc) · 5.19 KB

File metadata and controls

150 lines (103 loc) · 5.19 KB

Sample FastAPI + GraphQL Book API Project

made-with-python Maintenance License Python 3.12

Book API with GraphQL, REST, and MCP (fastapi-mcp) — Chapter 9 of Building Serverless Python Apps on AWS.

Based on sample-fastapi-graphql-book-api with REST routes annotated for MCP tools (operation_id, description).

MCP is mounted with streamable HTTP via mcp.mount_http() (recommended in fastapi-mcp 0.4+). The legacy mcp.mount() SSE transport is not used.

Part of the serverless-python-dev monorepo.

MCP (Chapter 9)

uv sync --all-groups
uv run uvicorn main:app --reload

Start MongoDB locally (API on the host uses localhost, not the Docker service name):

docker compose up mongo

In another terminal, launch the Inspector (no --url flag on current releases):

npx @modelcontextprotocol/inspector

Open the browser UI (default http://127.0.0.1:6274). The npx command does not pass your API URL—you connect in the UI:

  1. Transport: Streamable HTTP (not legacy SSE).
  2. Server: http://127.0.0.1:8000/mcp (or host 127.0.0.1, port 8000, path /mcp).
  3. Connect, then open the Tools tab and run fetch_books.

Do not use npx @modelcontextprotocol/inspector --url http://.../sse or transport SSE—those match Node/Java MCP samples, not this app. Use Streamable HTTP and path /mcp only. Current Inspector releases reject --url anyway.

REST/MCP tools return HTTP 200 with success: false and an errorMessage when the database is down (see src/api/rest_errors.py), instead of a bare 500.

Local .env example:

DB_URL=mongodb://localhost:27017
DB_NAME=bookapi

Use your Atlas URI only if that cluster still exists; a bad SRV host shows up as a DNS error in errorMessage.

Optional auth (.env):

AUTH_ENABLED=true
ALLOWED_SUBJECTS=TEST_SERVICE1,TEST_SERVICE_2

Claude/Cursor mcp.json example:

{
  "mcpServers": {
    "bookapi-local": {
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}

Running Services with Docker

For local MongoDB only:

docker compose up mongo

The bookapi service in docker-compose.yaml expects a locally built bookapi image (docker build -t bookapi -f Dockerfile .). For day-to-day MCP work, run the API with uv run uvicorn on the host and Mongo in Docker as above.

To refresh the image on your local (for server devs), run the following:

docker build -t bookapi -f Dockerfile .

You can run the one off image and container with the following:

docker run -d --name bookapi -p 8000:8000 bookapi

Running API Locally

Install dependencies with uv:

uv sync --all-groups

You'll need the following environment variables configured or in a .env file to run the server successfully:

# FastAPI Setup
export HOST="127.0.0.1"
export PORT=8000

# BookAPI DB Setup
export DB_URL='mongodb://localhost:27017'
export DB_NAME='bookapi'

# AWS and Infra Setup
AWS_ACCOUNT='YOUR_ACCOUNT'
AWS_REGION='AWS REGION (e.g. us-east-1)'
# Optional — chapter 5 "Prettify the URL"; omit for HTTP on the ALB DNS name
DOMAIN_NAME='example.com'

# Infra Setup
LOCAL_NETWORK_CIDR='YOUR_NETWORK_CIDR'

The main entry point is main.py, so you can start that file from command line or use whatever execution method is available from your IDE. To install the IDE to interact with GraphQL, look in the SETUP.md for GraphQL Playground installation instructions then simply open the GraphQL Playground to interact with the local server and insert the base url http://127.0.0.1:8000/graph.

Dev Notes

Viewing Changes

Changes under /app may be picked up by the auto-refresh (no need to restart server). To understand how to use the playground to run queries, please reference the following: GraphQL Queries Reference

Running Tests

All tests are located under the tests folder. To run them from terminal, execute the following:

uv run pytest tests

To run with coverage, run the following:

uv run coverage run -m pytest -v tests && uv run coverage report -m

Viewing Docs

The docs are autogenerated and are available after starting the server. Docs are available at {BASE_URL}/graphql/docs.

To update the doc url, update the get_graphql_docs() function in main.py.

Using the Makefile

Note that the Makefile included in this repo uses several environment variables. Be sure to have your .env setup to fully leverage all the shortcuts made available.