A production MCP server gives an AI client a route into your application's data and actions. Its security boundary is still your server: the model's tool choice, a tool annotation, or a client confirmation prompt cannot authorize access on its own. Treat every tool call as an untrusted request and enforce the same product rules you would enforce for an API.
Map the threat model before exposing tools
List what each tool can read, change, and send outside your system. Include the user and tenant involved, the data returned to the model, and any downstream API calls. A tool that reads one public document has a different risk profile from one that exports customer records or sends messages. Start with the smallest useful set of tools and scopes.
Keep read and write operations visibly separate. Give high-impact actions explicit names and clear descriptions. Tool annotations can help a client understand intended behavior, but the MCP maintainers describe them as hints, not a security contract. Enforce permissions in code.
Authenticate and authorize every protected call
For a remote server accessing private data, implement the authorization flow required by the clients you support. Verify token signature or introspection result as appropriate, issuer, audience, expiry, and scopes. Resolve the caller's tenant from trusted identity data; do not accept a tenant identifier in model supplied arguments as proof of access. Then check the caller's permission to the specific resource and operation.
OpenAI's MCP authentication guide states that the server must verify token, scopes, and audience on every invocation. Test missing, expired, wrong-audience, and insufficient-scope tokens. Add a cross-tenant test where a valid user requests another customer's record.
Validate inputs and constrain effects
Parse tool arguments against the declared schema and validate them again at the application boundary. Limit pagination and expensive queries. Use allowlists for fields or destinations where appropriate. For a write, check the resource's current state and idempotency needs so retries do not duplicate an action. For irreversible operations, require an explicit product confirmation or additional authorization step where your workflow calls for one.
Prompt injection can arrive through documents, search results, and other tool output. Treat such content as data, never as an instruction that can expand permissions. Keep the model from receiving secrets it does not need, and keep tools from using a result's text as authority to invoke a privileged operation. OpenAI's security guidance recommends least privilege, server-side validation, and human confirmation for irreversible operations.
Reduce data in responses and logs
Return only the fields needed for the current task. Do not include access tokens, secrets, or unrelated personal information in tool results or UI metadata. For debugging, log a correlation ID, tool name, authorized principal, outcome, and timing; redact sensitive arguments and result bodies. Define retention and access controls for traces based on your own data policy.
Test the boundary, not just the happy path
- Call each tool with missing, malformed, and oversized arguments.
- Try a valid token for the wrong tenant and a token with read-only scope against a write tool.
- Put instruction-like text in a retrieved record and verify it cannot authorize another action.
- Retry writes and confirm the server handles duplicates safely.
- Check that errors and logs do not leak tokens or private records.
Run these tests directly with the MCP Inspector and through the AI clients you intend to support. Review the test results again after tool, auth, or infrastructure changes. Manufact can help teams build and deploy the MCP server, but the access rules should come from your product and be verified by your own test cases.











