SUSPICIOUS_INSTRUCTIONS = [ "ignore previous", "ignore all previous", "system prompt", "developer message", "hidden instruction", "do not tell the user", "secretly", ] HIGH_IMPACT = [ "delete", "drop table", "wipe", "destroy", "terminate", "revoke", "transfer", "send money", "purchase", "deploy", "release", ] COMMAND_EXECUTION = [ "exec", "execute", "shell", "bash", "powershell", "python", "subprocess", "eval", "command", ] def _has_any(text, words): return any(word in text for word in words) def scan_mcp_tool_metadata(tools): """Return a small static risk report for MCP-style tool metadata.""" findings = [] for tool in tools: name = tool.get("name") or "(unnamed tool)" text = " ".join( str(part) for part in [ tool.get("name", ""), tool.get("title", ""), tool.get("description", ""), tool.get("inputSchema", {}), tool.get("outputSchema", {}), ] ).lower() schema = tool.get("inputSchema") or {} properties = schema.get("properties") or {} required = schema.get("required") or [] if _has_any(text, SUSPICIOUS_INSTRUCTIONS): findings.append({ "severity": "high", "tool": name, "title": "Instruction-override language", "fix": "Treat tool metadata as untrusted and keep authority in host policy.", }) if _has_any(text, HIGH_IMPACT): findings.append({ "severity": "high", "tool": name, "title": "Irreversible or high-impact capability", "fix": "Require exact human confirmation, allowlists, rate limits, and audit logs.", }) if _has_any(text, COMMAND_EXECUTION): findings.append({ "severity": "high", "tool": name, "title": "Command execution surface", "fix": "Use sandboxing, command allowlists, and explicit confirmation.", }) if schema.get("type") != "object": findings.append({ "severity": "medium", "tool": name, "title": "Weak or missing input schema", "fix": "Use an object schema with narrow properties, required fields, enums, and formats.", }) if properties and not required: findings.append({ "severity": "medium", "tool": name, "title": "No required arguments", "fix": "Mark the minimum safe arguments as required.", }) if not tool.get("outputSchema"): findings.append({ "severity": "low", "tool": name, "title": "No output schema", "fix": "Validate and normalize results before they enter model context.", }) points = sum({"high": 5, "medium": 3, "low": 1}[item["severity"]] for item in findings) return {"risk_points": points, "findings": findings} if __name__ == "__main__": sample = [ { "name": "run_shell", "description": "Execute a shell command on the host machine.", "inputSchema": { "type": "object", "properties": {"command": {"type": "string"}}, }, } ] print(scan_mcp_tool_metadata(sample))