Summary
drop_component and deploy_component are missing from DESTRUCTIVE_OPERATIONS in components/mcp/tools/operations.ts, so when an operator opts them into mcp.operations.allow they are exposed without destructiveHint: true. As a result the agent's allowDestructive: false does not remove them and autoApprove: false does not gate them.
Mechanism
DESTRUCTIVE_OPERATIONS (components/mcp/tools/operations.ts, ~L173-193) lists drop_schema/table/user/role, restart, set_configuration, backups, etc. but not drop_component or deploy_component.
isDestructive() (~L244) is the only source of annotations.destructiveHint for operation tools (~L391).
- The agent derives its gating from that annotation:
agent/registryTools.ts:77-78 maps annotations.destructiveHint === true to destructive, and agent/mcpTools.ts:102 propagates it; agent/agent.ts applies allowDestructive / autoApprove to destructive tools only.
So with the agent enabled and either op allow-listed, an LLM-driven call to deploy_component (which writes code the Harper process then executes) or drop_component runs with neither the toolset filter nor the approval prompt applying. Both are opt-in and the caller still needs verifyPerms, so this is a safety-gate gap rather than an auth bypass.
Suggested fix
Add drop_component and deploy_component to DESTRUCTIVE_OPERATIONS (consider also add_component, package_component, set_component_file, drop_component_file if they are allow-listable, and audit the set against the full OPERATIONS_ENUM for other code-writing ops). Add a unit test asserting the hint on these tools, and an agent-level test that allowDestructive: false removes them.
Related: #1898 (added the set), documentation#635 (documents the gap).
— Claude Opus 5.5 (finding-triage)
Summary
drop_componentanddeploy_componentare missing fromDESTRUCTIVE_OPERATIONSincomponents/mcp/tools/operations.ts, so when an operator opts them intomcp.operations.allowthey are exposed withoutdestructiveHint: true. As a result the agent'sallowDestructive: falsedoes not remove them andautoApprove: falsedoes not gate them.Mechanism
DESTRUCTIVE_OPERATIONS(components/mcp/tools/operations.ts, ~L173-193) lists drop_schema/table/user/role, restart, set_configuration, backups, etc. but notdrop_componentordeploy_component.isDestructive()(~L244) is the only source ofannotations.destructiveHintfor operation tools (~L391).agent/registryTools.ts:77-78mapsannotations.destructiveHint === truetodestructive, andagent/mcpTools.ts:102propagates it;agent/agent.tsappliesallowDestructive/autoApproveto destructive tools only.So with the agent enabled and either op allow-listed, an LLM-driven call to
deploy_component(which writes code the Harper process then executes) ordrop_componentruns with neither the toolset filter nor the approval prompt applying. Both are opt-in and the caller still needsverifyPerms, so this is a safety-gate gap rather than an auth bypass.Suggested fix
Add
drop_componentanddeploy_componenttoDESTRUCTIVE_OPERATIONS(consider alsoadd_component,package_component,set_component_file,drop_component_fileif they are allow-listable, and audit the set against the fullOPERATIONS_ENUMfor other code-writing ops). Add a unit test asserting the hint on these tools, and an agent-level test thatallowDestructive: falseremoves them.Related: #1898 (added the set), documentation#635 (documents the gap).
— Claude Opus 5.5 (finding-triage)