Standalone CLI and daemon for NapCat QQ bot management with skills-fs integration.
NapCat CLI provides two interfaces for interacting with your QQ bot:
- CLI Tools — Direct command-line access to all NapCat API features
- skills-fs Integration — Filesystem-based API exposure for AI agents
┌─────────────┐ WebSocket ┌──────────────┐
│ NapCat │◄─────────────────────────┤ Daemon │
│ Server │ │ (watch.py) │
└─────────────┘ └──────────────┘
│ HTTP API │
│ │ Events + Alerts
▼ ▼
┌─────────────┐ ┌──────────────┐
│ napcat │◄─────────────────────────┤ Filesystem │
│ CLI │ HTTP Provider (18821) │ Bridge │
└─────────────┘ └──────────────┘
│
▼
┌──────────────────┐
│ skills-fs │
│ Virtual Files │
└──────────────────┘
│
▼
┌──────────────────┐
│ AI Agent │
│ (Hermes) │
└──────────────────┘
napcatCLI — Command-line interface for all QQ bot operationsdaemon/watch.py— WebSocket listener + HTTP provider serverlib/— Core API client and event handlingskills-fs/— Virtual filesystem engine (submodule)
The skills-fs integration exposes QQ bot capabilities as an intuitive virtual filesystem:
~/.napcat-cli/skills/napcat-cli/ # FUSE mountpoint
├── SKILL.md # Auto-generated skill documentation
├── AGENTS.md # Agent guide: daemon setup and navigation
├── persona.md # Bot persona / system prompt artifact
├── napcat/ # API endpoints as files
│ ├── events/ # Real-time event stream
│ ├── alerts/ # Pending notifications
│ ├── groups/ # Dynamic directory: group IDs
│ │ └── {group_id}/ # Dynamic directory: time ranges + send file
│ │ ├── AGENTS.md
│ │ ├── send # Write message JSON to send to this group
│ │ └── {recent,1days,...}/ # Dynamic directory: message IDs
│ │ └── {message_id} # API file: read message metadata
│ ├── friends/ # Dynamic directory: user IDs
│ │ └── {user_id}/ # Dynamic directory: time ranges + send file
│ │ ├── AGENTS.md
│ │ ├── send # Write message JSON to send to this friend
│ │ └── {recent,1days,...}/ # Dynamic directory: message IDs
│ │ └── {message_id} # API file: read message metadata
│ ├── send_group # Legacy group send endpoint
│ ├── send_private # Legacy private send endpoint
│ └── ... # Other API endpoints
- Browse Intuitively — Navigate
napcat/to explore endpoints. - Read Operations — Files contain data (JSON, text, etc.).
- Write Operations — Writing JSON to a write-enabled file triggers the corresponding NapCat API call. The JSON payload is forwarded as provider parameters (requires
writeParams: "json"). - Dynamic Directories —
napcat/groups/{group_id}/...andnapcat/friends/{user_id}/...are provider-backed directories that render IDs, time ranges, and message IDs on demand. Each directory also exposes asendfile scoped to that group or friend. - Auto-Generated Docs —
SKILL.mdis generated from the skill definition and exposed at the FUSE root viaexposeAtRoot: true. - Persona Artifact —
persona.mdis mounted as a blob at the FUSE root for agents to read the bot persona. - Agent Guidance (AGENTS.md) — Per-directory
AGENTS.mdfiles describe what each directory contains and what parameters are available, so agents can navigate without guessing.
# Check bot status
cat ~/.napcat-cli/skills/napcat-cli/napcat/status
# Read recent events
cat ~/.napcat-cli/skills/napcat-cli/napcat/events
# Browse group messages dynamically
ls ~/.napcat-cli/skills/napcat-cli/napcat/groups
ls ~/.napcat-cli/skills/napcat-cli/napcat/groups/123456
cat ~/.napcat-cli/skills/napcat-cli/napcat/groups/123456/AGENTS.md
ls ~/.napcat-cli/skills/napcat-cli/napcat/groups/123456/recent
cat ~/.napcat-cli/skills/napcat-cli/napcat/groups/123456/recent/1001
# Send to a specific group by writing to its send file
echo '{"message": "Hello group!"}' > ~/.napcat-cli/skills/napcat-cli/napcat/groups/123456/send
# Browse private friend messages
ls ~/.napcat-cli/skills/napcat-cli/napcat/friends
ls ~/.napcat-cli/skills/napcat-cli/napcat/friends/987654
cat ~/.napcat-cli/skills/napcat-cli/napcat/friends/987654/recent/2001
# Send to a specific friend
echo '{"message": "Hi!"}' > ~/.napcat-cli/skills/napcat-cli/napcat/friends/987654/send
# Clear a specific alert
echo '{"name": "NEW_MESSAGE"}' > ~/.napcat-cli/skills/napcat-cli/napcat/clear_alert# Check bot status
napcat status
# List groups
napcat group list
# List group members
napcat group members <group_id>
# Send messages
napcat send group <group_id> -m "<message>" [--at USER_ID]
napcat send private <user_id> -m "<message>"
# Message management
napcat recall <message_id> [--group <group_id>]
# Friend operations
napcat friend list
napcat friend info <user_id>
# Events and alerts
napcat events --type message --limit 10
napcat alerts --clear# Raw API access (like `gh api`)
napcat api get_login_info
napcat api send_group_msg '{"group_id": 123456, "message": "Hello"}'
# Custom API endpoint
napcat api .send_poke '{"user_id": 123456}'# Start the daemon (WebSocket + HTTP provider)
napcat daemon start
# Check daemon status
napcat daemon status
# Stop the daemon
napcat daemon stop- Python 3.10+
- NapCat server running (Docker or native)
- Go compiler (for skills-fs build)
-
Clone repository
git clone https://github.com/255doesnotexist/napcat-cli.git cd napcat-cli -
Initialize submodules
git submodule update --init --recursive
-
Build skills-fs
cd skills-fs make build cd ..
-
Install napcat CLI
chmod +x napcat sudo ln -s $(pwd)/napcat ~/.local/bin/napcat
-
Configure
napcat config set api_url http://127.0.0.1:18801 napcat config set token "" napcat config set self_id 123456789
NAPCAT_API_URL— NapCat HTTP API endpoint (default:http://127.0.0.1:18801)NAPCAT_TOKEN— API authentication tokenNAPCAT_DATA_DIR— Data directory (default:~/.napcat-data)
A sample skills-fs-config.json is shipped in the repository root. Copy it to the runtime location and adjust the home path if needed:
cp skills-fs-config.json ~/.napcat-cli/skills-fs.jsonKey configuration points:
- FUSE mountpoint — Start
skills-fswith--mountpoint ~/.napcat-cli/skills/napcat-cli(no-fssuffix). The generatedSKILL.mdis exposed at the FUSE root viaexposeAtRoot: true. - Payload forwarding — Every write-enabled API mount uses
"writeParams": "json"so that the JSON written to the file is forwarded as provider parameters. - Persona artifact —
persona.mdis mounted as a blob at/persona.md.
Note: because skillsRoot is ~/.napcat-cli/skills, the skill generator writes SKILL.md to ~/.napcat-cli/skills/napcat-cli/SKILL.md before the FUSE daemon mounts. After FUSE mounts, that on-disk file is hidden and replaced by the virtual /SKILL.md exposed by exposeAtRoot: true. This is expected.
skills-fs fuse --config ~/.napcat-cli/skills-fs.json \
--mountpoint ~/.napcat-cli/skills/napcat-cli \
--allow-other \
--log-file ~/.napcat-cli/skills-fuse.logIf you need to validate or regenerate the config while FUSE is already mounted, unmount it first (e.g. fusermount3 -u ~/.napcat-cli/skills/napcat-cli), then validate and remount.
Example minimal config snippet:
{
"providers": [
{ "id": "napcat", "url": "http://127.0.0.1:18821/invoke" }
],
"skillsRoot": "$HOME/.napcat-cli/skills",
"skills": [
{
"name": "napcat-cli",
"description": "NapCat QQ bot messaging — send messages, read events, manage groups, handle friends",
"enabled": true,
"version": "1.0.0",
"author": "Ezra",
"license": "MIT",
"platforms": ["linux"],
"metadata": { "source": "napcat-cli", "category": "messaging" },
"allowedTools": ["read_file", "write_file", "list_directory"],
"bodyTemplate": "# NapCat CLI Skill\n...",
"exposeAtRoot": true
}
],
"mounts": [
{ "path": "/napcat", "kind": "dir", "mode": "0755" },
{ "path": "/persona.md", "kind": "blob", "mode": "0444", "data": "..." },
{
"path": "/napcat/send_group",
"kind": "api",
"provider": "napcat",
"read": "napcat_send_group_msg",
"write": "napcat_send_group_msg",
"mode": "0644",
"writeParams": "json"
}
]
}The daemon (daemon/watch.py) provides:
- Messages — Group and private messages
- Notices — Poke, recall, ban, admin changes, member join/leave
- Requests — Friend and group requests
- Meta — Connection status, heartbeat
The daemon generates alert files for important events:
NAPCAT_CLI_NEW_MESSAGE— Any new messageNAPCAT_CLI_AT_ME— Bot was @mentionedNAPCAT_CLI_REPLY_TO_ME— Reply to bot's messageNAPCAT_CLI_NEW_POKE— Poke receivedNAPCAT_CLI_NEW_REQUEST— Friend/group requestNAPCAT_CLI_NEED_WAKE_UP— Composite alert for agent attention
When wake_on_event is true in config, the daemon executes wake_command for important events (friend requests, @mentions, bans, kicks, etc.). The command string supports one variable:
$REASON/${REASON}/{reason}— replaced with the event reason code. Possible values:AT_ME,REPLY_TO_ME,GROUP_TRIGGER,PRIVATE_TRIGGER,NEW_POKE,PROFILE_LIKE,GROUP_ADMIN_CHANGE,BOT_BANNED,BOT_KICKED_FROM_GROUP,GROUP_DISBANDED,NEW_GROUP_MEMBER,MY_MESSAGE_RECALLED,NEW_FRIEND,NEW_REQUEST,BOT_OFFLINE
Examples for different agents:
# Hermes
napcat config set wake_command "hermes send --to weixin 'QQ事件: \$REASON,请检查 ~/.napcat-data/alerts/ 并考虑回复'"
# Claude Code (notify via file watch or custom script)
napcat config set wake_command "echo 'QQ事件: \$REASON,请检查 ~/.napcat-data/alerts/ 并考虑回复' >> ~/.napcat-data/.agent-wake"
# Generic shell script
napcat config set wake_command "/path/to/notify.sh 'QQ事件: \$REASON,请检查 ~/.napcat-data/alerts/ 并考虑回复'"Security: wake_command runs verbatim via shell=True with the user's privileges. Do not paste untrusted templates.
Daemon runs HTTP server implementing skills-fs provider contract:
- Endpoint:
http://127.0.0.1:18821 - Actions:
get_events,get_alerts,clear_alert,list_groups,list_friends,list_time_ranges,list_messages,get_message,send_group_message,send_private_message,napcat_*(API proxy) - Format: JSON request/response
Dynamic directory actions return entries in the format {"entries": [{"name": "...", "kind": "..."}]} so skills-fs can render them as directories.
napcat-cli/
├── napcat # Main CLI script
├── config.py # Configuration management
├── skills-fs-config.json # Sample skills-fs configuration (shipped with repo)
├── persona.md # Bot persona configuration (mounted as FUSE artifact)
├── lib/
│ ├── api.py # NapCat HTTP API client
│ ├── events.py # Event filesystem bridge
│ └── config.py # Data directory paths
├── daemon/
│ └── watch.py # WebSocket daemon + HTTP provider
├── skills-fs/ # Virtual filesystem (submodule)
└── README.md # This file
# Test CLI commands
napcat status
napcat group list
# Test daemon
python3 daemon/watch.py ~/.napcat-data/daemon.json
# Test skills-fs
cd skills-fs && make testContributions welcome! Proudly powered by skills-fs.
Same as parent project.
- NapCat — NapCat OneBot 11 implementation
- skills-fs — Virtual filesystem engine
- Hermes — AI agent framework (if applicable)
Note: This project is designed for integration with AI agent frameworks. The filesystem-based API design makes it intuitive for agents to explore and interact with QQ bot capabilities through familiar file operations.