mcp: read-only ShopDB MCP server generated from the OpenAPI spec

A separate tool (not shipped in the app) that exposes a curated set of read
endpoints as MCP tools, so an LLM client can query the asset DB directly. Built
with FastMCP.from_openapi over docs/openapi.json; auth via a scoped PAT
(SHOPDB_TOKEN) or managed X-API-Key. Read-only: only GETs on the curated
allowlist become tools, all writes excluded. Runs anywhere that can reach the
API - never on the air-gapped box. Needs `pip install fastmcp` + testing in that
env (not installed in this repo's venv).
This commit is contained in:
cproudlock
2026-07-30 07:52:53 -04:00
parent b507884ad6
commit f0b5465917
3 changed files with 123 additions and 0 deletions

42
mcp/README.md Normal file
View File

@@ -0,0 +1,42 @@
# ShopDB MCP server (read-only)
Lets an LLM client query ShopDB directly as tools, generated from the OpenAPI
spec (`docs/openapi.json`). Separate from the app - runs anywhere that can reach
the API; never on the air-gapped prod box.
## Install + run
```
pip install -r mcp/requirements.txt
export SHOPDB_BASE="https://tsgwp00525.wjs.geaerospace.net/shopdb"
export SHOPDB_TOKEN="<scoped READ PAT>" # mint in ShopDB: Settings > API Tokens
python mcp/shopdb_mcp.py # stdio
```
(Or `SHOPDB_API_KEY` instead of a Bearer PAT for managed-token access.)
## Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"shopdb": {
"command": "python",
"args": ["/abs/path/shopdb-flask/mcp/shopdb_mcp.py"],
"env": {
"SHOPDB_BASE": "https://tsgwp00525.wjs.geaerospace.net/shopdb",
"SHOPDB_TOKEN": "<scoped read PAT>"
}
}
}
}
```
## Scope / safety
- **Read-only**: only GET endpoints on the curated allowlist (`CURATED` in
`shopdb_mcp.py`) become tools; all writes are excluded.
- Give the PAT the **least** scope needed. Tool calls hit the normal API, so
they're subject to its auth + land in the audit log.
- To add write tools later, extend `CURATED` / add `RouteMap`s for those verbs,
behind a token that actually holds the scopes.
## Keeping it current
Tools follow `docs/openapi.json`. After API changes: `python scripts/gen_openapi.py`.