Skip to main content

neutron-tools

The shared protocol and browser-utility package used by the Kernel, app frontends, the compiler, and repository tooling.

What it provides

The message-bus bridge. The exec/expose postMessage transport, typed guards for the JSON envelopes, and the client used to route calls between endpoints.

neutron-tools/app — the source-bound app entrypoint. This is what app frontends should import. It exposes message-bus tools, approved canister-call dialogs, self calls, tray/state actions, vetKeys, Agent Mode, and the connection helpers re-exported from connections.ts. App identity comes from the live private port rather than an app-id field supplied by the caller; raw management actors and cycle primitives are not exposed.

import {
createMsgBusClient,
createCanisterClient,
loadNeutronCanisterId,
loadTileContext,
exposeTool,
callTool,
copyToClipboard,
onAppStateChange,
publishAppStateChange,
} from 'neutron-tools/app';

The manifest schema and validator. The closed JSON Schema (draft-07) for neutron.json, plus the semantic validation that raw JSON Schema cannot express — unique tile ids, safe relative asset paths, tray/background coupling.

Hashing and URL helpers, including the derivation of an app's physical Candid method names and its per-app subdomain.

The neutron-tools/repository protocol. The fixed neutron-repo-v1 link and manifest model used for certified third-party setup links. See Repositories.

Entrypoint map

EntrypointRole
neutron-toolsProtocol types, canonical ordering, app/physical names, versions, and capability catalog
neutron-tools/appApp-side browser SDK and connection helpers
neutron-tools/kernelKernel-side action exposure and port execution
neutron-tools/app_attachmentsBounded endpoint-to-endpoint binary tool attachments
neutron-tools/capabilitiesCapability catalog, plans, wire format, and normalization
neutron-tools/repositoryCertified repository protocol and setup-link parsing
neutron-tools/certified_assetBounded certified-asset reader and decoders
neutron-tools/browser_secret_cacheSmall encrypted browser-secret cache abstraction
neutron-tools/wasm_metadataWasm custom-section helpers

Shared workspace code also imports supported neutron-tools/src/*.js subpaths for manifest schema/validation, hashing, runtime URLs, and runtime config.

Sub-entrypoints worth knowing

neutron-tools/app_attachments

Bounded binary transfer between live endpoints. A tool declares its exact input/output attachment name, media type, required flag, and byte cap in its descriptor; the caller transfers an ArrayBuffer over the existing source-bound private port.

Ordinary tool JSON and progress events carry no attachment bytes. The kernel authenticates both endpoints, validates the declaration before routing, and applies global per-endpoint byte and count limits. Apps must still use app-specific media types and validate the payload after receipt.

Self calls

querySelf() and updateSelf() invoke methods the app listed in capabilities.preapproved_self_calls with no consent dialog.

Their value type is ordinary structural data plus Uint8Array (ArrayBuffer is accepted as an input convenience) — but only at positions the trusted live Candid type proves to be blob / vec nat8. Binary leaves may be nested or repeated. The SDK snapshots each buffer into an immutable copy and transfers the copies over the private port, so caller-owned buffers stay usable.

Connections

requestConnection, listConnections, acquireConnectionCredential, and disconnectConnection are exported from neutron-tools/app. Requests name one manifest-declared provider; the Kernel binds the caller endpoint and keeps the provider session outside the app frame. Returned credentials are sensitive, short-lived application data and must not be logged or persisted.

There is no attachment-direction plan, no app-supplied field path, and no transport envelope. The manifest declaration controls consent for the method; the live interface owns the type.

vetKeys helpers

requestVetKeys, listVetKeys, getVetKeyPublicKey, deriveVetKey, and approveVetKeyDerivation. Note the shape of the API: there is no appId, key name, derivation-input, cycle, or management-canister parameter. deriveVetKey reports a single-use challenge through onChallenge; that callback must immediately call approveVetKeyDerivation from the same endpoint. This is an automatic protocol confirmation, not a second user decision. The encrypted result resolves only to the endpoint that started the request.

Tool descriptors

Endpoints register tools locally. Descriptors carry a name, optional title and description, a required draft-07 inputSchema, an optional outputSchema, and optional annotations.

exposeTool(
'notes_search',
{
title: 'Search Notes',
description: 'Search notes owned by this app.',
inputSchema: {
type: 'object',
required: ['query'],
properties: {query: {type: 'string'}},
additionalProperties: false,
},
outputSchema: {
type: 'object',
required: ['matches'],
properties: {matches: {type: 'array'}},
additionalProperties: false,
},
},
async ({query}, context) => ({matches: []}),
);

Names, metadata lengths, schema sizes, and invisible/control characters are validated. Input and output are validated twice — once at the endpoint and once at the kernel broker. Discovery always asks the live endpoint, so there is no stale kernel-side tool cache.

Reserved annotations include the closed values "neutron:audit": "metadata_only", "neutron:control": "cancel", and "neutron:visibility": "same_app"; the attachment entrypoint adds its bounded "neutron:attachments" contract. Unsupported values for the closed reserved annotations are rejected.

Design rules to notice

The SDK's shape is itself a security decision. Three patterns recur:

  1. No authoritative identity in payloads. You never tell the kernel who you are; it already knows from the port.
  2. Privileged primitives stay brokered. The app SDK exposes scoped operations rather than a management actor, cycle attachment primitive, or certificate-tree handle.
  3. Private actions are not tools. Clipboard writes, tray badges, connection credentials, Ethereum provider sessions, and vetKeys actions travel as private SDK actions on the same port. They are absent from tool discovery, cross-app routing, agent tool selection, and the model-visible audit.