{"slug": "mcp-should-not-mean-letting-ai-touch-your-database", "title": "MCP should not mean letting AI touch your database", "summary": "A developer building the NENE2 PHP framework argues that Model Context Protocol (MCP) tools should call application boundaries, not production databases directly. The framework enforces this by mapping MCP tools to documented HTTP APIs with safety levels (read, write, admin, destructive) and structured error responses using RFC 9457. The approach aims to prevent AI agents from bypassing application logic and security controls.", "body_md": "After publishing my first article about **NENE2**, a small PHP framework for AI-readable business APIs, one comment stood out:\n\nconsistent JSON envelopes matter more than ever when agents are parsing responses.\n\nI agree.\n\nBut predictable JSON is only one part of the story.\n\nThe bigger question is:\n\n**What should an AI agent be allowed to touch?**\n\nMy answer is simple:\n\n**An MCP tool should call your application boundary, not your production database.**\n\nMCP is useful because it gives AI tools a structured way to call capabilities.\n\nBut if we use it carelessly, it can become a very polished shortcut around the application:\n\n``` php\nAI Agent\n  -> MCP Tool\n  -> direct SQL query\n  -> production database\n```\n\nThat may feel convenient during a demo.\n\nIt is also exactly the kind of thing I do not want in business software.\n\nThe database does not know the full application rules:\n\nYour application knows those things.\n\nSo the agent should go through the application.\n\nThe direction I use in NENE2 is:\n\n``` php\nAI Agent\n  -> MCP Tool\n  -> documented HTTP API\n  -> handler\n  -> use case\n  -> repository / transaction boundary\n```\n\nThis is less magical.\n\nThat is the point.\n\nIf an AI agent asks for the status of a record, the tool should call the same read API that a normal client would call.\n\nIf an AI agent creates or updates something, the tool should call the same write API that already validates the request, checks credentials, logs the request, and returns a predictable error shape.\n\nMCP should expose application capabilities.\n\nIt should not invent a second, hidden application.\n\nIn NENE2, OpenAPI is the public API contract.\n\nThat makes it a natural starting point for MCP tool definitions.\n\nIf the HTTP API says:\n\n```\nGET /examples/notes/{id}\n```\n\nthen an MCP tool can map to that operation:\n\n```\ngetExampleNoteById\n```\n\nThe tool does not need to know where the note is stored.\n\nIt does not need SQL.\n\nIt does not need to load a `.env`\n\nfile.\n\nIt needs:\n\nThe API remains the contract.\n\nI think most MCP integrations should start with read tools.\n\nRead tools are easier to reason about:\n\nThey still need authorization when the data is private, but they do not mutate state.\n\nThat makes them a good first milestone for teams learning how agents interact with their product.\n\nIn NENE2, MCP tools have safety levels such as:\n\n`read`\n\n`write`\n\n`admin`\n\n`destructive`\n\nThe first tools should usually be `read`\n\n.\n\nWrite tools need more design.\n\nAdmin and destructive tools need even more.\n\nWrite tools are not forbidden.\n\nBut they should not be treated as a weekend shortcut.\n\nA write tool needs the same kind of design you would expect from any sensitive API:\n\nIn local NENE2 development, write tools can call documented write endpoints.\n\nWhen `NENE2_LOCAL_JWT_SECRET`\n\nis configured, write tools require a valid Bearer JWT.\n\nFor production tools, the bar should be higher:\n\nProduction MCP tools are product features.\n\nThey are not debugging shortcuts.\n\nWhen an MCP tool calls an HTTP API, it should preserve the API's error behavior.\n\nFor NENE2, that means **RFC 9457 Problem Details**.\n\nIf a request is invalid, the agent should see a structured error.\n\nIf authentication fails, the agent should see a structured 401.\n\nIf a domain object is not found, the agent should see a structured 404.\n\nThe tool should not collapse everything into:\n\n```\nSomething went wrong.\n```\n\nAgents need predictable failure shapes too.\n\nGood error contracts are part of AI-readability.\n\nThis sounds obvious, but it matters.\n\nMCP configuration often lives close to developer tooling.\n\nThat makes it tempting to commit values that should never be committed:\n\nNENE2's guidance is:\n\n`.env`\n\nsecretsA tool can say it requires a scope.\n\nIt should not expose the credential.\n\nI also maintain **nene-mcp**, a small PHP stdio MCP bridge.\n\nIt can expose HTTP APIs as MCP tools using a committed `tools.json`\n\ncatalog.\n\nThe shape is intentionally simple:\n\n``` php\nMCP client\n  -> stdio JSON-RPC\n  -> nene-mcp\n  -> HTTP API\n```\n\nIt is not a customer-facing API gateway.\n\nIt is a sidecar for local development, staging, and small team workflows.\n\nIt works best when the application already has documented HTTP endpoints and a clear tool catalog.\n\nThat is the same idea again:\n\n**MCP should call the app, not bypass it.**\n\nWhen designing an MCP tool, I like to ask:\n\nCould a normal HTTP client safely do this through the documented API?\n\nIf yes, the MCP tool is probably a good wrapper.\n\nIf no, I ask another question:\n\nWhy does this capability exist only for the agent?\n\nSometimes there is a good answer.\n\nOften there is not.\n\nIf the capability is real business behavior, it probably deserves an application API, tests, documentation, and review.\n\nAn AI-readable API is not just an API with JSON.\n\nIt is an API where:\n\nThis is the design direction behind NENE2.\n\nIt is also why I prefer boring architecture:\n\n``` php\nHandler\n  -> Use Case\n  -> Repository\n```\n\nThe agent can understand it.\n\nThe developer can review it.\n\nThe tests can cover it.\n\nThe database stays behind the application boundary.\n\nI am still refining this approach through NENE2 and the surrounding NeNe OSS series.\n\nIf you are building MCP tools for business APIs, I would be interested to hear where you draw the line between useful automation and unsafe shortcuts.", "url": "https://wpnews.pro/news/mcp-should-not-mean-letting-ai-touch-your-database", "canonical_source": "https://dev.to/hideyukimori/mcp-should-not-mean-letting-ai-touch-your-database-57p1", "published_at": "2026-06-25 13:18:14+00:00", "updated_at": "2026-06-25 13:43:56.058144+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-safety", "large-language-models", "ai-infrastructure"], "entities": ["NENE2", "MCP", "RFC 9457", "OpenAPI", "nene-mcp", "PHP"], "alternates": {"html": "https://wpnews.pro/news/mcp-should-not-mean-letting-ai-touch-your-database", "markdown": "https://wpnews.pro/news/mcp-should-not-mean-letting-ai-touch-your-database.md", "text": "https://wpnews.pro/news/mcp-should-not-mean-letting-ai-touch-your-database.txt", "jsonld": "https://wpnews.pro/news/mcp-should-not-mean-letting-ai-touch-your-database.jsonld"}}