MCP server security: safe defaults for systems of record
Short answer: an MCP server in front of a legacy system should be read-only by default, validate every input, run with least privilege, and log every call. Anything riskier should require an explicit opt-in.
Why defaults matter
An AI agent can call tools in ways you did not anticipate. When the tool sits in front of a database or a transactional service, a bad call can modify or leak real data. Safe defaults mean the easy path is also the safe path.
Five guardrails
- Read-only first. Do not expose writes, deletes or arbitrary SQL unless an operator deliberately enables them.
- Validate inputs. Check every tool argument against a JSON Schema before it reaches the back end. Reject unknown fields and out-of-range values.
- Least privilege. Use a dedicated service account that can only do what the exposed tools need.
- Audit logging. Record which tool was called, with which arguments, by whom and when, so incidents can be investigated.
- Keep secrets out of the model. Credentials belong in server configuration, not in prompts, tool arguments or tool descriptions.
Beware of prompt injection
Data returned by a legacy system can contain text that tries to steer the agent. Treat tool output as untrusted, and avoid giving a single agent both access to sensitive reads and the ability to send data out.
How legacy2mcp approaches this
legacy2mcp is designed around these ideas: no arbitrary SQL or writes without explicit opt-in, JSON Schema validation of tool inputs, and audit logging. Source on GitHub.
FAQ
Is read-only enough?
It greatly reduces risk but does not remove it; reads can still expose sensitive data, so scope access and log it.
Should agents be allowed to write?
Only through narrow, well-described tools with validation and, for high-impact actions, human approval.