agentmux 0.6.0

Multi-agent coordination runtime with inter-agent messaging across CLI, MCP, tmux, and ACP.
Documentation
use rmcp::ErrorData as McpError;
use schemars::JsonSchema;
use serde_json::json;

use super::errors::validation_tool_error;
use super::params::{
    GRANT_COMMAND_LIST, GRANT_COMMAND_RESOLVE, GRANT_OUTCOME_SELECTED, GrantListArgs,
    GrantResolveArgs, HelpParams, LIST_COMMAND_SESSIONS, ListArgs, LookParams, NAMESPACE_AGENTMUX,
    RawwParams, SendParams, TOOL_GRANT, TOOL_HELP, TOOL_LIST, TOOL_LOOK, TOOL_RAWW, TOOL_SEND,
};

pub(super) fn help_tool(params: HelpParams) -> Result<serde_json::Value, McpError> {
    let query = params.query.as_deref().map(str::trim).unwrap_or_default();
    match query {
        "" | NAMESPACE_AGENTMUX => Ok(json!({
            "namespace": NAMESPACE_AGENTMUX,
            "shape_hints": [
                "Call help with query='list' or 'grant' for meta-tool command lists.",
                "Call help with query='list.sessions', 'grant.list', or 'grant.resolve' for command args schemas.",
                "Call help with query='send', 'look', or 'raww' for exact tool args schemas."
            ],
            "tools": [
                {"tool": TOOL_LIST, "kind": "meta_tool", "description": "List sessions for one bundle or fan out across bundles."},
                {"tool": TOOL_SEND, "kind": "tool", "description": "Submit a message to explicit targets or broadcast."},
                {"tool": TOOL_LOOK, "kind": "tool", "description": "Inspect a target session pane snapshot for this bundle."},
                {"tool": TOOL_RAWW, "kind": "tool", "description": "Write raw text directly to one target session."},
                {"tool": TOOL_GRANT, "kind": "meta_tool", "description": "Inspect or resolve pending ACP permission requests."},
                {"tool": TOOL_HELP, "kind": "tool", "description": "Return tool/command help and JSON schemas."}
            ],
            "invoke": {
                "tool": TOOL_HELP,
                "params": {"query": TOOL_LIST}
            }
        })),
        TOOL_LIST => Ok(json!({
            "tool": TOOL_LIST,
            "kind": "meta_tool",
            "description": "List sessions for one bundle or fan out across bundles.",
            "commands": [
                {
                    "command": "list.sessions",
                    "description": "List sessions for one bundle or fan out across bundles."
                }
            ],
            "invoke": {
                "tool": TOOL_LIST,
                "params": {
                    "command": LIST_COMMAND_SESSIONS,
                    "args": {}
                }
            }
        })),
        "list.sessions" => Ok(command_help(
            "list.sessions",
            "List sessions for one bundle or fan out across bundles.",
            json_schema_for::<ListArgs>(),
            json!({
                "tool": TOOL_LIST,
                "params": {
                    "command": LIST_COMMAND_SESSIONS,
                    "args": {}
                }
            }),
        )),
        TOOL_SEND => Ok(command_help(
            TOOL_SEND,
            "Submit a message to explicit targets or broadcast.",
            json_schema_for::<SendParams>(),
            json!({
                "tool": TOOL_SEND,
                "params": {}
            }),
        )),
        TOOL_LOOK => Ok(command_help(
            TOOL_LOOK,
            "Inspect a target session pane snapshot for this bundle.",
            json_schema_for::<LookParams>(),
            json!({
                "tool": TOOL_LOOK,
                "params": {}
            }),
        )),
        TOOL_RAWW => Ok(command_help(
            TOOL_RAWW,
            "Write raw text directly to one target session.",
            json_schema_for::<RawwParams>(),
            json!({
                "tool": TOOL_RAWW,
                "params": {}
            }),
        )),
        TOOL_HELP => Ok(command_help(
            TOOL_HELP,
            "Return tool/command help and JSON schemas.",
            json_schema_for::<HelpParams>(),
            json!({
                "tool": TOOL_HELP,
                "params": {}
            }),
        )),
        TOOL_GRANT => Ok(json!({
            "tool": TOOL_GRANT,
            "kind": "meta_tool",
            "description": "Inspect or resolve pending ACP permission requests.",
            "commands": [
                {
                    "command": "grant.list",
                    "description": "List pending ACP permission requests for the associated bundle."
                },
                {
                    "command": "grant.resolve",
                    "description": "Submit an ACP-native decision on a pending permission request."
                }
            ],
            "invoke": {
                "tool": TOOL_GRANT,
                "params": {
                    "command": GRANT_COMMAND_LIST,
                    "args": {}
                }
            }
        })),
        "grant.list" => Ok(command_help(
            "grant.list",
            "List pending ACP permission requests for the associated bundle.",
            json_schema_for::<GrantListArgs>(),
            json!({
                "tool": TOOL_GRANT,
                "params": {
                    "command": GRANT_COMMAND_LIST,
                    "args": {}
                }
            }),
        )),
        "grant.resolve" => Ok(command_help(
            "grant.resolve",
            "Submit an ACP-native decision on a pending permission request.",
            json_schema_for::<GrantResolveArgs>(),
            json!({
                "tool": TOOL_GRANT,
                "params": {
                    "command": GRANT_COMMAND_RESOLVE,
                    "args": {
                        "permission_request_id": "<uuid>",
                        "outcome": GRANT_OUTCOME_SELECTED,
                        "option_id": "<option-id>"
                    }
                }
            }),
        )),
        _ => Err(validation_tool_error(
            "validation_invalid_params",
            "unknown help query; try empty query, 'agentmux', 'list', 'list.sessions', 'send', 'look', 'raww', 'grant', 'grant.list', or 'grant.resolve'",
            Some(json!({"query": query})),
        )),
    }
}

fn command_help(
    command: &str,
    description: &str,
    args_schema: serde_json::Value,
    invoke: serde_json::Value,
) -> serde_json::Value {
    json!({
        "command": command,
        "description": description,
        "args_schema": args_schema,
        "invoke": invoke,
    })
}

fn json_schema_for<T: JsonSchema>() -> serde_json::Value {
    serde_json::to_value(schemars::schema_for!(T)).unwrap_or(serde_json::Value::Null)
}