{"id":50958576,"url":"https://github.com/walker1211/clawside","last_synced_at":"2026-06-18T10:32:17.579Z","repository":{"id":363262072,"uuid":"1232157304","full_name":"walker1211/clawside","owner":"walker1211","description":"Local MCP sidecar and truth layer for OpenClaw handoffs, workflows, and delivery bridges.","archived":false,"fork":false,"pushed_at":"2026-06-08T06:00:57.000Z","size":1473,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-08T07:18:48.194Z","etag":null,"topics":["a2a","agent-orchestration","agent2agent","golang","handoff","mcp","model-context-protocol","multi-agent","openclaw","workflow-orchestration"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/walker1211.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-07T16:39:21.000Z","updated_at":"2026-06-08T06:01:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/walker1211/clawside","commit_stats":null,"previous_names":["walker1211/clawside"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/walker1211/clawside","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walker1211%2Fclawside","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walker1211%2Fclawside/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walker1211%2Fclawside/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walker1211%2Fclawside/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/walker1211","download_url":"https://codeload.github.com/walker1211/clawside/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walker1211%2Fclawside/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34487069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a2a","agent-orchestration","agent2agent","golang","handoff","mcp","model-context-protocol","multi-agent","openclaw","workflow-orchestration"],"created_at":"2026-06-18T10:32:16.403Z","updated_at":"2026-06-18T10:32:17.546Z","avatar_url":"https://github.com/walker1211.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[中文](./README.zh-CN.md)\n\n# clawside\n\n`clawside` is a local MCP sidecar and truth layer for OpenClaw.\n\nIt is not the OpenClaw runtime, and it is not only a Telegram sender. OpenClaw owns sessions, messages, and model execution. `clawside` owns deterministic coordination state outside the runtime: workflows, handoffs, watches, repairs, ownership, evidence, and sender-backed delivery bridges.\n\n## What it provides\n\n- **Local Telegram sender** for authenticated, idempotent, loopback-only delivery.\n- **Truth-plane orchestration** for handoffs, workflows, events, watches, ownership, repairs, and divergence signals.\n- **MCP server** for OpenClaw or another runtime to register agents, query work, progress handoffs, and read evidence.\n- **A2A compatibility endpoint** for Agent Card discovery, JSON-RPC coordination queries, controlled inbound tasks, and read-only task events.\n- **A2A delivery bridge** for explicit outward delivery when the normal announce / nested callback path is unreliable.\n- **Verification scripts** for local CI, MCP smoke, A2A compatibility, private readiness, and public-readiness checks.\n\n## Demo\n\nThis private Telegram/OpenClaw dogfood run used a Werewolf-style game to stress A2A routing and handoff ownership. OpenClaw and Telegram carry the chat; `clawside` records durable coordination truth and exposes it through MCP/A2A surfaces.\n\n| Multi-agent chat | Orchestrator constraints |\n| --- | --- |\n| \u003cimg src=\"./assets/readme/clawside-a2a-game-01.png\" alt=\"Redacted Telegram screenshot showing multiple agents in an A2A coordination game\" width=\"420\"\u003e | \u003cimg src=\"./assets/readme/clawside-a2a-game-02.png\" alt=\"Redacted Telegram screenshot showing orchestrator constraints for A2A dogfood\" width=\"420\"\u003e |\n\n## Mental model\n\n| Runtime owns | `clawside` owns |\n| --- | --- |\n| Model workers, sessions, sandboxes, scheduling, and task execution | Durable workflow/handoff truth, ownership, watches, repairs, evidence, and delivery records |\n| Telegram conversation flow and agent messages | Sender queue, delivery status, idempotency, and bounded observability |\n| Decisions about what work to run | Deterministic projections of executable work, blocked work, reviewer gates, and stale owners |\n\n`clawside` does not launch OpenClaw, Claude, Kimi, model workers, runtime sessions, or sandboxes.\n\n## Quick start\n\n1. Generate local sender config from OpenClaw config:\n\n```bash\ncp .example.env .env\n# edit .env and set SENDER_AUTH_KEY to a local random key\n./scripts/config_builder.sh\n```\n\n2. Build and start the loopback sender:\n\n```bash\n./build.sh\n./start.sh\n```\n\nThe sender listens on `127.0.0.1:8787` by default. Check it with:\n\n```bash\ncurl http://127.0.0.1:8787/healthz\ncurl http://127.0.0.1:8787/readyz\n```\n\n3. Register the MCP server in OpenClaw or another runtime:\n\n```text\ncommand: \u003crepo-root\u003e/scripts/start_mcp.sh\nargs: --db \u003crepo-root\u003e/sender.db\nenv: SENDER_AUTH_KEY=\u003clocal-sender-key\u003e\n```\n\n4. Run the default local MCP smoke:\n\n```bash\nSENDER_AUTH_KEY=\u003clocal-sender-key\u003e ./scripts/verify_openclaw_mcp.sh\n```\n\nUseful help commands:\n\n```bash\ngo run ./cmd/clawside-a2a --help\ngo run ./cmd/clawside-swarmd help\n./scripts/tag-release.sh --help\n```\n\nFor the full operator runbook, see [Clawside operator guide](./assets/readme/operator-guide.md).\n\n## Which verifier should I run?\n\n| Situation | Command |\n| --- | --- |\n| Day-to-day local development | `./scripts/ci-local.sh clean` |\n| A2A compatibility endpoint | `./scripts/verify_clawside_a2a.sh` |\n| MCP tool surface and OpenClaw sidecar smoke | `SENDER_AUTH_KEY=\u003clocal-sender-key\u003e ./scripts/verify_openclaw_mcp.sh` |\n| Private coordination rehearsal | `./scripts/verify_openclaw_mcp.sh --profile private-coordination --json` |\n| Private validation aggregate before release/public work | `./scripts/verify_private_readiness.sh` |\n| Real OpenClaw external-runtime evidence closure | `./scripts/close_private_openclaw_external_runtime_evidence.sh --export-dir \u003cexport-dir\u003e` |\n| Final private/local closure dry run | `./scripts/final_closure_checklist.sh --external-runtime-evidence ./external-runtime-evidence.json --evidence-bundle ./release-evidence/\u003cbundle-dir\u003e --tag v0.0.0-dry-run --repo \u003cowner\u003e/\u003crepo\u003e` |\n| GitHub public-readiness review | `./scripts/github-readiness.sh \u003cowner\u003e/\u003crepo\u003e` |\n\nDo not claim public-readiness or release-readiness from a partial run. Use the matching verifier for the claim. Detailed stage-by-stage validation notes live in the [operator guide](./assets/readme/operator-guide.md#openclaw-mcp-smoke-verifier).\n\n## MCP coordination surface\n\nStart the stdio MCP server with the wrapper script:\n\n```bash\n./scripts/start_mcp.sh --db ./sender.db\n```\n\nThe current MCP surface groups tools by role:\n\n| Area | Tools |\n| --- | --- |\n| Handoff/workflow truth | `handoff_create`, `handoff_get`, `handoff_dispatch`, `handoff_progress`, `workflow_status`, `workflow_list` |\n| Agent coordination | `agent_register`, `agent_list`, `next_work`, `blocked_work` |\n| Templates | `collaboration_template_list`, `collaboration_template_apply` |\n| Watches and ownership | `watch_list`, `watch_run`, `watch_update`, `ownership_get`, `ownership_update` |\n| Repair and divergence | `repair_list`, `repair_invalidate_event`, `repair_backfill_event`, `repair_reopen_handoff`, `repair_candidate_list`, `divergence_record`, `divergence_list` |\n| Sender observability | `sender_health`, `sender_ready`, `sender_stats`, `sender_job_list`, `sender_job_get` |\n| Delivery | `a2a_deliver` |\n\nA minimal external runtime loop looks like this:\n\n```text\nagent_register actor=agent:planner project_refs=project://example/upstream capabilities=planning\nhandoff_create workflow_kind=coordination task_kind=planning intent=\"Plan the work\"\nnext_work agent_id=agent:planner project_ref=project://example/upstream\nhandoff_progress action=receive handoff_id=\u003chandoff-id\u003e\nhandoff_progress action=claim handoff_id=\u003chandoff-id\u003e\nhandoff_progress action=start handoff_id=\u003chandoff-id\u003e\nhandoff_progress action=complete handoff_id=\u003chandoff-id\u003e\nworkflow_status workflow_id=\u003cworkflow-id\u003e\ncoordination_evidence_summary workflow_id=\u003cworkflow-id\u003e include_agents=true\n```\n\nUse protocol actions such as `receive`, `claim`, `start`, `submit`, `review`, `approve`, and `complete`; do not use projected state names such as `started` or `completed` as actions.\n\n## A2A compatibility endpoint\n\n`cmd/clawside-a2a` exposes an experimental A2A-compatible local endpoint backed by the same SQLite truth store as the MCP server.\n\nStart it with a separate A2A auth key:\n\n```bash\nCLAWSIDE_A2A_AUTH_KEY=\u003clocal-a2a-key\u003e \\\n  go run ./cmd/clawside-a2a --db ./sender.db --addr 127.0.0.1:8789\n```\n\nVerify it as an external client:\n\n```bash\n./scripts/verify_clawside_a2a.sh\n```\n\nThe endpoint supports Agent Card discovery, a small JSON-RPC allowlist, `tasks/get`, controlled inbound task creation, cancellation, and read-only SSE task events. It does not call `message/send`, `message/stream`, sender delivery, Telegram delivery, runtime launch APIs, worker APIs, or local commands.\n\n## Private Telegram operator\n\n`cmd/clawside-telegram-operator` is a private dogfood operator for fixed truth-plane slash commands:\n\n```text\n/health\n/status \u003cworkflow_id\u003e\n/next \u003cagent_id\u003e\n/blocked \u003cagent_id\u003e\n/approve \u003chandoff_id\u003e\n```\n\nStart it only for a bot that OpenClaw is not already polling:\n\n```bash\n./scripts/start_telegram_operator.sh --bot guardian\n./scripts/stop_telegram_operator.sh\n```\n\nIf OpenClaw already owns Telegram inbound, keep that path in OpenClaw and report lifecycle events back through `openclaw_event_ingest` or `cmd/openclaw-event-bridge`.\n\n## Components\n\n| Area | Paths |\n| --- | --- |\n| Sender service | `main.go`, `http_handler.go`, `worker.go`, `send_service.go` |\n| Config builder | `cmd/config-builder/`, `internal/configbuilder/`, `scripts/config_builder.sh` |\n| Truth-plane CLI and store | `cmd/orchestrator/`, `internal/orchestrator/`, `store.go` |\n| MCP server | `cmd/clawside-mcp/`, `internal/toolserver/`, `scripts/start_mcp.sh` |\n| A2A endpoint | `cmd/clawside-a2a/`, `cmd/clawside-a2a-example/`, `internal/a2aserver/` |\n| A2A delivery bridge | `cmd/a2a-delivery/`, `internal/a2adelivery/`, `.claude/skills/openclaw-a2a-delivery/` |\n| Swarm reference loop | `cmd/clawside-swarmd/`, `cmd/clawside-swarm-runner/` |\n| OpenClaw evidence tools | `cmd/openclaw-*`, `scripts/verify_openclaw_mcp.sh`, `scripts/*evidence*.sh` |\n\n## Safety and release boundaries\n\n- Keep `SENDER_AUTH_KEY`, `CLAWSIDE_A2A_AUTH_KEY`, and Telegram bot tokens separate.\n- Keep real config in `.env` and `configs/config.toml`; both are ignored by git.\n- Do not put secrets, local absolute paths, private prompts, raw trajectory payloads, stdout/stderr, chat IDs, or bot tokens in public docs or release artifacts.\n- `clawside` must not accept runtime launch fields such as arbitrary `command`, `args`, `cwd`, private prompt, token, session id, worker id, or sandbox fields through truth-plane templates or A2A surfaces.\n- Release/tag/public work stays explicit: keep `./scripts/tag-release.sh --verify-only` unless the release/tag action is authorized.\n- Before making the repository public, run `./scripts/github-readiness.sh \u003cowner\u003e/\u003crepo\u003e` and confirm secret scanning, push protection, private vulnerability reporting, branch protection or rulesets, and code scanning.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalker1211%2Fclawside","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwalker1211%2Fclawside","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalker1211%2Fclawside/lists"}