{"_id":"@a2a-relay/server","_rev":"2-0d2d226f885e0be1d2bc21dd60c113ff","name":"@a2a-relay/server","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@a2a-relay/server","version":"0.1.0","keywords":["a2a","agent","agent-relay","ai","agent-to-agent"],"author":{"name":"Agent Relay Contributors"},"license":"MIT","_id":"@a2a-relay/server@0.1.0","maintainers":[{"name":"bruce_wayne_new_era","email":"bw61180@gmail.com"}],"homepage":"https://github.com/agent-relay/agent-relay","bugs":{"url":"https://github.com/agent-relay/agent-relay/issues"},"dist":{"shasum":"49398b501be727e7d9b9d1e68c96b498e819f787","tarball":"https://registry.npmjs.org/@a2a-relay/server/-/server-0.1.0.tgz","fileCount":14,"integrity":"sha512-N8mMKOFh0/E6fons8xESyL9Hw8XO+YhheaWJ54AiGDk+4TzJgZWvnKVFxiSEXzAk3Qt37EV/yNydSbQP4R+4UA==","signatures":[{"sig":"MEUCIDC/runzSKnozd98yAUwhfXvPGPJfmADAWtixde6oLCEAiEA7U8PkBHmyfUfnC+q4z3z5ArDSLYnz9mr34UOD7kx0jY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38471},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"244a47204f2c8011b65ae2c60af383292727f271","scripts":{"dev":"tsc --watch","test":"echo 'no tests yet'","build":"tsc"},"_npmUser":{"name":"bruce_wayne_new_era","email":"bw61180@gmail.com"},"repository":{"url":"git+https://github.com/agent-relay/agent-relay.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.4","description":"Build A2A-compliant agents in minutes","directories":{},"_nodeVersion":"22.22.0","dependencies":{"uuid":"^11.1.0","express":"^4.21.0","@a2a-js/sdk":"^0.3.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.7.0","@types/uuid":"^10.0.0","@types/express":"^5.0.0"},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/server_0.1.0_1770049323998_0.5152445939886228","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@a2a-relay/server","version":"0.2.0","description":"Build A2A-compliant agents in minutes","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc","dev":"tsc --watch","test":"echo 'no tests yet'"},"repository":{"type":"git","url":"git+https://github.com/agent-relay/agent-relay.git","directory":"packages/server"},"homepage":"https://github.com/agent-relay/agent-relay","author":{"name":"Agent Relay Contributors"},"license":"MIT","dependencies":{"@a2a-js/sdk":"^0.3.9","express":"^4.21.0","uuid":"^11.1.0"},"devDependencies":{"@types/express":"^5.0.0","@types/uuid":"^10.0.0","typescript":"^5.7.0"},"peerDependencies":{},"engines":{"node":">=18.0.0"},"keywords":["a2a","agent","agent-relay","ai","agent-to-agent"],"_id":"@a2a-relay/server@0.2.0","gitHead":"4e7f78907bfc62289184f90cffc71fdcc1e1e3d6","bugs":{"url":"https://github.com/agent-relay/agent-relay/issues"},"_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-oPtTXWdgnOKlQfe+7fW305QPKseRNipnBmWSNGqSKtowazOOwmYpReExQ4BPwUfocelHfvN8ch8x3uY5HbYpMg==","shasum":"efdef70489988748814cd7e8046e2cdfce761c08","tarball":"https://registry.npmjs.org/@a2a-relay/server/-/server-0.2.0.tgz","fileCount":14,"unpackedSize":49724,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC3XCIbV6ZBbIy1ZQraq+TQhumG1bwkS06F53nVj2hEtwIgK+MLv+yXUxuBgKZG450M8N44DPG/q8m82zzKhcy1Elk="}]},"_npmUser":{"name":"bruce_wayne_new_era","email":"bw61180@gmail.com"},"directories":{},"maintainers":[{"name":"bruce_wayne_new_era","email":"bw61180@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/server_0.2.0_1770052972890_0.7110266546236528"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-02T16:22:03.841Z","modified":"2026-02-02T17:22:53.150Z","0.1.0":"2026-02-02T16:22:04.159Z","0.2.0":"2026-02-02T17:22:53.025Z"},"bugs":{"url":"https://github.com/agent-relay/agent-relay/issues"},"author":{"name":"Agent Relay Contributors"},"license":"MIT","homepage":"https://github.com/agent-relay/agent-relay","keywords":["a2a","agent","agent-relay","ai","agent-to-agent"],"repository":{"type":"git","url":"git+https://github.com/agent-relay/agent-relay.git","directory":"packages/server"},"description":"Build A2A-compliant agents in minutes","maintainers":[{"name":"bruce_wayne_new_era","email":"bw61180@gmail.com"}],"readme":"# @a2a-relay/server\n\nBuild A2A-compliant agents in minutes. Define skills, start the server, done.\n\nPart of [Agent Relay](https://github.com/agent-relay/agent-relay) — the open infrastructure for the agent economy.\n\n## Install\n\n```bash\nnpm install @a2a-relay/server\n```\n\n## Quick Start\n\n```typescript\nimport { AgentRelay } from '@a2a-relay/server';\n\nconst relay = new AgentRelay({\n  name: 'My Agent',\n  description: 'An agent that does useful things',\n  version: '0.1.0',\n});\n\nrelay.skill({\n  id: 'greet',\n  name: 'Greeting',\n  description: 'Say hello',\n  tags: ['hello', 'greeting'],\n  handler: async (ctx) => `Hello! You said: \"${ctx.text}\"`,\n});\n\nrelay.listen(3000);\n```\n\nThat's it. Your agent is live with:\n\n- **Agent Card** at `/.well-known/agent-card.json` (A2A discovery)\n- **JSON-RPC endpoint** at `/a2a/jsonrpc` (A2A standard)\n- **REST endpoint** at `/a2a/rest/message/send` (simpler alternative)\n- **Health check** at `/health`\n\n## Features\n\n- **🔌 A2A Protocol** — fully compliant with the [Agent-to-Agent protocol](https://a2a-protocol.org)\n- **⚡ Skill-based routing** — register multiple skills, messages get routed automatically\n- **🔐 Built-in auth** — bearer token validation out of the box\n- **📋 Auto-generated Agent Card** — skills become discoverable metadata\n- **🛠️ Express under the hood** — add custom middleware, mount on existing apps\n\n## Multiple Skills\n\n```typescript\nconst relay = new AgentRelay({\n  name: 'Car Expert',\n  description: 'Automotive diagnostics and advice',\n  version: '0.1.0',\n});\n\nrelay.skill({\n  id: 'diagnose',\n  name: 'Engine Diagnostics',\n  description: 'Describe symptoms, get likely causes',\n  tags: ['engine', 'diagnostics', 'repair'],\n  handler: async (ctx) => {\n    // Your logic here — call an LLM, query a database, anything\n    return `Based on \"${ctx.text}\", the likely cause is...`;\n  },\n});\n\nrelay.skill({\n  id: 'estimate',\n  name: 'Repair Estimate',\n  description: 'Get a rough cost estimate for repairs',\n  tags: ['cost', 'estimate', 'repair'],\n  handler: async (ctx) => ({\n    text: 'Estimated repair cost: $200-400',\n    data: { minCost: 200, maxCost: 400, currency: 'USD' },\n  }),\n});\n\nrelay.listen(3000);\n```\n\n## Authentication\n\n```typescript\nconst relay = new AgentRelay({\n  name: 'Private Agent',\n  description: 'Only authorized agents can talk to me',\n  version: '0.1.0',\n  auth: {\n    type: 'bearer',\n    tokens: ['secret-token-1', 'secret-token-2'],\n  },\n});\n\n// Or use a custom validator\nconst relay = new AgentRelay({\n  name: 'Private Agent',\n  description: 'Custom auth logic',\n  version: '0.1.0',\n  auth: {\n    type: 'bearer',\n    validator: async (token) => {\n      // Check against your database, JWT, etc.\n      return token === process.env.API_KEY;\n    },\n  },\n});\n```\n\n## Returning Data\n\nSkill handlers can return a string or a structured result:\n\n```typescript\n// Simple text response\nhandler: async (ctx) => `Hello, ${ctx.text}!`\n\n// Structured response with text + data\nhandler: async (ctx) => ({\n  text: 'Here are the results',\n  data: { items: [...], count: 42 },\n})\n\n// File response\nhandler: async (ctx) => ({\n  text: 'Generated your report',\n  file: {\n    name: 'report.pdf',\n    mimeType: 'application/pdf',\n    bytes: base64EncodedContent,\n  },\n})\n```\n\n## Auto-Registration\n\nRegister with an agent registry automatically on startup:\n\n```typescript\nconst relay = new AgentRelay({\n  name: 'My Agent',\n  description: 'Does useful things',\n  version: '0.1.0',\n  url: 'https://my-agent.example.com',  // Your public URL\n  registry: 'https://registry.agent-relay.dev',\n});\n```\n\nThe agent registers when it starts, sends periodic heartbeats (every 5 min by default), and unregisters on graceful shutdown.\n\n```typescript\n// Multiple registries\nregistry: ['https://registry1.com', 'https://registry2.com']\n\n// Custom heartbeat interval (ms), or 0 to disable\nregistryHeartbeat: 600_000  // 10 minutes\n\n// Manual registration\nawait relay.register('https://another-registry.com');\nawait relay.unregister('https://another-registry.com');\n```\n\n## Custom Middleware\n\nAccess the underlying Express app for custom routes or middleware:\n\n```typescript\nconst relay = new AgentRelay({ name: 'My Agent', description: '...', version: '0.1.0' });\n\nconst app = relay.getApp();\napp.use(cors());\napp.get('/custom', (req, res) => res.json({ hello: 'world' }));\n\nrelay.listen(3000);\n```\n\n## API\n\n### `new AgentRelay(config)`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `name` | `string` | *required* | Agent name |\n| `description` | `string` | *required* | What your agent does |\n| `version` | `string` | *required* | Semantic version |\n| `port` | `number` | `3000` | Listen port |\n| `url` | `string` | — | Public URL (for Agent Card) |\n| `provider` | `{ organization, url? }` | — | Who runs this agent |\n| `auth` | `AuthConfig` | — | Authentication config |\n| `streaming` | `boolean` | `false` | Enable streaming |\n| `registry` | `string \\| string[]` | — | Registry URL(s) to auto-register with |\n| `registryHeartbeat` | `number` | `300000` | Re-registration interval (ms), 0 to disable |\n\n### `relay.skill(definition)`\n\n| Option | Type | Required | Description |\n|--------|------|----------|-------------|\n| `id` | `string` | ✅ | Unique skill ID |\n| `name` | `string` | ✅ | Human-readable name |\n| `description` | `string` | ✅ | What this skill does |\n| `tags` | `string[]` | — | Searchable tags |\n| `examples` | `string[]` | — | Example queries |\n| `handler` | `(ctx) => Promise<string \\| SkillResult>` | ✅ | Your logic |\n\n### `relay.listen(port?)`\n\nStart the server. Returns a Promise that resolves when listening.\n\n### `relay.stop()`\n\nStop the server gracefully.\n\n### `relay.getApp()`\n\nGet the Express app instance.\n\n## Related\n\n- [`@a2a-relay/client`](https://www.npmjs.com/package/@a2a-relay/client) — discover and talk to A2A agents\n- [Agent Relay](https://github.com/agent-relay/agent-relay) — the full project\n- [A2A Protocol](https://a2a-protocol.org) — the underlying standard\n\n## License\n\nMIT\n","readmeFilename":"README.md"}