Files
mcp-servers/README.md
help4bis 800610ae16 initial: forecastlab_db read-only MCP server
Read-only MariaDB facade for Claude Code. 4 tools:
list_databases / list_tables / describe_table / query.

Safety:
- 3 databases allowlisted (forecastlab, weewx_db, homeassistant)
- SELECT / SHOW / DESCRIBE / EXPLAIN / WITH only
- multi-statement injection rejected
- 1000 row hard cap (200 default)
- prefers MCP_DB_RO_USER if set; falls back to DB_USER

Tested: 10/10 read-only guard cases pass.
2026-04-26 15:47:18 +10:00

2.2 KiB

mcp-servers

Locally-hosted MCP (Model Context Protocol) servers exposed to Claude Code.

Each subdirectory is one MCP server. Registered with Claude via:

claude mcp add-json -s user <name> '{"type":"stdio","command":"<path>","args":[...]}'

Servers

Name Path Purpose
forecastlab_db forecastlab_db/server.py Read-only SQL access to forecastlab, weewx_db, homeassistant databases

forecastlab_db

Read-only MariaDB facade. Tools: list_databases, list_tables, describe_table, query.

Safety:

  • Only the 3 allowlisted databases reachable
  • SELECT / SHOW / DESCRIBE / EXPLAIN / WITH only — write statements rejected
  • Multi-statement injection rejected
  • Hard cap 1000 rows per query (default 200)
  • Datetimes serialised as ISO strings

Optional read-only DB user (recommended for production):

CREATE USER 'mcp_ro'@'localhost' IDENTIFIED BY '<secret>';
GRANT SELECT ON forecastlab.* TO 'mcp_ro'@'localhost';
GRANT SELECT ON weewx_db.* TO 'mcp_ro'@'localhost';
GRANT SELECT ON homeassistant.* TO 'mcp_ro'@'localhost';
FLUSH PRIVILEGES;

Then add to ~/.env:

MCP_DB_RO_USER=mcp_ro
MCP_DB_RO_PASSWORD=<secret>

The server prefers these if set; otherwise falls back to DB_USER/DB_PASSWORD.

Adding a new MCP server

  1. Create a subdirectory: mcp_servers/<name>/server.py
  2. Use the mcp Python SDK and the FastMCP helper (see forecastlab_db/server.py as a template)
  3. Register with Claude:
    claude mcp add-json -s user <name> \
      '{"type":"stdio","command":"/home/help4bis/miniconda3/envs/forecastlab/bin/python","args":["/home/help4bis/lib/mcp_servers/<name>/server.py"]}'
    
  4. Verify: claude mcp list should show it Connected
  5. Commit + push to Gitea

Testing

Each server's stdio-style protocol is best tested by Claude itself. For sanity-check the read-only guard:

/home/help4bis/miniconda3/envs/forecastlab/bin/python -c "
import sys; sys.path.insert(0, '/home/help4bis/lib/mcp_servers/forecastlab_db')
from server import _validate_read_only
_validate_read_only('SELECT 1')        # passes
_validate_read_only('DROP TABLE foo')  # raises ValueError
"