Skip to content

Repository files navigation

@iicp/web-node

Browser-native IICP node for the IICP mesh — consume AI from the network and serve a model from a browser tab. ESM, built on the platform's native fetch / SubtleCrypto / WebGPU (and runs in Node ≥18). The browser client refuses keyless providers rather than silently sending plaintext.

IICP supplies intent resolution and provider eligibility/selection. MCP, A2A, HTTP or another negotiated binding may then execute the selected task. See the public protocol positioning and adjacent-protocol comparison.

npm install @iicp/web-node

Consume — call the mesh

import { IicpBrowserClient, nodeCxKey } from "@iicp/web-node";

const client = new IicpBrowserClient(); // defaults to https://iicp.network
const nodes = await client.discover("urn:iicp:intent:llm:chat:v1");
// By default, discover() keeps only browser-usable HTTPS/loopback endpoints.
// Pass { browser_usable_only: false } if you are running in Node and want all routes.

const node = nodes[0];
const reply = await client.chat(
  [{ role: "user", content: "Hello!" }],
  { endpoint: node.endpoint, model: "llama3", cxPublicKey: nodeCxKey(node) },
);

The client prefers short-lived dispatch tickets, falls back only when an older directory does not support them, and can enforce strict region and signed-policy-manifest constraints before a prompt is sent. Declared prohibited or high-risk public-mesh intents are refused locally. Successful routing receipts exclude prompt, response, token, and endpoint content.

When the chosen node advertises an encryption key (nodeCxKey(node)), the payload is sealed end-to-end — the directory, relays, and network see only ciphertext. There is no opt-out. A node that does not advertise cx_public_key/public_key is refused before any network send so browser use cannot silently fall back to plaintext.

Runtime self-description

Browser chat() calls add a small IICP runtime identity context by default. It tells the selected model that it is being accessed through IICP, identifies the active intent and browser package version, and includes a model or capability fact only when it comes from the selected node's advertisement. It does not expose endpoints, full node identities, candidate sets, scores or credentials, and it is not a prompt-injection security boundary.

Set runtime_identity: { mode: "disabled" } to preserve the application messages without the capsule, or use mode: "required" to refuse when a supported instruction channel is unavailable. Non-chat operations and the plaintext envelope helper remain unchanged.

Serve — be a node from the browser

import { BrowserNodeProvider, WEBLLM_MODELS, assessDevice } from "@iicp/web-node";
// Loads a small model in-tab via WebLLM (WebGPU/WASM) and serves it behind a relay.

Browser providers advertise a generated cx_public_key, decrypt incoming iicp_conf payloads locally, report task success/failure/latency in heartbeats, and use a relay path because browser tabs cannot accept raw inbound TCP.

Browser provider mode is experimental. Tab lifetime, relay availability, browser policy and device resources make it unsuitable for unattended service.

Startup is intentionally ticketed: the provider registers, requests a short-lived relay bind ticket scoped to its worker and selected relay, and presents that ticket when it binds. Authentication or validation failures stop serving and clean up the temporary directory registration instead of silently falling back to an unsigned bind. Compatibility fallback is limited to directories that explicitly report that the ticket service is unavailable.

Provider state includes deterministic recovery diagnostics (stable, tunnel_starting, route_mismatch, operator_action_needed, or unavailable) so a host page can explain whether it is directory-listed and relay-bound. Browser lifetime still matters: closing or suspending the tab stops the in-browser provider.

Serving requires WebLLM — add it alongside this package:

npm install @mlc-ai/web-llm   # peer dependency, only needed to serve

Version metadata

Browser package identity and directory compatibility are separate values. Provider registration reports implementation_name=@iicp/web-node, the package implementation_version, and sdk_compatibility_version; the legacy sdk_version field remains the compatibility alias for older directories.

Encryption

IICP-CX (S.16) Tier-1: ephemeral X25519 key agreement → HKDF-SHA256AES-256-GCM authenticated encryption, computed with @noble/curves + @noble/hashes and the platform's SubtleCrypto. The envelope is wire-compatible with the Python, TypeScript, and Rust IICP clients and the provider/adapter that decrypts it.

CORS reality

Public discovery and ticketed dispatch work from approved browser origins because iicp.network sends CORS headers. Routing a task to a selected node is subject to the browser's CORS and mixed-content policy: an https:// page cannot reach an http://localhost model, a node without CORS headers, or an IPv6-firewalled node. In Node there is no CORS restriction and everything works.

License

Apache-2.0. Part of the open IICP protocol.

Documentation

About

Experimental browser-native IICP consumer and provider implementation

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages