@upstate-web/d1-readonly-mcp
v0.1.0
Published
MCP server that exposes read-only SQL queries against Cloudflare D1 — with write-blocking. Lets AI coding agents read your database safely without risking DROP TABLE, INSERT, UPDATE, DELETE, ALTER, or any other mutation.
Downloads
74
Maintainers
Readme
@upstate-web/d1-readonly-mcp
MCP server for safe, agent-accessible D1 queries. The only D1 MCP server that blocks writes.
The Problem
You want Claude Code (or any AI coding agent) to query your Cloudflare D1 database — but you don't want it to run DROP TABLE, INSERT, UPDATE, DELETE, or any other mutation. Every D1 user faces this: "How do I let my agent read the database without letting it destroy the database?"
The Solution
d1-readonly-mcp is a Model Context Protocol server that exposes a single tool: query_d1(sql). It runs SELECT queries against your D1 database via the wrangler CLI — and blocks all write operations before they reach D1.
Write blocking
The server uses a regex pattern that catches 15+ SQL write operations before passing the query to wrangler:
INSERT | UPDATE | DELETE | DROP | ALTER | CREATE | REPLACE |
TRUNCATE | MERGE | UPSERT | PRAGMA | ATTACH | DETACH |
REINDEX | VACUUM | BEGIN | COMMIT | ROLLBACKIf a query matches any of these, it returns a typed error — the query never touches your database.
Install
npm install -g @upstate-web/d1-readonly-mcpOr run via npx:
npx @upstate-web/d1-readonly-mcpPrerequisites
- Node.js >= 18
wranglerCLI installed and authenticated (npx wrangler loginorCLOUDFLARE_API_TOKENenv var)- A Cloudflare D1 database
Configuration
Set the database name via environment variable:
export D1_DATABASE="your-database-name" # defaults to "agency-db"Use with Claude Code
claude mcp add d1-readonly -- npx @upstate-web/d1-readonly-mcpOr with a custom database name:
claude mcp add d1-readonly \
--env D1_DATABASE=my-db \
-- npx @upstate-web/d1-readonly-mcpThen in a Claude Code session, the tool appears as query_d1. Example:
Claude: "query_d1: SELECT COUNT(*) FROM users WHERE created_at > '2026-01-01'"
The tool returns the result set as JSON. Write queries return an error.
Smoke Test
# Start the server on stdio
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"query_d1","arguments":{"sql":"SELECT 1"}}}' | D1_DATABASE=your-db npx @upstate-web/d1-readonly-mcpCompanion Packages
- @upstate-web/uwc-skills — Claude Agent Skills bundle
- @upstate-web/uwc-pipeline-mcp — MCP server for Agent Skills
- @upstate-web/uwc-django-skills — Django Agent Skills
License
MIT.
