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

@vikhulus/agentid-protocol

v0.2.3

Published

Identity, discovery, and trust for AI agents — TypeScript SDK

Downloads

29

Readme

@vikhulus/agentid-protocol

npm version npm downloads License: MIT Node 18+

Identity, discovery, and trust for AI agents — TypeScript SDK

Give every AI agent a cryptographic identity, let agents discover each other, and verify messages end-to-end without a central authority.

  • Ed25519 key pairs — one per agent, generated locally
  • DIDs (did:agentid:<base58-public-key>) — portable, self-describing identifiers
  • Signed messages with nonce + timestamp — built-in replay protection
  • HTTP registry client — optional; agents work fully offline too
  • Pure JavaScript (@noble/ed25519) — Node 18+ and modern browsers

Install

npm install @vikhulus/agentid-protocol

Quick start

import { createAgent, Agent } from '@vikhulus/agentid-protocol';

// 1. Create an agent (no registry = fully local)
const agent = await createAgent({
  name: 'my-bot',
  capabilities: ['summarization', 'web-search'],
  owner: '[email protected]',
});

console.log(agent.did);
// did:agentid:3mFxR8kzWpTqNvYjLdCeAb...

// 2. Sign a message
const msg = await agent.sign({ task: 'fetch', url: 'https://example.com' });
// msg = { payload: {..., signer_did, timestamp, nonce}, signature, signer_did, timestamp, nonce }

// 3. Verify locally (you have the signer's Agent instance)
const agentCopy = await Agent.fromPrivateKey(agent.exportPrivateKey());
const valid = await agentCopy.verifyLocal(msg);
console.log(valid); // true

Agent-to-agent authentication

import { createAgent, Agent, RegistryClient } from '@vikhulus/agentid-protocol';

const registry = new RegistryClient('https://api.agentid-protocol.com', process.env.AGENTID_API_KEY);

// Agent A: data collector
const agentA = await createAgent({
  name: 'collector',
  capabilities: ['scraping'],
  owner: '[email protected]',
  registry,
});

// Agent B: analyst (separate process, loaded from saved key)
const agentB = await createAgent({
  name: 'analyst',
  capabilities: ['reasoning'],
  owner: '[email protected]',
  registry,
});

// A signs a task assignment
const task = await agentA.sign({ action: 'analyse', dataset: 'q1-sales.csv' });

// B verifies A's identity via the registry (no prior knowledge of A's key)
const trusted = await Agent.verifyFromRegistry(task, registry);
console.log(trusted); // true — A's public key was fetched and verified

// Tamper detection — modify the payload, signature fails
const tampered = { ...task, payload: { ...task.payload, dataset: 'backdoor.csv' } };
console.log(await Agent.verifyFromRegistry(tampered, registry)); // false

API reference

createAgent(opts) / Agent.create(opts)

| Option | Type | Required | Description | |----------------|-----------------------------|----------|------------------------------------------| | name | string | Yes | Human-readable name | | capabilities | string[] | Yes | Tags describing what this agent can do | | owner | string | Yes | Email, team ID, or owner identifier | | metadata | Record<string, unknown> | No | Arbitrary key/value pairs | | registry | RegistryClient | No | If provided, agent is registered remotely|

Returns Promise<Agent>.


Agent

| Member | Description | |-----------------------------------------------|-----------------------------------------------------------| | .did | did:agentid:<base58-public-key> | | .name | Agent name | | .capabilities | Capability tags | | .sign(payload) | Sign a payload — returns SignedMessage | | .verifyLocal(msg) | Verify a message using this agent's own public key | | Agent.fromPrivateKey(key, registry?) | Restore agent from saved private key bytes | | Agent.verifyFromRegistry(msg, registry) | Verify by fetching signer's public key from registry | | .exportPrivateKey() | Export raw 32-byte private key for secure storage |


SignedMessage

interface SignedMessage {
  payload:    Record<string, unknown>; // original data + signer_did, timestamp, nonce
  signature:  string;                  // base64 Ed25519 signature
  signer_did: string;                  // DID of signing agent
  timestamp:  number;                  // ms since epoch
  nonce:      string;                  // UUID for replay protection
}

RegistryClient

const registry = new RegistryClient(baseUrl?, apiKey?);

| Method | Description | |-----------------------------------------|-----------------------------------------------------| | register(doc, proof) | Register an agent document | | resolve(did) | Fetch an agent document by DID | | find({ capability?, owner?, name?, limit? }) | Search for agents | | verify(did, payload, signature) | Server-side signature verification | | ping() | Health check — returns boolean |


Crypto utilities

import { generateKeypair, sign, verify, publicKeyToDid, didToPublicKey } from '@vikhulus/agentid-protocol';

const { privateKey, publicKey } = await generateKeypair();
const did = publicKeyToDid(publicKey);
const sig = await sign(privateKey, { hello: 'world' });
const ok  = await verify(publicKey, { hello: 'world' }, sig);

Key persistence

// Export the private key once after creating the agent
const rawKey = agent.exportPrivateKey(); // Uint8Array (32 bytes)
// Store it securely (env variable, secret manager, encrypted file, etc.)

// Later — restore the agent
const agent = await Agent.fromPrivateKey(rawKey, registry);

The private key never leaves your machine. The registry only stores the public key.


Framework integrations

LangChain.js

Give any LangChain.js agent a verifiable identity and agent-discovery tools using the core SDK:

import { createAgent, Agent, RegistryClient } from '@vikhulus/agentid-protocol';
import { DynamicTool } from '@langchain/core/tools';
import { AgentExecutor } from 'langchain/agents';

const REGISTRY = 'https://api.agentid-protocol.com';
const registry = new RegistryClient(REGISTRY, process.env.AGENTID_API_KEY);

// Create a persistent identity (store rawKey in a secret manager)
const identity = await createAgent({
  name: 'research-agent',
  capabilities: ['web-search', 'summarization'],
  owner: '[email protected]',
  registry,
});
console.log('DID:', identity.did);

// Subsequent starts — reload from saved key
// const identity = await Agent.fromPrivateKey(savedKey, registry);

// Discovery tool — lets the agent find other agents by capability
const findAgentTool = new DynamicTool({
  name: 'find_agent',
  description: 'Find AI agents registered in the network by capability. Input: a capability string.',
  func: async (capability: string) => {
    const agents = await registry.find({ capability });
    return JSON.stringify(agents.map(a => ({ did: a.did, name: a.name, capabilities: a.capabilities })));
  },
});

// Verify tool — lets the agent verify a signed message from another agent
const verifyTool = new DynamicTool({
  name: 'verify_agent_message',
  description: 'Verify a signed message from another agent. Input: JSON string with payload and signature.',
  func: async (input: string) => {
    const msg = JSON.parse(input);
    const valid = await Agent.verifyFromRegistry(msg, registry);
    return JSON.stringify({ valid, signer: msg.signer_did });
  },
});

const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [findAgentTool, verifyTool, /* ...your other tools */],
});

// Sign outputs before sending to other agents
const result = await executor.invoke({ input: 'Research the latest AI papers' });
const signed = await identity.sign({ output: result.output });
// signed.signature — Ed25519 signature any downstream agent can verify

Vercel AI SDK

import { createAgent, Agent, RegistryClient } from '@vikhulus/agentid-protocol';
import { tool } from 'ai';
import { z } from 'zod';

const registry = new RegistryClient('https://api.agentid-protocol.com');

const identity = await createAgent({
  name: 'vercel-agent',
  capabilities: ['reasoning', 'code-generation'],
  owner: '[email protected]',
  registry,
});

// Agent-discovery tool for use with generateText / streamText
const findAgentTool = tool({
  description: 'Find AI agents by capability',
  parameters: z.object({ capability: z.string() }),
  execute: async ({ capability }) => {
    return registry.find({ capability });
  },
});

// After generating a response, sign it
const response = await generateText({ model, prompt, tools: { findAgent: findAgentTool } });
const signed = await identity.sign({ output: response.text });

AutoGen (Python → TypeScript handoff)

The TypeScript SDK is designed to interoperate with AutoGen Python agents. An AutoGen agent signs its output; a TypeScript service verifies it:

import { Agent, RegistryClient } from '@vikhulus/agentid-protocol';

const registry = new RegistryClient('https://api.agentid-protocol.com');

// Receive a signed message from a Python AutoGen agent
const incomingMessage = JSON.parse(req.body);  // { payload, signature, signer_did, ... }

const trusted = await Agent.verifyFromRegistry(incomingMessage, registry);
if (!trusted) {
  throw new Error(`Rejected: unverified message from ${incomingMessage.signer_did}`);
}

console.log('Verified agent:', incomingMessage.signer_did);

License

MIT