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

@indexnetwork/protocol

v4.2.0

Published

The agent orchestration layer for Index Network. Implements LangGraph-based workflows for intent processing, opportunity discovery, and chat — decoupled from any specific infrastructure via adapter injection.

Readme

@indexnetwork/protocol

The agent orchestration layer for Index Network. Implements LangGraph-based workflows for intent processing, opportunity discovery, and chat — decoupled from any specific infrastructure via adapter injection.

Install

npm install @indexnetwork/protocol

Setup

1. Configure the LLM

The package reads OPENROUTER_API_KEY (required), CHAT_MODEL, and CHAT_REASONING_EFFORT from environment variables. No startup call is needed.

To override the chat model or reasoning effort when using the built-in chat runtime (ChatGraphFactory / ChatAgent), pass modelConfig on ToolContext. ChatAgent reads these fields when the chat graph runs; the tools themselves do not consume modelConfig:

import { createChatTools } from "@indexnetwork/protocol";

const tools = await createChatTools({
  // ... other deps ...
  modelConfig: {
    chatModel: "google/gemini-2.5-flash",       // optional — has a default
    chatReasoningEffort: "low",                  // optional: minimal | low | medium | high | xhigh
  },
});

apiKey and baseURL can also be overridden this way. All other protocol agents (evaluators, generators, etc.) rely on OPENROUTER_API_KEY set in the environment regardless of modelConfig.

2. Implement the adapters

The package defines interfaces — your application provides the concrete implementations.

Required (always needed by createChatTools):

| Interface | Responsibility | |---|---| | ChatGraphCompositeDatabase | Core data access (users, intents, indexes/networks, opportunities) | | UserDatabase / SystemDatabase | Context-bound databases built by createUserDatabase / createSystemDatabase | | Embedder | Vector embeddings for semantic search | | Scraper | Web content extraction | | Cache / HydeCache | Result caching (HyDE may share the general cache) | | IntegrationAdapter | OAuth and external tool actions | | IntentGraphQueue | Background intent processing queue | | ContactServiceAdapter | Contact management | | ChatSessionReader | Load conversation history | | ProfileEnricher | Enrich profiles from external sources | | NegotiationGraphDatabase | Negotiation state persistence |

Optional (enable specific capabilities; omit to run without that feature):

| Interface | Responsibility | |---|---| | AgentDatabase | Agent registry CRUD (agents, transports, permissions) | | AgentDispatcher | Resolves and invokes personal agents during negotiation turns — required to register the negotiation tools | | McpAuthResolver | Resolves { userId, agentId } from an incoming MCP HTTP request (MCP server only) | | DeliveryLedger | Commits OpenClaw opportunity-delivery rows | | DiscoveryRunStore / DiscoveryRunQueue | Persist and execute async MCP discovery runs | | ProfileRunStore / ProfileRunQueue | Persist and execute async MCP profile builds | | MintConnectLink | Mints short connect links for opportunity accepts | | ChatSummaryReader | Read-through chat-session digest | | ChatMessageWriter | Writes user messages into the most-recent chat session (MCP elicitation) | | QuestionGeneratorReader / QuestionerDatabase | Decision-question generation and persistence | | NegotiationSummaryReader | Negotiation-digest summarization (falls back to deterministic digests) |

All interfaces are exported from the package root — import them with import type { ... } from "@indexnetwork/protocol".

3. Create tools

Pass your adapter implementations to createChatTools to get a set of LangChain-compatible tools bound to a user session:

import { createChatTools } from "@indexnetwork/protocol";

const tools = await createChatTools({
  userId: "user-uuid",

  // ── Required adapters ──
  database,             // ChatGraphCompositeDatabase
  embedder,             // Embedder
  scraper,              // Scraper
  cache,                // Cache
  hydeCache,            // HydeCache
  integration,          // IntegrationAdapter
  intentQueue,          // IntentGraphQueue
  contactService,       // ContactServiceAdapter
  chatSession,          // ChatSessionReader
  enricher,             // ProfileEnricher
  negotiationDatabase,  // NegotiationGraphDatabase
  integrationImporter,  // bulk contact import
  createUserDatabase,   // (db, userId) => UserDatabase
  createSystemDatabase, // (db, userId, indexScope, embedder?) => SystemDatabase

  // ── Optional scoping ──
  networkId: "optional-network-uuid", // scope tools to a specific index/network
  sessionId: "chat-session-id",       // enables draft opportunities with conversation context

  // ── Optional capabilities (enable when the host supports them) ──
  agentDatabase,        // AgentDatabase — agent registry
  agentDispatcher,      // AgentDispatcher — routes negotiation turns to personal agents
  deliveryLedger,       // DeliveryLedger — OpenClaw delivery commits
  discoveryRuns,        // DiscoveryRunStore + discoveryRunQueue — async MCP discovery
  profileRuns,          // ProfileRunStore + profileRunQueue — async MCP profile builds
  mintConnectLink,      // short connect links for opportunity accepts
  modelConfig,          // override chat model / reasoning effort (see above)
});

// tools is an array of LangChain Tool objects ready to bind to an agent

createChatTools accepts a single ToolContext object. The required adapters above are always needed; the optional capabilities default to a degraded-but- functional mode when omitted (e.g. without agentDispatcher the negotiation tools are not registered, and without discoveryRuns MCP discovery runs synchronously).

Graphs

For direct graph invocation (bypassing the tool layer), a *GraphFactory class is exported for each workflow:

import {
  ChatGraphFactory,
  IntentGraphFactory,
  OpportunityGraphFactory,
  ProfileGraphFactory,
  PremiseGraphFactory,
  NegotiationGraphFactory,
  HydeGraphFactory,
  NetworkGraphFactory,
  NetworkMembershipGraphFactory,
  IntentNetworkGraphFactory,
  HomeGraphFactory,
  MaintenanceGraphFactory,
} from "@indexnetwork/protocol";

Each factory takes its typed dependencies in the constructor and exposes a .createGraph() method that returns a compiled LangGraph ready for .invoke().

| Factory | Workflow | |---|---| | ChatGraphFactory | ReAct chat loop — LLM calls tools, responds to the user | | IntentGraphFactory | Clarify, infer, verify felicity, reconcile, and persist intents | | OpportunityGraphFactory | HyDE-based discovery: search, evaluate (valency), rank, persist | | ProfileGraphFactory | Generate/update user profiles with scraping and embedding | | PremiseGraphFactory | Decompose and index a user's premises | | NegotiationGraphFactory | Multi-turn bilateral negotiation flows | | HydeGraphFactory | Generate hypothetical documents and embed them (cache-aware) | | NetworkGraphFactory | Manage index/network CRUD | | NetworkMembershipGraphFactory | Manage index/network member join/leave | | IntentNetworkGraphFactory | Evaluate and assign/unassign intents to indexes | | HomeGraphFactory | Categorize and curate home-feed content | | MaintenanceGraphFactory | Periodic maintenance (feed health, opportunity expiration) |

MCP server

The package exports a factory that registers every chat tool over the Model Context Protocol and attaches a canonical instructions block (MCP_INSTRUCTIONS) that every connecting runtime follows. The factory takes three arguments:

import { createMcpServer, type McpAuthResolver } from "@indexnetwork/protocol";

const authResolver: McpAuthResolver = {
  async resolveIdentity(req) {
    // Look up the API key in `x-api-key` and return { userId, agentId? }.
    // `agentId` should come from Better Auth token metadata so downstream
    // tool handlers can attribute every call to a concrete agent identity.
    return resolveFromApiKey(req);
  },
};

const server = createMcpServer(
  deps,
  authResolver,
  {
    // Per-request factory for scoped user/system databases.
    create: (userId, indexScope) => createScopedDeps(userId, indexScope),
  },
);

On every tool call the server:

  1. Extracts the HTTP request from the MCP ServerContext.
  2. Calls authResolver.resolveIdentity(req) to get { userId, agentId }.
  3. Gates access: MCP callers without a resolved agentId are blocked from every tool except register_agent, read_docs, and scrape_url until they register.
  4. Builds per-request scoped databases via scopedDepsFactory and invokes the tool handler through the shared runtime.

Runtime controls

MCP tools are bounded by ToolInvocationRuntime:

| Class | Default | Class override | |---|---:|---| | fast | 10 s | MCP_TOOL_TIMEOUT_FAST_MS | | bounded_slow | 45 s | MCP_TOOL_TIMEOUT_BOUNDED_SLOW_MS | | async_candidate | 50 s | MCP_TOOL_TIMEOUT_ASYNC_CANDIDATE_MS |

Per-tool timeout overrides use MCP_TOOL_TIMEOUT_<TOOL_NAME>_MS, such as MCP_TOOL_TIMEOUT_DISCOVER_OPPORTUNITIES_MS. Tool outputs are capped by MCP_TOOL_MAX_OUTPUT_BYTES (default 1000000) or MCP_TOOL_MAX_OUTPUT_<TOOL_NAME>_BYTES; inbound MCP request bodies are capped by the backend with MCP_MAX_REQUEST_BYTES (default 1000000). Runtime failures return JSON text envelopes with stable code values: TOOL_TIMEOUT, TOOL_CANCELLED, or TOOL_OUTPUT_TOO_LARGE.

For MCP callers, discover_opportunities is async: it returns a discoveryRunId immediately, and clients poll get_discovery_run or request cancellation with cancel_discovery_run. Non-MCP chat/web paths stay synchronous.

MCP_INSTRUCTIONS

The instructions string is the single canonical behavioral contract for every runtime that connects to Index Network — voice, entity model, discovery-first rule, output rules, and the Negotiation turn mode block that tells a silent subagent how to handle a live negotiation turn when its session key is prefixed index:negotiation:. Plugin skills and bootstrap scripts do not redefine this guidance; they defer to whatever ships in MCP_INSTRUCTIONS.

Negotiation-facing tools

Personal agents participate in bilateral negotiation via a small set of MCP tools:

| Tool | Purpose | |---|---| | get_negotiation | Fetch the full turn history and assessment seed for a negotiation | | list_negotiations | List negotiations awaiting a response from this agent's user | | respond_to_negotiation | Submit a turn (propose / counter / accept / reject / question) |

Publishing

Publishing is handled via CI:

# dev pushes publish an rc prerelease
git push <remote> dev

# main pushes publish the stable release if the package version is new
git push <remote> main

dev publishes prerelease versions derived from package.json using npm's rc tag, for example 3.6.3-rc.123.1. main publishes the base version from package.json to latest only when that version is not already on npm.

Or publish manually from packages/protocol/:

npm publish --access public