{"id":45952808,"url":"https://github.com/zeroasterisk/a2a-relay","last_synced_at":"2026-02-28T13:02:00.697Z","repository":{"id":338691033,"uuid":"1158205306","full_name":"zeroasterisk/a2a-relay","owner":"zeroasterisk","description":"A2A Protocol relay for agents without public URLs","archived":false,"fork":false,"pushed_at":"2026-02-15T21:54:53.000Z","size":19,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-16T04:39:48.569Z","etag":null,"topics":["a2a","agent","ai","relay","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zeroasterisk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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-02-15T00:48:10.000Z","updated_at":"2026-02-15T21:54:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zeroasterisk/a2a-relay","commit_stats":null,"previous_names":["zeroasterisk/a2a-relay"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zeroasterisk/a2a-relay","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroasterisk%2Fa2a-relay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroasterisk%2Fa2a-relay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroasterisk%2Fa2a-relay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroasterisk%2Fa2a-relay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zeroasterisk","download_url":"https://codeload.github.com/zeroasterisk/a2a-relay/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroasterisk%2Fa2a-relay/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29934956,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:00:17.143Z","status":"ssl_error","status_checked_at":"2026-02-28T12:59:13.669Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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","ai","relay","websocket"],"created_at":"2026-02-28T13:02:00.123Z","updated_at":"2026-02-28T13:02:00.688Z","avatar_url":"https://github.com/zeroasterisk.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A2A Relay\n[![CI](https://github.com/zeroasterisk/a2a-relay/actions/workflows/ci.yaml/badge.svg)](https://github.com/zeroasterisk/a2a-relay/actions/workflows/ci.yaml) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n\n\n\u003e ⚠️ **Beta** — Tested and working, but API may change. Production use at your own risk.\n\nA relay service for [A2A Protocol](https://a2a-protocol.org) that enables agents without public URLs to participate in agent-to-agent communication.\n\n## Why?\n\nA2A assumes HTTP endpoints, but many agents can't expose public URLs:\n- Behind NAT/firewalls\n- Laptops that sleep\n- Privacy-conscious deployments\n\n**Solution:** Agents connect *outbound* to the relay. Clients send requests to the relay, which forwards to connected agents.\n\n```\nClient ──HTTP──► Relay ◄──WebSocket── Agent (no public URL)\n```\n\n## Quick Start\n\n### Deploy the Relay\n\n```bash\ncd relay-go\ngo build -o a2a-relay .\n./a2a-relay --port 8080 --secret \"your-32-char-jwt-secret\"\n```\n\nOr use Docker:\n```bash\ndocker run -p 8080:8080 -e JWT_SECRET=\"your-secret\" ghcr.io/zeroasterisk/a2a-relay\n```\n\n### Connect an Agent\n\n```javascript\nconst ws = new WebSocket('wss://your-relay.com/agent');\nws.send(JSON.stringify({\n  type: 'auth',\n  token: createJWT({ tenant: 'default', agent_id: 'my-agent', role: 'agent' }),\n  tenant: 'default',\n  agent_id: 'my-agent',\n  agent_card: { name: 'My Agent', ... }\n}));\n```\n\n### Send a Message (Client)\n\n```bash\ncurl -X POST https://your-relay.com/t/default/a2a/my-agent/message/send \\\n  -H \"Authorization: Bearer $CLIENT_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"message\": {\"role\": \"user\", \"parts\": [{\"text\": \"Hello!\"}]}}'\n```\n\n## OpenClaw Integration\n\nThe easiest way to use A2A Relay is with [OpenClaw](https://openclaw.ai):\n\n```json\n{\n  \"channels\": {\n    \"a2a\": {\n      \"enabled\": true,\n      \"accounts\": {\n        \"default\": {\n          \"relayUrl\": \"wss://your-relay.com/agent\",\n          \"relaySecret\": \"your-jwt-secret\",\n          \"agentId\": \"my-agent\"\n        }\n      }\n    }\n  }\n}\n```\n\nSee [openclaw-a2a plugin](https://github.com/zeroasterisk/openclaw-a2a) for details.\n\n## Architecture\n\n```\nRelay\n├── Tenant: acme-corp\n│   ├── Agent: assistant (WebSocket)\n│   └── Agent: researcher (WebSocket)\n└── Tenant: personal\n    └── Agent: my-bot (WebSocket)\n```\n\n### Auth Model\n\n| Token | Who | Allows |\n|-------|-----|--------|\n| Agent | Agent process | Register \u0026 receive requests |\n| Client | End users | Send requests to agents |\n\nTokens are JWTs signed with the relay's secret.\n\n## API\n\n### Agent WebSocket (`/agent`)\n\n```json\n// Auth\n{ \"type\": \"auth\", \"token\": \"...\", \"tenant\": \"...\", \"agent_id\": \"...\", \"agent_card\": {...} }\n\n// Receive request\n{ \"type\": \"a2a.request\", \"payload\": { \"id\": \"...\", \"params\": {...} } }\n\n// Send response\n{ \"type\": \"a2a.response\", \"payload\": { \"id\": \"...\", \"result\": {...} } }\n```\n\n### Client HTTP (`/t/{tenant}/a2a/{agent}`)\n\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/.well-known/agent.json` | Agent card |\n| POST | `/message/send` | Send message |\n| GET | `/tasks/{id}` | Get task |\n| GET | `/tasks` | List tasks |\n\n## Implementations\n\n| Directory | Language | Status |\n|-----------|----------|--------|\n| `/relay-go` | Go | ✅ Production-ready |\n| `/relay-elixir` | Elixir | 🚧 WIP |\n| `/relay-restate` | TypeScript | 🚧 WIP |\n\n## Config\n\n```bash\n# Environment variables\nJWT_SECRET=your-32-char-minimum-secret\nPORT=8080\nBIND=0.0.0.0\n```\n\n## Docs\n\n- [**Deployment Guide**](docs/deploy.md) — Cloud Run, Fly.io, Cloudflare Workers, Vercel, self-hosted\n- [**Roadmap**](docs/roadmap.md) — TypeScript relay, message queuing, federation\n- [**Design**](DESIGN.md) — Architecture, auth model, streaming, implementation comparison\n- [**Tech Debt**](BACKLOG.md) — Known issues and improvements\n\n## Links\n\n- [A2A Protocol](https://a2a-protocol.org)\n- [OpenClaw A2A Plugin](https://github.com/zeroasterisk/openclaw-a2a)\n- [A2A OPT Extension](https://github.com/zeroasterisk/a2a-opt)\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeroasterisk%2Fa2a-relay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzeroasterisk%2Fa2a-relay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeroasterisk%2Fa2a-relay/lists"}