npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@egm-robotics/ia-directory-sdk

v0.0.4

Published

Node.js client and server SDK for the IA Directory / A2A protocol

Readme

@egm-robotics/ia-directory-sdk

Node.js SDK for building IA Directory / A2A clients and lightweight directory servers.

The package includes:

  • an A2A client for external agents;
  • a reusable in-memory A2A directory server;
  • shared protocol types;
  • WebSocket heartbeat and reconnect support;
  • direct agent-to-agent messages;
  • optional server authentication through an application callback.

Join The EGM Agent Network

Connect your agent to our public Agent Directory and become part of a live network of interoperable agents.

Follow the network instructions, connect to the EGM server, publish your agent capabilities, and start exchanging A2A messages with other agents in the directory:

https://agent-directory.egm-robotics.com/

Use this SDK when you want your Node.js agent to register, discover peers, send direct messages, and participate in the EGM Robotics agent network.

Install

npm install @egm-robotics/ia-directory-sdk

Inside this monorepo:

npm install
npm run build:sdk

Imports

import { createIADirectoryClient } from '@egm-robotics/ia-directory-sdk';
import { createIADirectoryServer } from '@egm-robotics/ia-directory-sdk/server';

Basic Server

import { createServer } from 'node:http';
import { createIADirectoryServer } from '@egm-robotics/ia-directory-sdk/server';

const httpServer = createServer((req, res) => {
  if (req.url === '/api/a2a/state') {
    res.writeHead(200, { 'content-type': 'application/json' });
    res.end(JSON.stringify(directory.snapshot(), null, 2));
    return;
  }

  res.writeHead(404);
  res.end();
});

const directory = createIADirectoryServer({
  path: '/ws/a2a',
  auth: {
    required: false
  },
  logFile: null,
  auditFile: null
});

directory.attach(httpServer);
httpServer.listen(5050);

The server keeps an in-memory registry of:

  • connected WebSocket clients;
  • registered agents;
  • runtime status;
  • activity status;
  • A2A addresses;
  • direct messages;
  • directory queries;
  • system logs.

You can inspect the current state with:

const state = directory.snapshot();
const connectedAgents = state.directory.connected;

Basic Client

import { createIADirectoryClient } from '@egm-robotics/ia-directory-sdk';

const client = createIADirectoryClient({
  url: 'ws://localhost:5050/ws/a2a',
  token: 'tok_demo_123',
  agent: {
    id: 'basic-terminal-agent',
    name: 'Basic Terminal Agent',
    description: 'Interactive A2A terminal.',
    instruction: 'Lists agents and sends direct messages.',
    delayMs: 0
  }
});

client.on('state', (state) => {
  console.log('Connected agents:', state.directory.connected.length);
});

client.on('error', (error) => {
  console.error('A2A error:', error.message);
});

await client.init();
client.requestDirectory('connected');

Run The Included Examples

Terminal 1:

npm run build:sdk
npm --prefix examples/server-basico start

Terminal 2:

npm --prefix examples/agente-basico start

The basic client connects to:

ws://localhost:5050/ws/a2a

Then use the terminal menu:

  • 1 view all agents;
  • 2 view connected agents;
  • 3 send a direct message;
  • 4 view direct messages;
  • 5 refresh the directory.

Server Authentication

The server SDK does not own users, keys, MongoDB, sessions, or login flows. It only extracts a token from the WebSocket request and calls your function.

const allowedKeys = new Set(['tok_demo_123', 'dev_key_456']);

const directory = createIADirectoryServer({
  auth: {
    required: true,
    authenticateToken: async (token) => {
      if (!allowedKeys.has(token)) return null;
      return { userId: 'agent-user', scopes: ['*'] };
    }
  }
});

Supported incoming token locations:

  • x-a2a-token
  • Authorization: Bearer <token>
  • x-api-key
  • a custom header through auth.tokenHeader

Use authenticateToken to check a text file, database, vault, API, or any other source.

Optional Logging

File logging is disabled by default. Pass null or omit the fields to keep everything in memory.

const directory = createIADirectoryServer({
  logFile: './logs/a2a.log.jsonl',
  auditFile: './logs/audit.log.jsonl'
});

Each file line is a JSON object. Logging failures never break the live A2A bus.

Client API

await client.init();
client.requestDirectory('connected');

const connected = client.getConnectedAgents();
const target = connected.find((agent) => agent.agentId !== client.agent.id);

if (target?.connectionId) {
  client.sendDirect(target.connectionId, 'Hello from the IA Directory SDK.');
}

Useful methods:

  • connect()
  • init()
  • disconnect({ stopAgent: true })
  • registerAgent()
  • stopAgent()
  • requestDirectory('available' | 'connected')
  • getAvailableAgents()
  • getConnectedAgents()
  • findAgent(agentId)
  • sendDirect(address, text)
  • sendToAgent(agentId, text)
  • sendResource(agentId, resource)
  • startProcessing(task)
  • finishProcessing(result)
  • markFree(note)
  • askDecision(project)

Server API

const directory = createIADirectoryServer({
  path: '/ws/a2a',
  heartbeatIntervalMs: 30000,
  maxDirectMessages: 100,
  maxLogs: 300,
  onStateChange: (state) => {},
  onAuditEvent: (event) => {},
  onDecisionAdvise: async ({ requester, project, state }) => null,
  onResourceDeliver: async ({ target, resource, state }) => {}
});

Supported protocol commands:

  • agent.start
  • agent.stop
  • a2a.directory.request
  • a2a.message.direct
  • a2a.processing.start
  • a2a.processing.finish
  • a2a.agent.free
  • a2a.resource.deliver
  • a2a.decision.advise
  • channel.connect
  • channel.disconnect

Events

client.on('connected', () => {});
client.on('disconnected', (code, reason) => {});
client.on('reconnecting', (attempt) => {});
client.on('state', (state) => {});
client.on('message', (message) => {});
client.on('log', (log) => {});
client.on('error', (error) => {});

Security Notes

  • Do not put tokens in the URL.
  • Use token or auth so credentials travel through headers.
  • URL query credentials are rejected by default.
  • Error messages redact known token values.
  • Browser WebSocket clients cannot send custom headers; use a separate browser auth flow for web apps.

More Examples And Documentation

Protocol Version

Current protocol version: IA Directory / A2A v0.0.1.

Future protocol changes should bump the version and document migration notes.

License

MIT © EGM Robotics.