Claude Code Plugins

Community-maintained marketplace

Feedback

Run diagnostic scripts in sandbox with human approval (MCP tool)

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name shannot
description Run diagnostic scripts in sandbox with human approval (MCP tool)

Shannot - Sandboxed System Diagnostics

Run diagnostic scripts in a sandbox with human approval.

Usage

# Run a script locally
shannot run script.py

# Run against a remote host
shannot run script.py --target user@host

# Dry-run mode (queue all operations for review)
shannot run script.py --dry-run

After running with --dry-run, instruct the user to open shannot approve to review and execute queued operations.

MCP Integration (v0.5.0+)

Shannot provides MCP (Model Context Protocol) integration for LLM agents like Claude.

Available Tools

sandbox_run - Execute Python 3.6 scripts with profile-based approval:

  • Fast path: Auto-approved operations execute immediately
  • Review path: Unapproved operations create sessions for user approval
  • Blocked path: Denied operations rejected immediately

session_result - Poll status of pending sessions

Profiles

  • minimal: ls, cat, grep, find
  • readonly: minimal + head, tail, file, stat, wc, du
  • diagnostics: readonly + df, free, ps, uptime, hostname, uname, env, id

Example MCP Usage

# Check disk space (diagnostics profile auto-approves df)
sandbox_run({
  "script": "import subprocess\nsubprocess.call(['df', '-h'])",
  "profile": "diagnostics"
})
# Returns immediately with disk usage

# Search files (may require approval depending on profile)
sandbox_run({
  "script": "import subprocess\nsubprocess.call(['find', '/home', '-name', '*.log'])",
  "profile": "minimal"
})
# Returns session ID for user approval
# User reviews: shannot approve show <session_id>
# User approves: shannot approve --execute <session_id>
# Poll results: session_result({"session_id": "<session_id>"})

Remote Execution

# Run diagnostics on a remote server
sandbox_run({
  "script": "import subprocess\nsubprocess.call(['df', '-h'])",
  "profile": "diagnostics",
  "target": "prod"  # Uses configured remote target
})

Installation

# Install for Claude Desktop/Code
shannot mcp install --client claude-code

See MCP Documentation for complete guide.

Diagnostic Script Examples

System Health Check

# health_check.py - Comprehensive system status
import subprocess

print("=== System Information ===")
subprocess.call(["uname", "-a"])

print("\n=== Uptime ===")
subprocess.call(["uptime"])

print("\n=== Disk Usage ===")
subprocess.call(["df", "-h"])

print("\n=== Memory Usage ===")
subprocess.call(["free", "-h"])

print("\n=== Top Processes ===")
subprocess.call(["ps", "aux", "--sort=-pcpu"])

Log Analysis

# analyze_logs.py - Search for errors in logs
import subprocess

print("=== Recent Errors ===")
subprocess.call(["grep", "-i", "error", "/var/log/syslog"])

print("\n=== Last 50 Lines ===")
subprocess.call(["tail", "-n", "50", "/var/log/syslog"])

Network Diagnostics

# network_check.py - Network status
import subprocess

print("=== Network Interfaces ===")
subprocess.call(["ip", "addr"])

print("\n=== Listening Ports ===")
subprocess.call(["ss", "-tlnp"])

print("\n=== Routing Table ===")
subprocess.call(["ip", "route"])

Service Status

# service_check.py - Check systemd services
import subprocess

services = ["nginx", "postgresql", "redis"]

for service in services:
    print(f"\n=== {service} ===")
    subprocess.call(["systemctl", "status", service, "--no-pager"])

File System Inspection

# fs_check.py - Filesystem analysis
import subprocess
import os

print("=== Large Files ===")
subprocess.call(["find", "/var", "-size", "+100M", "-type", "f"])

print("\n=== Disk I/O Stats ===")
subprocess.call(["iostat", "-x", "1", "3"])

print("\n=== Mount Points ===")
subprocess.call(["mount"])

Configuration Audit

# config_audit.py - Check configuration files
import os

configs = [
    "/etc/nginx/nginx.conf",
    "/etc/postgresql/14/main/postgresql.conf",
    "/etc/redis/redis.conf"
]

for config in configs:
    print(f"\n=== {config} ===")
    if os.path.exists(config):
        with open(config) as f:
            # Print first 20 lines
            for i, line in enumerate(f):
                if i >= 20:
                    print("... (truncated)")
                    break
                print(line.rstrip())
    else:
        print("File not found")

Writing Scripts

Scripts run in a virtualized environment with Python 3.6 syntax.

Running Commands

import subprocess

# Commands are intercepted and queued for approval
result = subprocess.run(["ls", "-la", "/etc"], capture_output=True, text=True)
print(result.stdout)

Reading Files

# File reads are allowed within the virtual filesystem
with open("/etc/hostname") as f:
    print(f.read())

Writing Files

# Writes are queued for approval, not executed immediately
with open("/tmp/output.txt", "w") as f:
    f.write("diagnostic results")

Python 3.6 Compatibility

Sandboxed scripts must use Python 3.6 syntax:

# Use namedtuple instead of dataclasses
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])

# Use Union from typing instead of pipe syntax
from typing import Union
def process(x):
    # type: (Union[int, str]) -> None
    pass

# Use if/elif instead of match statements
if value == 1:
    print("one")
elif value == 2:
    print("two")

Security Model

  • Reads: Allowed within virtual filesystem boundaries
  • Commands: Queued for human approval (or auto-approved via profile)
  • Writes: Queued for human approval
  • Network: Disabled (socket calls return errors)

Tips

  • Keep scripts focused on diagnostics and information gathering
  • Use --dry-run to preview what operations a script will request
  • Tell the user to run shannot approve to review queued operations
  • Use the appropriate profile for your use case (diagnostics for system info, minimal for restricted access)
  • For remote targets, ensure SSH keys are configured