Field notes
MCP server security and auth
Check who can call each tool, on whose behalf and with which permissions. Carry that identity into the audit trail.
A remote MCP server is an API whose primary caller is a language model acting on instructions it partly read from untrusted content. That is the threat model in one sentence, and it should change how you build.
Ordinary API security still applies. What follows is the part that is specific to serving agents.
Identity: three parties, not two
A normal API has a caller and a server. An MCP server has a client application, an end user, and a model in the middle deciding what to invoke. Your token has to carry enough to answer all three questions: which integration is calling, on whose behalf, and with what permitted surface.
- Per-client tokens. One per integration, revocable independently. Never one key for everyone.
- User context inside the token. For multi-user products, the token binds to an end user so row-level permissions still apply downstream.
- Short lifetimes with refresh. Long-lived bearer tokens in agent configuration files leak. Assume it and limit the window.
- Tool allowlist on the token. A read-only integration must be structurally unable to reach a write tool.
Never let the model choose its own permissions
A tool must not treat a model-supplied role or a boolean called confirm as authorization. The model will set that parameter based on context it does not fully control. That is not a permission system, it is a suggestion box.
Authorization decisions are made server-side from the token, every time, with no input from the arguments. This is the same principle as the runtime-permission argument in prompt injection is not a prompt problem, applied at the protocol boundary.
Three tiers for tools
- Read. Runs unattended. Still rate limited, still scoped, still logged, and still filtered by the caller's data permissions.
- Write, reversible. Requires validation, an idempotency key, and a bounded blast radius. Creating a draft, adding a note, updating a status.
- Irreversible. Sending money, sending email to customers, deleting records, changing access. These require a human approval step or a one-time signed grant issued for that exact payload.
Tier three is where teams get uncomfortable, because a human gate feels like it defeats the automation. It does not. The agent still does all the preparation and reasoning. A person reviews the proposed action and its supporting information. Match the approval step to the consequences of the action and the information a reviewer needs.
Untrusted content is the main attack path
The realistic attack is not someone hitting your server directly. It is a document, ticket, email, or web page containing instructions, which your tool faithfully returns, and which the model then treats as guidance.
- Label retrieved content as data. Fence it clearly and state in the tool description that the content is untrusted and must not be followed as instruction.
- Strip or neutralize instruction-shaped patterns in returned text where the format allows it.
- Separate contexts. The agent that reads untrusted documents should not be the agent that holds write credentials. Pass structured findings between them, not raw text.
- Validate outputs against a schema before any write. A write tool that only accepts a narrow shape cannot be talked into arbitrary behavior.
The payload was one line in the footer of a PDF. The agent had permission to email, so it emailed.
Rate limits and cost as security controls
Agents fail by repetition. A malformed loop can hit a tool thousands of times in a minute, and if that tool is expensive, that is a financial denial of service.
- Per-token and per-tool rate limits with proper 429 responses.
- Daily call ceilings per token, alerting before the hard stop.
- Duplicate-call detection. Identical arguments repeated in a short window is a bug signature worth rejecting outright.
- Spend attribution per token so you can find the expensive caller in minutes, per the metrics in observability.
Audit logging that would survive a review
If a customer asks what your agent did to their data on a Tuesday in March, you need an answer that does not involve guessing.
Log caller identity, token scope, tool, normalized arguments, outcome, timestamp, and the agent run ID. Keep it append-only. Keep write and irreversible calls far longer than read calls. Redact payload content but never the fact of the call. That distinction is what makes the log both useful and safe to retain.
Deployment hygiene
- Server-side secrets only. Never let a tool return a credential, and never accept one as an argument.
- Egress restrictions on the server, so a compromised dependency cannot quietly exfiltrate.
- Separate staging server with its own tokens and its own data. Agents exploring your staging environment against production data is a preventable category of incident.
- A documented revocation path. When a token leaks, the fix should be one command, not an investigation.
Ship checklist
- Per-client, short-lived, scoped tokens with tool allowlists.
- Server-side authorization only, never from arguments.
- Read, reversible write, and irreversible tiers enforced in code.
- Untrusted content fenced, separated, and schema-validated.
- Rate limits, daily caps, duplicate-call rejection.
- Append-only audit log with run correlation.
- Egress limits, staging isolation, one-command revocation.
Check tool access in the context of the workflow that calls the server. If you have a stalled product build that has to work for a real customer, pilot, or launch, send the project brief. Scope and price are agreed before work starts. Related reading: shipping a production MCP server, AI agent security, what actually breaks.
Frequently asked
How do you authenticate an MCP server?
Issue short-lived, scoped tokens per client and per user, validate them on every call, and attach a tool allowlist to each token. For multi-user products, exchange the end user's identity for a downstream credential rather than sharing one service key.
Should an MCP server use one shared API key?
No, not for anything multi-user. A shared key means every caller has every permission and your audit log cannot attribute actions. Per-client tokens with narrow scopes are the minimum bar.
How do you handle destructive tools safely?
Put irreversible actions behind an explicit approval step or a one-time signed token issued for that specific action and payload. The agent should be able to request the action and unable to complete it alone.
What should an MCP audit log contain?
Caller identity, token scope, tool name, normalized arguments, outcome, timestamp, and a request ID that ties back to the agent run. Keep write and irreversible calls on a longer retention than read calls.
Have a stalled product build?
I help founders turn stalled product builds into software ready for a real customer, pilot, or launch.
Show me what exists, what is stuck, and what needs to work. I take ownership of the implementation, test the agreed user journey, and document the handoff.
New field notes also go out on my newsletter. Subscribe on Substack.

Written by
Alex Cinovoj, TechTide AI
Founder & CTO, TechTide AI · CTO & Co-Founder, CPG Playbook. I’m based in Columbus, Ohio, and spent 13 years in IT across support, systems, cloud, architecture, and engineering, and the last 2 years on AI implementation. I’m a Lovable Senior Champion, an earned Discord community-support volunteer role, with 9 Anthropic Academy course completions. Logs over vibes. Production over theater.