Skip to main content

Extensions

Extensions add capabilities to an ECP (Execution Control Protocol) environment: model providers, formats, memory, secrets, and more.

Catalog and bind

Extension packages should call catalogExtension(def) at module load so string ids resolve:
Prefer npm package name === extension id (for example @executioncontrolprotocol/format-toon). ensureBoundExtensionsRegistered() runs automatically before encode, decode, describe, and run when using the core environment path — you typically do not need a separate register step for cataloged packages.

Definitions vs invocations

Custom extension

Capability bodies are inline TypeScript handlers via .withHandler(...):
Bind with extension("@vendor/my-ext").with({}), then invoke with step("@vendor/my-ext.do-thing", "Label").with({ value: "hi" }).

Package boundaries

Extensions depend on @executioncontrolprotocol/types and @executioncontrolprotocol/core (plus focused third-party libs). They must not import:
  • @executioncontrolprotocol/node
  • @executioncontrolprotocol/browser
  • @executioncontrolprotocol/cli
  • @executioncontrolprotocol/mcp
Hosts wrap core; extensions stay portable.

Browser vs Node package graphs

Capability execution (local | host | mixed) is not a bundler export name. Those names describe where a step runs after dispatch. If the Node implementation imports native modules or Node-only SDKs (sharp, @azure/storage-blob, node:fs), ship a standard exports condition so web bundlers never see that graph:
browser and node are bundler/Node conditions (Vite, webpack, Rollup, Node). Apps import the package root only:
Do not import index.browser by path. Vite selects exports["."].browser automatically.

Media refs (images and binaries)

Workflows pass portable ImageRef values (buffer | file | url | artifact), not raw bytes. Extensions resolve and write through core:
file.path may be a Node path or an ecp://browser/<id> locator in ctx.blobs. Do not reimplement fs/fetch/artifact maps inside the extension.

First-party and vendor

Protocol/platform extensions live in the ECP monorepo (formats, providers such as Ollama and Chrome AI, memory, secrets, …). Vendor integrations (fal, Slack, image-sharp, Adobe, …) ship from the sibling extensions repository. In-repo testing stub:

Next steps