Skip to main content
Glama
hothienlac

Note App MCP Server

by hothienlac
README.md
# Note App — FastAPI + MCP Demo

A simple JWT-authenticated note-taking API built with FastAPI, backed by SQLite via SQLAlchemy, and exposed as [MCP](https://modelcontextprotocol.io) tools for agents using [fastapi-mcp](https://github.com/tadata-org/fastapi_mcp).

## Requirements

- Python 3.13+
- Node.js (only needed to run the MCP Inspector via `npx`)

## Setup

```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

Create a `.env` file in the project root (see `src/environment.py` for the full list of settings):

```
USERNAME=admin
PASSWORD=changeme
JWT_SECRET=some-long-random-secret
JWT_EXPIRATION_MINUTES=60   # optional, defaults to 60
```

## Running the server

```bash
python server.py
```

This starts uvicorn on `http://0.0.0.0:8000`, serving `src.app:app`.

- Swagger UI: http://localhost:8000/docs
- The root URL `/` redirects to `/docs`

## Authentication

Get an access token:

```bash
curl -X POST http://localhost:8000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "changeme"}'
```

Use the returned `access_token` as a Bearer token on all `/notes` endpoints:

```bash
curl http://localhost:8000/notes/ \
  -H "Authorization: Bearer <access_token>"
```

## Notes API

| Method | Path            | Description       |
|--------|-----------------|--------------------|
| GET    | `/notes/`       | List notes        |
| GET    | `/notes/{id}`   | Get a note        |
| POST   | `/notes/`       | Create a note     |
| PUT    | `/notes/{id}`   | Update a note      |
| DELETE | `/notes/{id}`   | Delete a note      |

## Using the MCP server

The app mounts an MCP server at `/mcp`, exposing every endpoint tagged `Note` as an MCP tool. Requests require the same Bearer token as the REST API, forwarded via the `authorization` header.

### Inspecting it with MCP Inspector

1. Start the server: `python server.py`
2. In a separate terminal, launch the inspector:
   ```bash
   npx @modelcontextprotocol/inspector
   ```
3. In the inspector UI, set:
   - Transport: **Streamable HTTP**
   - URL: `http://127.0.0.1:8000/mcp`
   - Header: `Authorization: Bearer <access_token>` (obtained from `/auth/login`)
4. Click **Connect**, go to the **Tools** tab, and click **List Tools** to see `list_notes`, `get_note`, `create_note`, `update_note`, `delete_note`.
5. Select a tool, fill in parameters, and click **Run Tool** to test it.

### Connecting from an MCP client (e.g. Claude Desktop)

Since the server requires auth headers, use `mcp-remote` as a bridge:

```json
{
  "mcpServers": {
    "note-app": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:8000/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer <access_token>"
      }
    }
  }
}
```

## Project structure

```
server.py                  # entrypoint (uvicorn runner)
src/
  app.py                   # FastAPI app + MCP mount
  environment.py           # settings loaded from .env
  modules/
    auth/                  # login route, JWT issuing/verification
    note/                  # notes CRUD (model, schema, service, route)
  sqlalchemy/              # base model + engine/session setup
```

## Dev tooling

Config files are included for:

```bash
ruff check .   # linting (ruff.toml)
mypy .         # type checking (mypy.ini)
```