Token导航 LogoToken导航TokenDH.com
研究检索敏感数据clawhub未标认证来源可访问clear审计提醒

crafty-controller狡猾的控制器

Agent Skill

crafty-controller 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

2,399

周安装

102

GitHub Stars

公开资料未说明

下载量

840
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:crafty-controller(狡猾的控制器)
来源仓库:https://github.com/zdstudios/crafty-controller
安装命令:
openclaw skills install crafty-controller
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install crafty-controller

简介

用于通过 REST API 管理 Crafty Controller 实例。

  • 适合在 OpenClaw 中启动、停止或配置 Minecraft 服务器时使用。
  • 通过 clawhub 安装,需结合来源仓库和 README 核验用法。
  • 安装前建议确认权限范围和维护状态。
  • crafty-controller 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

name
crafty_controller
description
Use this skill whenever the user wants to interact with a Crafty Controller instance via its REST API. Triggers include: managing Minecraft servers, starting/stopping/restarting servers, sending console commands, checking server stats, managing users, handling backups, viewing logs, managing files, working with schedules, or any Crafty Controller-related task. Use for any request referencing 'Crafty', 'Crafty Controller', 'game server panel', or Minecraft server management through a web panel.

Crafty Controller API Skill


⚙️ CONFIGURATION — SET THESE BEFORE ANYTHING ELSE

# ============================================================
#  CRAFTY CONTROLLER CONNECTION SETTINGS
#  Edit these three values to match your Crafty instance
# ============================================================

CRAFTY_HOST    = "https://your-server-ip-or-domain"   # e.g. "https://192.168.1.50" or "https://crafty.myserver.com"
CRAFTY_PORT    = 8443                                   # Default Crafty port — change if you use a custom one
CRAFTY_API_KEY = "your_api_key_here"                   # Found in Crafty UI → Profile → API Key

# Derived base URL — do not edit
CRAFTY_BASE_URL = f"{CRAFTY_HOST}:{CRAFTY_PORT}/api/v2"

# Standard headers used on every request
HEADERS = {
    "Authorization": f"Bearer {CRAFTY_API_KEY}",
    "Content-Type": "application/json"
}
# ============================================================
Where to find your API key: Log into Crafty Controller → click your username (top right) → API Key tab → copy the token.

Overview

Crafty Controller exposes a REST API under /api/v2. All endpoints require Bearer token authentication. The API covers:

DomainWhat you can do
ServersList, create, start, stop, restart, kill, delete
ConsoleSend commands, stream logs
StatsCPU, RAM, player counts, ping, world size
BackupsList, trigger, restore, delete
SchedulesList, create, update, delete cron tasks
FilesBrowse, read, write, upload, delete server files
UsersList, create, update, delete, assign roles
RolesList, create, assign permissions
Crafty ConfigServer-wide settings, announcements

Python Helper Setup

Install dependencies first:

pip install requests urllib3

Base client to reuse everywhere:

import requests
import urllib3
import json

# Suppress SSL warnings if using self-signed cert (common on local Crafty installs)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def crafty_get(path, params=None):
    """GET request to Crafty API."""
    url = f"{CRAFTY_BASE_URL}{path}"
    resp = requests.get(url, headers=HEADERS, params=params, verify=False)
    resp.raise_for_status()
    return resp.json()

def crafty_post(path, payload=None):
    """POST request to Crafty API."""
    url = f"{CRAFTY_BASE_URL}{path}"
    resp = requests.post(url, headers=HEADERS, json=payload or {}, verify=False)
    resp.raise_for_status()
    return resp.json()

def crafty_patch(path, payload=None):
    """PATCH request to Crafty API."""
    url = f"{CRAFTY_BASE_URL}{path}"
    resp = requests.patch(url, headers=HEADERS, json=payload or {}, verify=False)
    resp.raise_for_status()
    return resp.json()

def crafty_delete(path):
    """DELETE request to Crafty API."""
    url = f"{CRAFTY_BASE_URL}{path}"
    resp = requests.delete(url, headers=HEADERS, verify=False)
    resp.raise_for_status()
    return resp.json()

1. Servers

List All Servers

def list_servers():
    """Returns all servers registered in Crafty."""
    data = crafty_get("/servers")
    for s in data.get("data", []):
        print(f"[{s['server_id']}] {s['server_name']} — Running: {s['running']}")
    return data

Get Single Server Details

def get_server(server_id: str):
    """Get full details for a specific server."""
    return crafty_get(f"/servers/{server_id}")

Create a New Server

def create_server(
    name: str,
    java_path: str = "java",
    jar_path: str = "server.jar",
    min_ram: int = 512,
    max_ram: int = 2048,
    port: int = 25565,
    crash_detection: bool = True,
    auto_start: bool = False,
):
    payload = {
        "name": name,
        "java_path": java_path,
        "jar_path": jar_path,
        "min_ram": min_ram,
        "max_ram": max_ram,
        "port": port,
        "crash_detection": crash_detection,
        "auto_start": auto_start,
    }
    return crafty_post("/servers", payload)

Update Server Settings

def update_server(server_id: str, changes: dict):
    """
    Patch any combination of server fields.
    Example changes: {"max_ram": 4096, "auto_start": True}
    """
    return crafty_patch(f"/servers/{server_id}", changes)

Delete a Server

def delete_server(server_id: str):
    """Permanently delete a server from Crafty (does NOT delete files by default)."""
    return crafty_delete(f"/servers/{server_id}")

2. Server Power Actions

All power actions POST to /servers/{server_id}/action/{action}.

def server_action(server_id: str, action: str):
    """
    Valid actions:
      start_server    — start the server
      stop_server     — graceful stop
      restart_server  — stop then start
      kill_server     — force-kill (SIGKILL)
      backup_server   — trigger a backup immediately
    """
    return crafty_post(f"/servers/{server_id}/action/{action}")

# Convenience wrappers
def start_server(server_id):   return server_action(server_id, "start_server")
def stop_server(server_id):    return server_action(server_id, "stop_server")
def restart_server(server_id): return server_action(server_id, "restart_server")
def kill_server(server_id):    return server_action(server_id, "kill_server")

3. Console & Commands

Send a Console Command

def send_command(server_id: str, command: str):
    """
    Send any console command to a running server.
    Examples: "say Hello!", "op PlayerName", "weather clear", "stop"
    """
    return crafty_post(f"/servers/{server_id}/action/send_command", {"command": command})

Common Command Shortcuts

def op_player(server_id, player):     return send_command(server_id, f"op {player}")
def deop_player(server_id, player):   return send_command(server_id, f"deop {player}")
def kick_player(server_id, player, reason=""):
    cmd = f"kick {player}" + (f" {reason}" if reason else "")
    return send_command(server_id, cmd)
def ban_player(server_id, player, reason=""):
    cmd = f"ban {player}" + (f" {reason}" if reason else "")
    return send_command(server_id, cmd)
def say_message(server_id, message):  return send_command(server_id, f"say {message}")
def set_time(server_id, time):        return send_command(server_id, f"time set {time}")
def set_weather(server_id, weather):  return send_command(server_id, f"weather {weather}")
def give_item(server_id, player, item, amount=1):
    return send_command(server_id, f"give {player} {item} {amount}")
def teleport(server_id, player, x, y, z):
    return send_command(server_id, f"tp {player} {x} {y} {z}")

Get Server Logs

def get_logs(server_id: str):
    """Retrieve recent console log output for a server."""
    return crafty_get(f"/servers/{server_id}/logs")

4. Server Stats

def get_server_stats(server_id: str):
    """
    Returns live stats:
      - running (bool)
      - online_players (int)
      - max_players (int)
      - cpu (float, %)
      - mem (float, MB)
      - world_size (str)
      - server_port (int)
      - version (str)
      - desc (str, MOTD)
    """
    return crafty_get(f"/servers/{server_id}/stats")

def print_server_stats(server_id: str):
    stats = get_server_stats(server_id)
    d = stats.get("data", {})
    status = "🟢 Online" if d.get("running") else "🔴 Offline"
    print(f"""
  Status  : {status}
  Players : {d.get('online_players', 0)}/{d.get('max_players', 0)}
  CPU     : {d.get('cpu', 0):.1f}%
  RAM     : {d.get('mem', 0):.1f} MB
  Version : {d.get('version', 'N/A')}
  World   : {d.get('world_size', 'N/A')}
    """)

Get Stats for All Servers

def get_all_stats():
    """Snapshot stats for every registered server."""
    return crafty_get("/servers/stats")

5. Backups

List Backups for a Server

def list_backups(server_id: str):
    return crafty_get(f"/servers/{server_id}/backups")

Trigger a Manual Backup

def trigger_backup(server_id: str):
    """Immediately run a backup for the given server."""
    return server_action(server_id, "backup_server")

Get Backup Config

def get_backup_config(server_id: str):
    return crafty_get(f"/servers/{server_id}/backups/config")

Update Backup Config

def update_backup_config(server_id: str, changes: dict):
    """
    Example changes:
    {
      "backup_path": "/backups/myserver",
      "max_backups": 5,
      "compress": True,
      "shutdown_server": False
    }
    """
    return crafty_patch(f"/servers/{server_id}/backups/config", changes)

Delete a Backup

def delete_backup(server_id: str, backup_filename: str):
    return crafty_delete(f"/servers/{server_id}/backups/{backup_filename}")

6. Schedules

List Schedules

def list_schedules(server_id: str):
    return crafty_get(f"/servers/{server_id}/schedules")

Create a Schedule

def create_schedule(
    server_id: str,
    name: str,
    action: str,         # "command", "start", "stop", "restart", "backup"
    interval: int,       # how often (in the unit below)
    interval_type: str,  # "hours", "minutes", "days", "weeks" or a cron string
    command: str = "",   # only needed for action="command"
    enabled: bool = True,
    one_time: bool = False,
    cron_string: str = "",
):
    payload = {
        "name": name,
        "action": action,
        "interval": interval,
        "interval_type": interval_type,
        "command": command,
        "enabled": enabled,
        "one_time": one_time,
        "cron_string": cron_string,
    }
    return crafty_post(f"/servers/{server_id}/schedules", payload)

# Example: restart every 6 hours
# create_schedule(server_id, "6hr restart", "restart", 6, "hours")

# Example: daily backup
# create_schedule(server_id, "Daily Backup", "backup", 24, "hours")

# Example: broadcast message every 30 minutes
# create_schedule(server_id, "30min broadcast", "command", 30, "minutes", command="say Server has been running for 30 more minutes!")

Update a Schedule

def update_schedule(server_id: str, schedule_id: str, changes: dict):
    return crafty_patch(f"/servers/{server_id}/schedules/{schedule_id}", changes)

Delete a Schedule

def delete_schedule(server_id: str, schedule_id: str):
    return crafty_delete(f"/servers/{server_id}/schedules/{schedule_id}")

7. File Management

List Files / Browse Directory

def list_files(server_id: str, path: str = ""):
    """
    Browse the server's file system.
    path is relative to the server's root directory.
    Leave empty to list the root.
    """
    return crafty_get(f"/servers/{server_id}/files", params={"path": path})

Read a File

def read_file(server_id: str, file_path: str):
    """
    Read the contents of a text file (e.g. server.properties, ops.json).
    file_path is relative to server root.
    """
    return crafty_get(f"/servers/{server_id}/files", params={"path": file_path, "file": "true"})

Write / Update a File

def write_file(server_id: str, file_path: str, content: str):
    """
    Overwrite a file with new content.
    Useful for editing server.properties, whitelist.json, etc.
    """
    return crafty_post(f"/servers/{server_id}/files/save", {
        "path": file_path,
        "content": content
    })

Create a Directory

def create_directory(server_id: str, dir_path: str):
    return crafty_post(f"/servers/{server_id}/files/create", {"path": dir_path})

Delete a File or Directory

def delete_file(server_id: str, file_path: str):
    return crafty_post(f"/servers/{server_id}/files/delete", {"path": file_path})

Upload a File

def upload_file(server_id: str, local_file_path: str, upload_dir: str = ""):
    """Upload a local file into the server's directory."""
    url = f"{CRAFTY_BASE_URL}/servers/{server_id}/files/upload"
    with open(local_file_path, "rb") as f:
        files = {"file": f}
        data = {"path": upload_dir}
        # Note: don't pass Content-Type header for multipart
        auth_headers = {"Authorization": f"Bearer {CRAFTY_API_KEY}"}
        resp = requests.post(url, headers=auth_headers, files=files, data=data, verify=False)
    resp.raise_for_status()
    return resp.json()

8. Users

List All Users

def list_users():
    return crafty_get("/users")

Get a User

def get_user(user_id: str):
    return crafty_get(f"/users/{user_id}")

Create a User

def create_user(
    username: str,
    password: str,
    email: str = "",
    enabled: bool = True,
    superuser: bool = False,
):
    return crafty_post("/users", {
        "username": username,
        "password": password,
        "email": email,
        "enabled": enabled,
        "superuser": superuser,
    })

Update a User

def update_user(user_id: str, changes: dict):
    """
    Example changes:
    {"password": "newpass", "enabled": False}
    """
    return crafty_patch(f"/users/{user_id}", changes)

Delete a User

def delete_user(user_id: str):
    return crafty_delete(f"/users/{user_id}")

Update User Server Permissions

def set_user_server_permissions(user_id: str, server_id: str, permissions: list):
    """
    Permissions list can contain any of:
      "Commands", "Terminal", "Logs", "Schedule", "Backup",
      "Files", "Config", "Players"
    """
    return crafty_patch(f"/users/{user_id}", {
        "server_permissions": {server_id: permissions}
    })

9. Roles

List Roles

def list_roles():
    return crafty_get("/roles")

Get Role Details

def get_role(role_id: str):
    return crafty_get(f"/roles/{role_id}")

Create a Role

def create_role(name: str, servers: dict = None):
    """
    servers = {
      "server_id_1": {"permissions": "1111111"},  # bitmask string
      ...
    }
    """
    return crafty_post("/roles", {
        "role_name": name,
        "servers": servers or {}
    })

Update a Role

def update_role(role_id: str, changes: dict):
    return crafty_patch(f"/roles/{role_id}", changes)

Delete a Role

def delete_role(role_id: str):
    return crafty_delete(f"/roles/{role_id}")

Assign Role to User

def assign_role_to_user(user_id: str, role_id: str):
    return crafty_patch(f"/users/{user_id}", {"roles": [role_id]})

10. Crafty System Info

Get Crafty Version & System Stats

def get_crafty_info():
    """Returns Crafty version, uptime, OS info, Python version, etc."""
    return crafty_get("/server/stats")

Get All Audit Log Entries

def get_audit_log():
    return crafty_get("/crafty/audit-log")

Error Handling

All functions can raise requests.HTTPError. Wrap calls for production use:

def safe_call(fn, *args, **kwargs):
    try:
        result = fn(*args, **kwargs)
        if result.get("status") == "ok":
            return result.get("data")
        else:
            print(f"Crafty API error: {result.get('error')} — {result.get('data')}")
            return None
    except requests.exceptions.ConnectionError:
        print(f"❌ Cannot connect to Crafty at {CRAFTY_BASE_URL}. Check HOST and PORT.")
    except requests.exceptions.HTTPError as e:
        print(f"❌ HTTP {e.response.status_code}: {e.response.text}")
    except Exception as e:
        print(f"❌ Unexpected error: {e}")
    return None

Common Patterns

Full Server Status Dashboard

def dashboard():
    servers = crafty_get("/servers").get("data", [])
    print(f"{'Name':<25} {'Status':<10} {'Players':<12} {'CPU':<8} {'RAM'}")
    print("-" * 70)
    for s in servers:
        sid = s["server_id"]
        stats = get_server_stats(sid).get("data", {})
        status  = "Online " if stats.get("running") else "Offline"
        players = f"{stats.get('online_players',0)}/{stats.get('max_players',0)}"
        cpu     = f"{stats.get('cpu', 0):.1f}%"
        ram     = f"{stats.get('mem', 0):.0f}MB"
        print(f"{s['server_name']:<25} {status:<10} {players:<12} {cpu:<8} {ram}")

Restart All Running Servers

def restart_all():
    servers = crafty_get("/servers").get("data", [])
    for s in servers:
        if s.get("running"):
            print(f"Restarting {s['server_name']}...")
            restart_server(s["server_id"])

Edit server.properties Value

def set_property(server_id: str, key: str, value: str):
    """
    Read server.properties, change one key, write it back.
    Example: set_property(sid, "max-players", "50")
    """
    result = read_file(server_id, "server.properties")
    content = result.get("data", {}).get("content", "")
    lines = content.splitlines()
    new_lines = []
    found = False
    for line in lines:
        if line.startswith(f"{key}="):
            new_lines.append(f"{key}={value}")
            found = True
        else:
            new_lines.append(line)
    if not found:
        new_lines.append(f"{key}={value}")
    write_file(server_id, "server.properties", "\
".join(new_lines))
    print(f"✅ Set {key}={value}")

API Response Structure

Every Crafty API response follows this envelope:

{
  "status": "ok",       // "ok" or "error"
  "data": { ... },      // payload (dict, list, or string)
  "error": null         // error message if status is "error"
}

Always check response["status"] == "ok" before using response["data"].


Notes

  • SSL: Crafty uses a self-signed certificate by default. The helpers above pass verify=False. In production, provide your real cert path: verify="/path/to/cert.pem".
  • API version: This skill targets Crafty Controller v4 (/api/v2 routes). Crafty 3 uses a different API.
  • Permissions: Your API key inherits the permissions of the user it belongs to. For full access, generate the key from a superuser account.
  • Rate limiting: Crafty does not enforce rate limiting by default, but avoid hammering the stats endpoint — poll at most once per 5 seconds.

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

91.92%
按下载量换算772

安全审计

VirusTotal

可疑

ClawScan

可疑

Static analysis

通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills