How I Built a Read-Only SQLite MCP Server in Python (and Why Read-Only Matters)
Giving an LLM a database connection is one of those ideas that sounds great in a demo and terrifying in production. The agent writes a slightly-wrong query, and now you're explaining to your team why orders is empty. So when I wanted an AI agent (Claude Desktop, in my case) to answer questions about a SQLite database, I didn't want to hand it a read-write connection and hope for the best. I built a small MCP server that gives the agent read-only SQL access — and I made "read-only" mean it, with two independent layers of protection. Here's how it works, and the design decisions that matter. Full source: github.com/skycandykey1/mcp-sqlite-server (MIT). A 30-second primer on MCP The Model Context Protocol (MCP) is an open standard for connecting AI apps to tools and data. An MCP client (Claude Desktop, Claude Code, Cursor, ...) connects to MCP servers that expose three kinds of capability: Tools — functions the model can call ( query , list_tables , ...) Resources — read-only data the model can pull in (a schema, a file) Prompts — reusable prompt templates The Python SDK ships a high-level helper, FastMCP , that turns this into a few decorators. The interesting part isn't the protocol — it's the safety design behind the tools. Design: keep the dangerous part away from the protocol The first decision: the read-only safety logic has zero MCP dependency. It lives in a plain module ( db.py ) that knows nothing about MCP, so I can unit-test it with nothing but the standard library. The server ( server.py ) is a thin wrapper. That separation matters: the part that must never be wrong (write protection) is testable in isolation, without spinning up an MCP client. Two layers of write protection A single guard is a single point of failure. So write protection happens twice, independently. Layer 1 — open the database read-only at the engine level: import sqlite3 def connect ( path : str ) -> sqlite3 . Connection : """ Open a SQLite database in READ-ONLY mode. Any write raises Op