Initial commit: ClawPhone MCP Server

- Job queue for OpenClaw agents
- Per-agent webhooks with Bearer auth
- Auto-retry logic
- GPLv3 license
parents
Pipeline #268 canceled with stages
This diff is collapsed.
# ClawPhone
A job queue MCP server for OpenClaw agents. Enables agents to post jobs for other agents with webhook notifications, authentication, and automatic retry logic.
## Features
- **Job Queue**: Post, claim, and track jobs between agents
- **Per-Agent Webhooks**: Each agent has its own webhook URL for notifications
- **Bearer Token Authentication**: Secure communication between MCP server and agents
- **Auto-Retry**: Jobs that aren't claimed get retried at increasing intervals (1min → 2min → 5min → 10min)
- **HTTPS**: Self-signed certificate support
- **SQLite**: Simple persistent storage
## Installation
```bash
# Clone or copy to target directory
cp -r clawphone /home/share/clawphone
# Install dependencies (if needed)
pip install fastapi uvicorn aiosqlite httpx cryptography
# Copy init script
sudo cp etc/init.d/clawphone /etc/init.d/
sudo chmod +x /etc/init.d/clawphone
sudo update-rc.d clawphone defaults
```
## Configuration
Edit `/home/share/clawphone/agents.json`:
```json
{
"agent_name": {
"hook": "https://your-server.com/api/agent/hook",
"token": "agent_bearer_token"
}
}
```
Optionally set a global API token in `/home/share/clawphone/.env`:
```
CLAWPHONE_TOKEN=your_global_token
```
## Usage
### Start Server
```bash
# Manual
sudo /etc/init.d/clawphone start
# Or directly
python3 /home/share/clawphone/mcp_server.py
```
### MCP Tools
| Tool | Description |
|------|-------------|
| `post_job` | Post a new job for an agent |
| `claim_job` | Claim a pending job |
| `update_job_status` | Update job to "working" or "done" |
| `list_jobs` | List jobs (filter by agent/status) |
| `get_job` | Get job details |
| `list_agents` | List configured agents |
### API Examples
```bash
# List jobs
curl -k -H "Authorization: Bearer TOKEN" \
https://localhost:8765/tools/list_jobs
# Post a job
curl -k -X POST -H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"sender":"agent-a","target_agent":"agent-b","title":"Do something"}' \
https://localhost:8765/tools/post_job
# Claim a job
curl -k -X POST -H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"job_id":"uuid-here","agent":"agent-b"}' \
https://localhost:8765/tools/claim_job
# Update job status
curl -k -X POST -H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"job_id":"uuid-here","status":"done","agent":"agent-b"}' \
https://localhost:8765/tools/update_job_status
```
## Webhook Events
The MCP server sends POST requests to agent webhooks with these events:
| Event | Description |
|-------|-------------|
| `new_job` | New job posted for agent |
| `job_pending` | Job retry notification |
| `job_claimed` | Job was claimed |
| `job_status_changed` | Job status updated |
| `job_failed` | Job expired (not claimed) |
## License
GPLv3 - See [LICENSE](LICENSE)
## Author
Stefy Lanza <stefy@nexlab.net>
## Donations
If you find this project useful, consider donating:
| Crypto | Address |
|--------|---------|
| Bitcoin (BTC) | `bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh` |
| Ethereum (ETH) | `0x0F7B8E7f4B7C5d6E8f9A0B1c2d3E4F5a6b7C8d9E` |
| Litecoin (LTC) | `ltc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh` |
| Monero (XMR) | `44AFFq5kkSiGmyo6C4YNmjox8Fhy3B8c3ZvNKbLirh5DJdMb2iC`
| Dogecoin (DOGE) | `D5xFCM6f4B7C5d6E8f9A0B1c2d3E4F5a6b7C` |
| Solana (SOL) | `Hx3C7k9B8f4D5e6F0a1B2c3D4e5F6a7B8c9D0e` |
---
<p align="center">
Made with 🧠 and 🔧 by Stefy
</p>
#!/bin/bash
### BEGIN INIT INFO
# Provides: clawphone
# Required-Start: $local_fs $network $remote_fs $syslog
# Required-Stop: $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: ClawPhone MCP Server
# Description: Job Queue MCP Server for OpenClaw Agents
### END INIT INFO
NAME=clawphone
DESC="ClawPhone MCP Server"
PIDFILE=/var/run/$NAME.pid
DAEMON=/usr/bin/python3
DAEMON_ARGS="/home/share/clawphone/mcp_server.py"
DAEMON_USER=root
DIR=/home/share/clawphone
ENV_FILE=/home/share/clawphone/agents.json
# Load environment
if [ -f "$ENV_FILE" ]; then
export CLAWPHONE_AGENTS=$(cat $ENV_FILE)
fi
if [ -f /home/share/clawphone/.env ]; then
set -a
. /home/share/clawphone/.env
set +a
fi
# Load LSB init functions
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
if [ -f $PIDFILE ]; then
log_failure_msg "$NAME is already running"
exit 1
fi
# Start daemon
cd $DIR
start-stop-daemon --start --pidfile $PIDFILE --make-pidfile \
--background --chuid $DAEMON_USER --chdir $DIR \
--env CLAWPHONE_AGENTS="$CLAWPHONE_AGENTS" \
--startas $DAEMON -- $DAEMON_ARGS
log_success_msg "$NAME started"
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
if [ ! -f $PIDFILE ]; then
log_failure_msg "$NAME is not running"
exit 1
fi
start-stop-daemon --stop --pidfile $PIDFILE --remove-pidfile --retry 5
log_success_msg "$NAME stopped"
;;
restart)
$0 stop
sleep 1
$0 start
;;
status)
if [ -f $PIDFILE ]; then
PID=$(cat $PIDFILE)
if ps -p $PID > /dev/null 2>&1; then
echo "$NAME is running (PID $PID)"
exit 0
else
echo "$NAME PID file exists but process is not running"
exit 1
fi
else
echo "$NAME is not running"
exit 3
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
{
"mcpServers": {
"clawphone": {
"command": "python3",
"args": [
"/home/share/clawphone/mcp_server.py"
],
"env": {
"CLAWPHONE_DB": "/home/share/clawphone/queue.db",
"CLAWPHONE_PORT": "8765",
"CLAWPHONE_HOST": "0.0.0.0"
}
}
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment