elsheikh21/vera-ai-mcp-server
If you are the rightful owner of vera-ai-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
This document provides a comprehensive guide to setting up and using a minimal MCP-style API server that exposes static and dynamic resources for books and exchange rates.
README – MCP Server (Books + Exchange)
A minimal MCP-style API exposing:
- Static
booksresource backed by a spreadsheet dataset (Excel/CSV) - Dynamic
exchangeresource backed by exchange-rate table (Excel/CSV) with inverse and 2‑hop derivation - Resource discovery via
/resources
Quickstart (local)
# 1) Create & activate venv
python -m venv .venv
. .venv/bin/activate # Windows: .venv\Scripts\activate
# 2) Install deps
pip install -r requirements.txt
# 3) Run
uvicorn app.main:app --reload
# open http://127.0.0.1:8000/docs
Authentication
The /books and /exchange endpoints are protected by an API key. Requests to these endpoints must include a valid key in the X-API-Key header.
Example using curl:
curl -X 'GET' \
'http://127.0.0.1:8000/books' \
-H 'accept: application/json' \
-H 'X-API-Key: your-secret-key'
If the key is missing or invalid, the API will return a 401 Unauthorized error.
Configuration
Paths and the API key can be changed via environment variables (pydantic-settings):
BOOKS_PATH(default:data/BooksDatasetClean.xlsx)RATES_PATH(default:data/exchange_rates_dataset.xlsx)API_KEY(default:default-secret-key)
Example (Linux/macOS):
BOOKS_PATH=data/books.csv \
RATES_PATH=data/rates.csv \
API_KEY="your-secret-key" \
uvicorn app.main:app --reload
Example (Windows Command Prompt):
set BOOKS_PATH=data/books.csv
set RATES_PATH=data/rates.csv
set API_KEY="your-secret-key"
uvicorn app.main:app --reload
Docker
docker build -t mcp-server .
docker run --rm -p 8000:8000 \
-e BOOKS_PATH="data/BooksDatasetClean.xlsx" \
-e RATES_PATH="data/exchange_rates_dataset.xlsx" \
-e API_KEY="your-secret-key" \
mcp-server
Resource Discovery
GET /resources
{
"resources": [
{"name":"books","type":"static","endpoints":["/books","/books/{id}"]},
{"name":"exchange","type":"dynamic","endpoints":["/exchange"]}
]
}
Books API
List & filter
GET /books?author=&genre=&year=&title_contains=&limit=&offset=
{
"total": 1234,
"limit": 50,
"offset": 0,
"items": [
{"id":"1","title":"...","author":"...","year":1993,"genre":"History"}
]
}
Get by ID
GET /books/{id}
{"id":"1","title":"...","author":"...","year":1993,"genre":"History"}
Column mapping:
Title→titleAuthors→author(strips leading "By ")Category→genre(first token before comma)Publish Date (Year)→yearID→ synthesized incremental id if absent
Exchange API
GET /exchange?from=USD&to=EUR&amount=100
{"from_currency":"USD","to_currency":"EUR","rate":0.92,"amount":100.0,"converted":92.0}
Error examples:
- 400:
{"detail":"Unsupported currency: XXX"} - 400:
{"detail":"No rate path from XXX to YYY"} - 422 for missing/invalid query params
Design Choices
- Service boundary: routers are thin; data logic lives in
services/. - ID synthesis: dataset has no stable id → we generate deterministic
1..Non load. - Genre normalization: first token before comma keeps it coarse and filterable.
- Exchange graph: load directed edges, add inverse + identity, allow simple 2‑hop via common pivots.
- Extensibility: swap Excel/CSV for DB with the same service interface.
Tests (pytest)
How tests are structured
- Tests generate tiny temp CSVs at runtime so they don't depend on the large Excel files.
conftest.pysets env vars before importing the app so startup loads the temp files.- We cover: discovery, books list/filter/get/404, exchange success/identity/invalid.
Running tests
pip install -r requirements.txt
pip install pytest httpx anyio
pytest -q
Submission Checklist
- Two resources (static books, dynamic exchange)
- Resource discovery
/resources - List, get-by-id, filter (author/genre/year), partial title, pagination
- Exchange with input validation, inverse + identity + 2-hop
- Error handling: 400/404/422
- Modular code + Dockerfile
- README (this file)
- Tests (pytest suite)