07 Tools Reference - samerfarida/mcp-ssh-orchestrator GitHub Wiki
Purpose: Complete documentation of all MCP tools provided by MCP SSH Orchestrator, including parameters, return values, and usage examples.
All user-controlled parameters are validated before processing:
- Alias: Max 100 characters, alphanumeric, dash, underscore, dot only
- Command: Max 10,000 characters, no null bytes or control characters (except newline, tab, carriage return)
- Tag: Max 50 characters, alphanumeric, dash, underscore, dot only
- Task ID: Max 200 characters, alphanumeric, colon, dash, underscore only
Invalid inputs are rejected with clear error messages. Security events are logged for injection attempts.
MCP SSH Orchestrator provides 13 MCP tools that enable secure SSH command execution, host management, and policy testing. All tools follow the MCP specification and return structured JSON responses.
Return Types: Tools return either:
- Structured dicts for successful operations and policy denials (most common)
- JSON strings for some policy/network denial responses (for backward compatibility)
- Plain strings for validation errors and exceptional cases
FastMCP automatically:
- Generates JSON schemas for clients
- Validates tool outputs
- Wraps responses in MCP tool response format
Note: While most tools return structured dicts, some denial responses and error cases return JSON strings or plain strings. Clients should handle both dict and string return types.
-
ssh_ping- Health check -
ssh_list_hosts- List configured hosts -
ssh_describe_host- Get host details
-
ssh_run- Execute command on single host (blocks until complete) -
ssh_run_on_tag- Execute command on multiple hosts (blocks until all complete) -
ssh_cancel- Cancel running command
-
ssh_run_async- Start command execution asynchronously (returns immediately) -
ssh_get_task_status- Get current status of async task -
ssh_get_task_result- Get final result of completed task -
ssh_get_task_output- Stream recent output from running task -
ssh_cancel_async_task- Cancel async task
-
ssh_plan- Dry-run command (policy testing) -
ssh_reload_config- Reload configuration
FastMCP also exposes read-only resources so MCP clients can inspect your fleet without invoking tools.
-
Purpose: Sanitized inventory with
alias,host,port,tags,description, andhas_credentials_ref - Response:
{
"count": 4,
"hosts": [
{"alias": "prod-web-1", "host": "10.0.0.11", "port": 22, "tags": ["production","web"], "description": "Primary public web front-end", "has_credentials_ref": true}
]
}-
Purpose: Detailed metadata for a single alias, reusing
_validate_alias()for safety -
Behavior: Returns
{ "error": "<reason>" }for invalid inputs or missing hosts
- Purpose: Lightweight tag list for planning tag-based executions
-
Response:
{ "alias": "prod-web-1", "tags": ["production","web","critical-service"] }
- Purpose: High-level summary of policy-derived limits, network controls, and sample command allowances
-
Fields:
limits,policy_probes,network,features - Example snippet:
{
"alias": "prod-web-1",
"limits": {
"max_seconds": 60,
"max_output_bytes": 1048576,
"require_known_host": true,
"host_key_auto_add": false,
"deny_patterns_enabled": true
},
"policy_probes": [
{"probe": "basic_diagnostics", "command": "uptime", "allowed": true},
{"probe": "docker_status", "command": "docker ps", "allowed": false}
],
"network": {
"require_known_host": true,
"allowlist_enabled": true,
"blocklist_enabled": true
},
"features": {
"supports_async": true,
"supports_cancellation": true
}
}Resources show up in MCP Inspector, Cursor, Claude Desktop, and any MCP-compatible client under the Resources tab so LLMs can reason about topology before calling tools.
Purpose: Health check to verify mcp-ssh-orchestrator is running and responsive.
Parameters: None
Request:
{
"name": "ssh_ping",
"arguments": {}
}Response:
{
"status": "pong"
}Note: Tools now return structured JSON objects. FastMCP automatically generates schemas and validates outputs.
Use Cases:
- Verify MCP server is running
- Test connectivity to mcp-ssh-orchestrator
- Health monitoring and alerting
Example:
# Test via Claude Desktop
ssh_pingPurpose: List all configured hosts from servers.yml.
Parameters: None
Request:
{
"name": "ssh_list_hosts",
"arguments": {}
}Response:
{
"hosts": [
"web1",
"web2",
"db1",
"monitor1"
]
}Note: Returns a structured object with a hosts array. FastMCP generates the schema automatically.
Use Cases:
- Discover available hosts
- Verify host configuration
- Build dynamic host lists
Example:
# List all configured hosts
ssh_list_hostsPurpose: Get detailed information about a specific host.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
alias |
string | Yes | Host alias to describe | "web1" |
Request:
{
"name": "ssh_describe_host",
"arguments": {
"alias": "web1"
}
}Response:
{
"alias": "web1",
"host": "10.0.0.11",
"port": 22,
"credentials": "prod_admin",
"tags": ["production", "web"],
"description": "Primary web server"
}Use Cases:
- Get host connection details
- Verify host configuration
- Check policy limits for specific host
Example:
# Get details for web1
ssh_describe_host --alias "web1"Purpose: Dry-run a command to test policy rules without executing.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
alias |
string | Yes | Target host alias | "web1" |
command |
string | Yes | Command to test | "uptime" |
Request:
{
"name": "ssh_plan",
"arguments": {
"alias": "web1",
"command": "uptime"
}
}Response:
{
"alias": "web1",
"command": "uptime",
"hash": "4c2d8a8f7b1e",
"allowed": true,
"limits": {
"max_seconds": 60,
"max_output_bytes": 1048576,
"host_key_auto_add": false,
"require_known_host": true
}
}When
allowedisfalse, the response also includeswhyandhintfields so MCP clients know to callssh_planagain or consult the SSH Orchestrator prompts before retrying. No sensitive policy details are exposed.
Use Cases:
- Test policy rules before execution
- Inspect effective execution limits
- Debug policy configuration
- Validate command authorization
Example:
# Test if command would be allowed
ssh_plan --alias "web1" --command "uptime"
ssh_plan --alias "prod-web-1" --command "systemctl restart nginx"Purpose: Execute a command on a single host.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
alias |
string | Yes | Target host alias | "web1" |
command |
string | Yes | Command to execute | "uptime" |
Request:
{
"name": "ssh_run",
"arguments": {
"alias": "web1",
"command": "uptime"
}
}Response:
{
"task_id": "web1:4c2d8a8f7b1e:1700000000000",
"alias": "web1",
"hash": "4c2d8a8f7b1e",
"exit_code": 0,
"duration_ms": 1234,
"cancelled": false,
"timeout": false,
"target_ip": "10.0.0.11",
"output": "14:30:45 up 42 days, 3:14, 1 user, load average: 0.15, 0.08, 0.05"
}Policy or network denials return structured JSON with a
hintfield that reminds the caller to usessh_planor review the orchestrator prompts for next steps.
Response Fields:
| Field | Type | Description |
|---|---|---|
task_id |
string | Unique task identifier (alias:hash:timestamp) |
alias |
string | Target host alias |
hash |
string | Short SHA256 hash of the command |
exit_code |
integer | Command exit status (0 = success, -1 = connection/execution error) |
duration_ms |
integer | Execution time in milliseconds |
cancelled |
boolean | Whether command was cancelled |
timeout |
boolean | Whether command hit the time limit |
target_ip |
string | Actual IP address connected to |
output |
string | Combined stdout/stderr output (truncated to limit), or error message if exit_code is -1 |
Error Handling:
If SSH connection fails, the response includes:
-
exit_code: -1indicating connection/execution failure -
output: Specific, sanitized error message (e.g., "SSH connection refused: Port may be closed or firewall blocking") -
target_ip: ""(empty, as connection was not established) -
duration_ms: 0or small value (connection failed quickly)
Error Message Examples:
"SSH authentication failed: Invalid credentials""SSH connection timeout: Host did not respond""SSH connection refused: Port may be closed or firewall blocking""SSH hostname resolution failed: DNS lookup failed""SSH key file not found: Check key path configuration"
All error messages are sanitized for security (no IPs, hostnames, or file paths exposed). See Troubleshooting Guide for detailed solutions.
Use Cases:
- Execute single commands on hosts
- Run system diagnostics
- Perform maintenance tasks
- Test host connectivity
Example:
# Execute uptime command
ssh_run --alias "web1" --command "uptime"
# Check disk usage
ssh_run --alias "web1" --command "df -h"
# Check service status
ssh_run --alias "web1" --command "systemctl status nginx"Purpose: Execute a command on all hosts with a specific tag.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
tag |
string | Yes | Tag to match hosts | "production" |
command |
string | Yes | Command to execute | "uptime" |
Request:
{
"name": "ssh_run_on_tag",
"arguments": {
"tag": "production",
"command": "uptime"
}
}Response:
{
"tag": "production",
"results": [
{
"alias": "prod-web-1",
"task_id": "prod-web-1:4c2d8a8f7b1e:1700000000000",
"hash": "4c2d8a8f7b1e",
"exit_code": 0,
"duration_ms": 1100,
"cancelled": false,
"timeout": false,
"target_ip": "10.0.0.11",
"output": "uptime output..."
},
{
"alias": "prod-db-1",
"hash": "4c2d8a8f7b1e",
"denied": true,
"reason": "policy"
}
]
}Notes:
- Entries include
task_idwhen a command was executed. Denied hosts omittask_idand includedenied/reason. - Policy or network denials include
hinttext that points MCP clients back tossh_planor the orchestrator prompts for next steps. - No summary object is returned; aggregate stats can be derived from the
resultsarray.
Per-Host Error Handling:
Individual host failures are handled gracefully - one host failure does not stop execution on other hosts. Each host's result is included in the results array:
-
Successful hosts:
exit_code: 0,outputcontains command output -
Failed hosts:
exit_code: -1,outputcontains specific error message -
Denied hosts:
denied: true,reasonexplains why (policy/network)
Example Response with Mixed Success/Failure:
{
"tag": "production",
"results": [
{
"alias": "prod-web-1",
"task_id": "prod-web-1:4c2d8a8f7b1e:1700000000000",
"hash": "4c2d8a8f7b1e",
"exit_code": 0,
"duration_ms": 1100,
"cancelled": false,
"timeout": false,
"target_ip": "10.0.0.11",
"output": "uptime output..."
},
{
"alias": "prod-web-2",
"task_id": "prod-web-2:4c2d8a8f7b1e:1700000000001",
"hash": "4c2d8a8f7b1e",
"exit_code": -1,
"duration_ms": 5,
"cancelled": false,
"timeout": false,
"target_ip": "",
"output": "SSH connection timeout: Host did not respond"
},
{
"alias": "prod-db-1",
"hash": "4c2d8a8f7b1e",
"denied": true,
"reason": "policy"
}
]
}Error Messages:
Failed hosts return specific, actionable error messages in the output field:
"SSH connection refused: Port may be closed or firewall blocking""SSH connection timeout: Host did not respond""SSH authentication failed: Invalid credentials""SSH hostname resolution failed: DNS lookup failed"
All error messages are sanitized for security. See Troubleshooting Guide for detailed solutions.
Use Cases:
- Bulk operations across host groups
- Environment-wide maintenance
- Tag-based host management
- Parallel command execution
Example:
# Check uptime on all production hosts
ssh_run_on_tag --tag "production" --command "uptime"
# Check disk usage on all web servers
ssh_run_on_tag --tag "web" --command "df -h"
# Check service status on all database servers
ssh_run_on_tag --tag "database" --command "systemctl status postgresql"Purpose: Cancel a running command using its task ID.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
task_id |
string | Yes | Task ID to cancel | "web1:a1b2c3d4:1234567890" |
Request:
{
"name": "ssh_cancel",
"arguments": {
"task_id": "web1:a1b2c3d4:1234567890"
}
}Response:
Cancellation signaled for task_id: web1:4c2d8a8f7b1e:1700000000000
Errors:
-
Task not found: <task_id>— the ID is unknown or already completed.
Use Cases:
- Stop long-running commands
- Cancel stuck processes
- Emergency command termination
- Resource management
Example:
# Cancel a running command
ssh_cancel --task_id "web1:a1b2c3d4:1234567890"Purpose: Reload configuration files without restarting the MCP server.
Parameters: None
Request:
{
"name": "ssh_reload_config",
"arguments": {}
}Response:
Configuration reloaded.
Use Cases:
- Update configuration without restart
- Apply policy changes
- Add new hosts dynamically
- Update credentials
Example:
# Reload configuration
ssh_reload_configPurpose: Start SSH command execution asynchronously. Returns immediately with a task ID for polling results.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
alias |
string | Yes | Target host alias | "web1" |
command |
string | Yes | Command to execute | "long-running-script.sh" |
Request:
{
"name": "ssh_run_async",
"arguments": {
"alias": "web1",
"command": "long-running-script.sh"
}
}Response:
{
"task_id": "web1:4c2d8a8f7b1e:1700000000000",
"status": "pending",
"keepAlive": 300,
"pollFrequency": 5,
"alias": "web1",
"command": "long-running-script.sh",
"hash": "4c2d8a8f7b1e"
}Response Fields:
| Field | Type | Description |
|---|---|---|
task_id |
string | Unique async task identifier |
status |
string | Initial status (always "pending") |
keepAlive |
integer | Result retention time in seconds |
pollFrequency |
integer | Recommended polling interval in seconds |
alias |
string | Target host alias |
command |
string | Command being executed |
hash |
string | SHA256 hash of the command |
Use Cases:
- Long-running commands (minutes to hours)
- Background execution
- Non-blocking operations
- Progress monitoring
Example:
# Start long-running backup
ssh_run_async --alias "backup-server" --command "tar -czf /backup/full.tar.gz /data"
# Start deployment script
ssh_run_async --alias "prod-web" --command "./deploy.sh"Purpose: Get current status and progress of an async task without waiting for completion.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
task_id |
string | Yes | Async task ID | "async:web1:abc123" |
Request:
{
"name": "ssh_get_task_status",
"arguments": {
"task_id": "async:web1:abc123def456"
}
}Response:
{
"task_id": "web1:4c2d8a8f7b1e:1700000000000",
"status": "running",
"keepAlive": 300,
"pollFrequency": 5,
"progress_percent": 42,
"elapsed_ms": 18000,
"bytes_read": 8192,
"output_lines_available": 24
}Response Fields:
| Field | Description |
|---|---|
task_id |
Async task identifier |
status |
pending, running, completed, failed, or cancelled
|
keepAlive |
Seconds the result will be retained (approximate) |
pollFrequency |
Suggested polling interval in seconds |
progress_percent |
Progress estimate based on elapsed time vs max_seconds
|
elapsed_ms |
Milliseconds since task started |
bytes_read |
Bytes collected from stdout/stderr so far |
output_lines_available |
Number of buffered output lines retrievable via ssh_get_task_output
|
Errors:
-
Error: Task not found: <task_id>— unknown or expired ID.
Use Cases:
- Monitor long-running operations
- Check task progress percentage
- Verify task is still running
- Track execution time
Example:
# Check status
ssh_get_task_status --task_id "async:web1:abc123def456"
# Monitor every 5 seconds
watch -n 5 ssh_get_task_status --task_id "async:web1:abc123def456"Purpose: Get final result of a completed async task (success or failure).
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
task_id |
string | Yes | Async task ID | "async:web1:abc123" |
Request:
{
"name": "ssh_get_task_result",
"arguments": {
"task_id": "async:web1:abc123def456"
}
}Response:
{
"task_id": "web1:4c2d8a8f7b1e:1700000000000",
"status": "completed",
"exit_code": 0,
"duration_ms": 42000,
"output": "backup complete",
"cancelled": false,
"timeout": false,
"target_ip": "10.0.0.11",
"max_seconds": 3600
}Errors:
-
Error: Task not found or expired: <task_id>— result exceeded TTL or never existed.
Use Cases:
- Retrieve final output of completed tasks
- Check exit codes
- Analyze execution results
- Handle task outcomes
Example:
# Get final result
ssh_get_task_result --task_id "async:web1:abc123def456"
# Check if successful
if ssh_get_task_result --task_id "async:web1:abc123def456" | grep '"exit_code": 0'; then
echo "Task succeeded"
fiPurpose: Stream recent output lines from a running or completed task.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
task_id |
string | Yes | Async task ID | "async:web1:abc123" |
max_lines |
integer | No | Maximum lines to return (default: 50) | 100 |
Request:
{
"name": "ssh_get_task_output",
"arguments": {
"task_id": "async:web1:abc123def456",
"max_lines": 50
}
}Response:
{
"task_id": "web1:4c2d8a8f7b1e:1700000000000",
"output_lines": [
"[2025-11-09 14:30:41] backup chunk 12/42",
"[2025-11-09 14:30:42] backup chunk 13/42"
],
"total_lines": 384,
"has_more": true
}Response Fields:
| Field | Description |
|---|---|
task_id |
Async task identifier |
output_lines |
Most recent lines from stdout/stderr (bounded by max_lines) |
total_lines |
Total buffered lines available |
has_more |
true if additional lines can be retrieved |
Errors:
-
Error: Task not found or no output available: <task_id>— ID invalid or no buffered output.
Use Cases:
- Stream output from long-running tasks
- Monitor progress in real-time
- Debug running commands
- Check recent activity
Example:
# Get last 50 lines of output
ssh_get_task_output --task_id "async:web1:abc123def456"
# Get last 100 lines
ssh_get_task_output --task_id "async:web1:abc123def456" --max_lines 100
# Stream in real-time
while true; do
ssh_get_task_output --task_id "async:web1:abc123def456"
sleep 5
donePurpose: Cancel a running async task.
Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
task_id |
string | Yes | Async task ID to cancel | "web1:4c2d8a8f7b1e:1700000000000" |
Request:
{
"name": "ssh_cancel_async_task",
"arguments": {
"task_id": "web1:4c2d8a8f7b1e:1700000000000"
}
}Response:
Cancellation signaled for async task: web1:4c2d8a8f7b1e:1700000000000
Errors:
-
Task not found or not cancellable: <task_id>— task already finished or unknown.
Use Cases:
- Stop long-running commands
- Abort stuck processes
- Emergency termination
- Resource management
Example:
# Cancel async task
ssh_cancel_async_task --task_id "web1:4c2d8a8f7b1e:1700000000000"# Check system health
ssh_ping
# List all hosts
ssh_list_hosts
# Check specific host details
ssh_describe_host --alias "web1"# Test policy before execution
ssh_plan --alias "web1" --command "uptime"
ssh_plan --alias "prod-web-1" --command "systemctl restart nginx"
# Test network policies
ssh_plan --alias "web1" --command "ping 8.8.8.8"# System information
ssh_run --alias "web1" --command "uptime"
ssh_run --alias "web1" --command "df -h"
ssh_run --alias "web1" --command "free -h"
# Service management
ssh_run --alias "web1" --command "systemctl status nginx"
ssh_run --alias "web1" --command "systemctl is-active nginx"
# Process information
ssh_run --alias "web1" --command "ps aux | grep nginx"
ssh_run --alias "web1" --command "top -n 1"# Environment-wide checks
ssh_run_on_tag --tag "production" --command "uptime"
ssh_run_on_tag --tag "production" --command "df -h"
# Service-specific operations
ssh_run_on_tag --tag "web" --command "systemctl status nginx"
ssh_run_on_tag --tag "database" --command "systemctl status postgresql"
# Infrastructure checks
ssh_run_on_tag --tag "monitoring" --command "systemctl status prometheus"# Start long-running command (synchronous)
ssh_run --alias "web1" --command "tail -f /var/log/nginx/access.log"
# Cancel if needed
ssh_cancel --task_id "web1:a1b2c3d4:1234567890"
# Reload configuration
ssh_reload_config# Start async backup
TASK_ID=$(ssh_run_async --alias "backup-server" --command "tar -czf /backup/full.tar.gz /data")
# Monitor progress
ssh_get_task_status --task_id "$TASK_ID"
# Stream output in real-time
ssh_get_task_output --task_id "$TASK_ID" --max_lines 100
# Get final result when complete
ssh_get_task_result --task_id "$TASK_ID"
# Cancel if needed
ssh_cancel_async_task --task_id "$TASK_ID"# Start deployment asynchronously
TASK_ID=$(ssh_run_async --alias "prod-web" --command "./deploy.sh")
# Poll until complete
while true; do
STATUS=$(ssh_get_task_status --task_id "$TASK_ID" | jq -r '.status')
if [ "$STATUS" == "completed" ]; then
ssh_get_task_result --task_id "$TASK_ID"
break
elif [ "$STATUS" == "failed" ]; then
echo "Task failed"
ssh_get_task_result --task_id "$TASK_ID"
break
fi
sleep 5
doneMCP SSH Orchestrator provides 6 prompts that guide LLM behavior when interacting with the orchestrator. Prompts are reusable templates that help LLMs understand how to safely use the tools, handle denials, and suggest configuration changes.
Available Prompts:
-
ssh_orchestrator_usage - General usage guidance for SSH orchestrator tools
- Explains available tools and rules for safe usage
- Guides workflow patterns and best practices
-
ssh_policy_denied_guidance - How to handle policy denials
- Guides LLM on responding to policy denials
- Explains how to ask about policy changes and propose YAML snippets
-
ssh_network_denied_guidance - How to handle network policy denials
- Guides LLM on responding to network policy denials
- Explains how to ask about IP/CIDR allowlists and propose network changes
-
ssh_missing_host_guidance - How to handle missing host aliases
- Guides LLM on handling missing host aliases
- Explains how to propose YAML entries for servers.yml
-
ssh_missing_credentials_guidance - How to handle missing/incomplete credentials
- Guides LLM on handling missing credentials
- Explains how to propose YAML entries for credentials.yml
-
ssh_config_change_workflow - Global rules for config change suggestions
- Global workflow rules for suggesting config changes
- Explains how to handle all three YAML files (servers.yml, credentials.yml, policy.yml)
Using Prompts:
Prompts are exposed via the MCP protocol and can be retrieved using prompts/list and prompts/get operations. MCP clients (Claude Desktop, Cursor, etc.) can use these prompts to guide LLM behavior.
Example:
# List all available prompts
prompts/list
# Get a specific prompt
prompts/get --name ssh_orchestrator_usageNote: Prompts are client-controlled templates. The server does not invoke them automatically - they are used by MCP clients to guide LLM behavior.
-
Policy denied: Returns structured JSON with
status: "denied"andreason: "policy"— command matches a deny rule or substring. -
Host not found:
Error: Host alias not found: <alias>— configuration missing the requested host. -
Invalid alias/tag/command:
Error: <reason>— input validation failed (length, characters, null bytes, etc.). -
Network blocked: Returns structured JSON with
status: "denied"andreason: "network"— DNS resolution failed allowlist checks or post-connect IP blocked. -
SSH connection issues:
Run error: <sanitized message>— authentication, host key, or connection failures. Detailed context is logged to stderr for auditing.
Structured JSON Denial Responses:
Policy and network denials now return structured JSON for better LLM understanding:
{
"status": "denied",
"reason": "policy",
"alias": "web1",
"hash": "a1b2c3d4",
"command": "rm -rf /"
}{
"status": "denied",
"reason": "network",
"alias": "web1",
"hostname": "10.0.0.1",
"detail": "No resolved IPs allowed by policy.network"
}This structured format makes it easier for LLMs to parse and respond appropriately using the provided prompts.
Command Timeout:
{
"task_id": "web1:a1b2c3d4:1234567890",
"alias": "web1",
"command": "sleep 120",
"exit_code": 124,
"timeout": true,
"duration_ms": 60000
}All tools respect policy configuration:
- ssh_run, ssh_run_on_tag, and ssh_run_async check policy before execution
- ssh_plan shows policy decision without executing
- ssh_cancel and ssh_cancel_async_task respect cancellation policies
- ssh_reload_config validates new configuration
All tool usage is logged:
- JSON audit logs to stderr
- Complete operation trail for compliance
- Security-relevant metadata in every log entry
- Immutable log format for integrity
All tools enforce network policies:
- IP allowlists prevent unauthorized connections
- Host key verification prevents MITM attacks
- DNS resolution verification before connection
- Network segmentation via CIDR controls
- Usage Cookbook - Practical tool usage examples
- Configuration - Tool configuration and policies
- Troubleshooting - Common tool issues and solutions
- Deployment - Production tool deployment