Agent / foldkit-agent-webmcp
Sixty seconds: publish a bound runtime
Start with the Agent contract and host guide.
The integration below assumes AssistantAgent is your declared contract and
AgentBuilder is its application-specialized builder. mounted below
is an application host (for example, the value returned by Sync.mount),
not an arbitrary Foldkit runtime handle.
Bind that contract to the running application, then register its currently available capabilities with WebMCP:
import { AgentWebMcp } from 'foldkit-agent-webmcp'
const agentRuntime = AgentBuilder.bind({
definition: AssistantAgent,
host: {
model: mounted.model,
dispatch: message => mounted.dispatch(message),
subscribe: mounted.subscribe,
observe: mounted.observe, // Message-based completion
principal: () => currentPrincipal, // your authenticated application principal
},
})
const modelContext = AgentWebMcp.pageModelContext()
if (modelContext !== undefined) {
const registration = AgentWebMcp.register({
agent: agentRuntime,
modelContext,
})
await registration.refresh()
window.addEventListener('pagehide', () => registration.unregister())
}Also call registration.unregister() when the owning component or runtime
is disposed; a page unload listener alone does not handle in-page teardown.
currentPrincipal above comes from your application, not tool arguments.
That is the whole architecture: the contract remains protocol-neutral, the runtime remains the one authority for availability/authorization/dispatch, and this package translates it to the browser API.
pageModelContext() is document.modelContext, where the spec and Chromium
150 put it, or else navigator.modelContext, the older name that earlier
Chromium and agent extensions providing WebMCP still expose. It is safe during
SSR and returns undefined when neither exists. Calling register() without a model context
throws rather than silently pretending registration succeeded.
Registration starts immediately, but browser registration is asynchronous.
register() returns after reconciliation is scheduled; use
await registration.refresh() when the caller needs to know that the browser
has accepted the current tool set, and onError for background reconcile
failures.