vera-ai-mcp-server

elsheikh21/vera-ai-mcp-server

3.1

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 books resource backed by a spreadsheet dataset (Excel/CSV)
  • Dynamic exchange resource 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:

  • Titletitle
  • Authorsauthor (strips leading "By ")
  • Categorygenre (first token before comma)
  • Publish Date (Year)year
  • ID → 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..N on 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.py sets 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)