A workflow automation platform implements an MCP server that exposes tools to Claude for managing production infrastructure. The MCP tool schema for restart_service is: {"name": "restart_service", "description": "Restarts a production service", "inputSchema": {"service_name": {"type": "string"}}}. During an incident response, an operator prompts Claude to 'restart the payment service.' Claude calls restart_service({"service_name": "payment-service"}) correctly. Later, a different operator asks Claude to 'fix the slow database.' Claude calls restart_service({"service_name": "database"}) — a dangerous action that causes a production outage. What MCP schema design would have constrained Claude's tool use to safer choices?
Select an answer to reveal the explanation.
Short Explanation
Here's the deal — schema-level constraints are the most reliable safety control in MCP tool design. If you restrict service_name to an enum of valid, pre-approved values, the database is structurally excluded from the tool's possible inputs.
Full Explanation
Schema-level constraints are the most reliable safety control in MCP tool design. By restricting the service_name parameter to an enum of valid, pre-approved service names that are safe to restart — for example ['payment-service', 'auth-service', 'notification-service'] — and adding a description noting that the tool is for stateless services only, the database is structurally excluded from the tool's possible inputs. Claude cannot call the tool with 'database' because the schema will reject it during tool use generation. This implements capability minimization at the schema level. The confirmation boolean field can be gamed — Claude may set it to true based on its interpretation of the request, not based on human confirmation. The warning in the tool description is the described failure mode: Claude interpreted 'fix the slow database' as a restart problem and ignored or overrode the warning. Description-based constraints are advisory, not enforced. The two-step validate_restart followed by execute_restart approach adds friction but doesn't prevent the wrong service from being specified in validate_restart — Claude would still name 'database' in the validation call.