Skip to content

Confirmation Flow

mcdbus asks for user confirmation before performing operations that could change system state. This page explains when confirmation triggers, how the three-tier fallback cascade works, and how environment variables control the behavior.

Two conditions trigger a confirmation prompt:

  1. System bus method calls. Any call to call_method with bus="system". The system bus can affect the entire machine, so every method call requires explicit approval.

  2. Property mutations on any bus. Any call to set_property, regardless of which bus. Changing a property is always a state mutation, even on the session bus.

Read-only operations never trigger confirmation. This includes list_services, introspect, list_objects, get_property, get_all_properties, and all the shortcut tools (battery_status, network_status, bluetooth_devices, list_systemd_units, send_notification, media_player_control). The shortcut tools either read properties only or operate on the session bus.

When confirmation is required, mcdbus tries three methods in sequence. If one succeeds, the remaining tiers are skipped. If all three are exhausted, the behavior depends on configuration.

The preferred method. mcdbus calls ctx.elicit(), which is a native MCP protocol feature that presents the user with a choice dialog in their MCP client. The prompt shows the operation details (service, method, path, arguments) and offers two options: “Yes, proceed” and “No, cancel.”

If the MCP client supports elicitation and the user selects “Yes, proceed”, the operation continues. If the user selects “No, cancel”, the operation is aborted with a ToolError.

If the client does not implement elicitation at the protocol level, ctx.elicit() either returns a CancelledElicitation or throws an exception. In either case, mcdbus catches this and falls through to Tier 2.

This tier is opt-in. It activates only when the MCDBUS_NOTIFY_CONFIRM environment variable is set to a non-empty value (e.g., MCDBUS_NOTIFY_CONFIRM=1).

When active, mcdbus sends a desktop notification through org.freedesktop.Notifications on the session bus. The notification has the urgency set to critical and presents two action buttons: “Approve” and “Deny.”

The implementation registers D-Bus signal match rules for ActionInvoked and NotificationClosed before sending the notification, ensuring no signal can be missed due to a race condition. It then waits up to 60 seconds for the user to respond.

If the user clicks “Approve”, the operation proceeds. If they click “Deny”, dismiss the notification, or let it expire, the operation is aborted. If the notification service itself is unreachable, mcdbus logs the failure and falls through to Tier 3.

If both Tier 1 and Tier 2 fail or are unavailable, mcdbus logs a warning to stderr and allows the operation to proceed.

This is the default behavior when no confirmation method is available. The rationale is that the operation was initiated by Claude at the user’s request, and blocking it entirely when no confirmation channel exists would make the tool unusable in environments that lack elicitation support.

The warning is written to stderr (and to the systemd journal if running as a service), creating an audit trail even when no interactive confirmation was possible.

Confirmation required?
|
+-- No --> Execute immediately
|
+-- Yes --> Try MCP elicitation (ctx.elicit)
|
+-- User approved --> Execute
|
+-- User denied --> Abort (ToolError)
|
+-- Elicitation unavailable
|
+-- MCDBUS_REQUIRE_ELICITATION set?
| |
| +-- Yes --> Abort (ToolError: "Elicitation required
| | but client does not support it")
| |
| +-- No --> Continue to fallbacks
|
+-- MCDBUS_NOTIFY_CONFIRM set?
|
+-- Yes --> Send desktop notification
| |
| +-- User clicked Approve --> Execute
| |
| +-- User clicked Deny / dismissed / timed out --> Abort
| |
| +-- Notification service unreachable --> Proceed with warning
|
+-- No --> Proceed with warning (log to stderr)

Two environment variables control the confirmation flow:

MCDBUS_REQUIRE_ELICITATION — When set to any non-empty value, mcdbus refuses to proceed if the MCP client does not support elicitation. No fallback to notifications or warn-and-proceed. The operation fails immediately with a ToolError. Use this in high-security deployments where you need a guarantee that every sensitive operation was explicitly approved through the MCP protocol.

MCDBUS_NOTIFY_CONFIRM — When set to any non-empty value, enables the desktop notification fallback (Tier 2). Without this, mcdbus skips directly from Tier 1 failure to Tier 3 (proceed with warning). Use this when your MCP client does not support elicitation but you have a graphical session with a notification daemon.

Both can be set in the systemd unit file:

[Service]
Environment=MCDBUS_REQUIRE_ELICITATION=1
Environment=MCDBUS_NOTIFY_CONFIRM=1

If both are set, MCDBUS_REQUIRE_ELICITATION takes priority. The notification fallback is never reached because elicitation failure immediately aborts the operation.

Regardless of which tier handles confirmation, mcdbus logs every system bus method call and every property mutation to stderr. The log message includes the bus type, service name, interface, method (or property name), object path, and signature. When running under systemd, these messages go to the journal and can be reviewed with:

Terminal window
journalctl -u mcdbus.service | grep "mcdbus:"

This audit trail exists independently of the confirmation mechanism. Even Tier 3 (proceed with warning) produces a log entry, so you can always reconstruct what operations were performed.