Skip to main content
Glama
nikita-pakhno

parking-mcp-server

README.md
# Parking MCP Server

MCP (Model Context Protocol) server that exposes a tool for writing confirmed
parking reservations to a file. Called by the admin agent once an
administrator approves a reservation.

## Tool

```
write_reservation(
    name: str,
    car_number: str,
    reservation_period: str,   # "start - end"
    approval_time: str         # ISO timestamp
) -> str   # confirmation or error
```

Appends one line per reservation to `data/confirmed_reservations.txt`:

```
Name | Car Number | Reservation Period | Approval Time
```

## Security

- **Bearer token auth** on every request (`Authorization: Bearer <token>`).
- **Input validation** — names, plate numbers, timestamps are validated and
  rejected if they contain pipe characters or newlines (anti-injection for the
  delimited file format).
- **Append-only, atomic writes** — file is opened in append mode with a brief
  file lock so concurrent writes don't interleave.
- **No arbitrary file paths** — the output file is fixed by the server config,
  not by tool arguments.

## Setup

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# edit .env — change MCP_AUTH_TOKEN

python -m mcp_server.run
# MCP endpoint at http://localhost:8002/mcp
```

## Calling the tool from a Python MCP client

```python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client(
        "http://localhost:8002/mcp",
        headers={"Authorization": "Bearer change-me-parking-mcp-secret"},
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "write_reservation",
                {"name": "Nikita", "car_number": "BC1234AB",
                 "reservation_period": "2025-12-01 10:00 - 2025-12-01 12:00",
                 "approval_time": "2026-08-11T12:00:00Z"},
            )
            print(result.content[0].text)

asyncio.run(main())
```

## Project layout

```
mcp_server/
  server.py        # FastMCP server + tool definition
  storage.py       # atomic append-only writer with input validation
  auth.py          # Bearer token middleware
  config.py
tests/
  test_storage.py
  test_server.py
  test_auth.py
```

## Tests

```bash
pytest -q
```