Skip to content
BoringStack
Star

MCP servers for agents

4 min read

A coding agent reads your code fine. It’s blind to runtime state: the live database schema, the actual rows, the cache keys and their TTLs, the BullMQ queue backlog. So it guesses — and guesses drift from reality.

Model Context Protocol servers close that gap. The dev stack already publishes Postgres and Valkey on the host (so you can psql and valkey-cli them), which means an MCP server reaches them with no extra setup. Same idea as observability: the runtime context is pre-wired — for humans in Grafana, and here for agents.

This is dev-only and opt-in. Two servers, both read-leaning:

ServerReach for it when…What it gives the agent
Postgres (read-only)writing a Drizzle migration, debugging a query, checking a constraintlive schema, indexes, row samples, EXPLAIN plans, index/health analysis
Valkey / Redisa cache or TTL bug, a stuck job, inspecting rate-limit keyskeys, TTLs, bull:* queue state, INFO
  1. Install uv (provides uvx; the servers run through it — no global installs):

    Terminal window
    brew install uv # or: curl -LsSf https://astral.sh/uv/install.sh | sh
  2. Bring the dev stack up — this publishes Postgres on 5432 and Valkey on 6379 (the development-labels overlay; production never exposes them):

    Terminal window
    cd infra/compose/compose && ./dev.sh up -d
  3. Copy the committed example into place. Your real config is gitignored, so any local edits stay local:

    Terminal window
    cp .mcp.json.example .mcp.json
  4. Restart your agent (Claude Code, Cursor, any MCP client) and approve the two servers when prompted.

That’s it — ask the agent to “list the tables” or “show the cache keys” and it queries the running stack.

{
"mcpServers": {
"postgres": {
"command": "uvx",
"args": ["--python", "3.13", "postgres-mcp", "--access-mode=restricted"],
"env": {
"DATABASE_URI": "postgresql://app:app_dev_password@localhost:5432/app"
}
},
"valkey": {
"command": "uvx",
"args": [
"--from",
"redis-mcp-server@latest",
"redis-mcp-server",
"--url",
"redis://localhost:6379/0"
]
}
}
}
  • Postgres uses postgres-mcp (Postgres MCP Pro). --access-mode=restricted is its read-only mode: read queries and EXPLAIN only, wrapped in read-only transactions. The --python 3.13 pin sidesteps a missing wheel on newer Python builds.
  • Valkey uses the official redis-mcp-server over the Redis wire protocol (Valkey is a drop-in). The default values match the dev stack: Postgres app / app_dev_password / db app, and Valkey DB 0 (the API’s; DB 1 is GlitchTip’s).

BoringStack’s pitch is that agents and humans get the same contract — lint enforces the architecture for both. MCP extends that to runtime: the agent inspects the same database and cache you do, so its edits are grounded in what’s actually there. Pair it with the spec loop and the agent plans against real schema instead of an imagined one.