mcp
Import
Section titled “Import”import * as api from "@fungi.computer/oyster/mcp";Exports
Section titled “Exports”| Kind | Export | Description |
|---|---|---|
| class | AppMethodRefused | Why an App method call from the MCP catalog was refused. |
| type alias | ComputerControlPort | Host policy stays outside this family: Hub admits funded slots, standalone admits its current owner. Both call their durable fleet through this port. Keep the host contract independent of the Worker-only fleet lifecycle. |
| type alias | OysterMcpCatalogSnapshot | Captured capabilities and grants offered to one admitted MCP caller. |
| type alias | OysterCallerAccess | The App-tool access one caller’s catalog capture used, re-checked at call time
against a fresh read. An Agent’s policy is one blanket level for every
installation (host.appToolPolicy); a key’s is its own grants, resolved per
installation (keyAppAccess) – an installation the key has no grant for is
captured as absent, never merely refused, so it is never listed at all. |
| type alias | ReleaseSurface | What one Release contributes to every MCP catalog: its verified build, its declared operations and its compiled tool schemas. |
| type alias | AppSurfaceCache | Per-host memo of each installed Release’s catalog surface. A Release’s artifacts are immutable and content-addressed, so verifying the build, deriving its operations and compiling its tool schemas happens once per Release ID and artifact digest, not on every catalog capture: an MCP call captures the catalog several times (refresh, session acquire, the pre-call authority check), and redoing this for every installed App on each one exhausted a Durable Object’s CPU and memory. Only Release-derived facts are cached; installation authority, caller access and tool-family listings are still read fresh on every capture. A failed build is not cached. |
| function | computerControlSpecs() | One set of schemas and operations for MCP and direct broker invocation. |
| function | appBindingName() | An installation ID as a guest binding name: spawn-git becomes SPAWN_GIT. |
| function | appSurfaceCache() | Make one AppSurfaceCache for a host whose artifact store and capabilities stay fixed. |
| function | oysterAppSnapshot() | Derive the current principal’s admitted App modules and grants. |
| function | oysterAppMethods() | Capture installed App methods for MCP or agents as one principal-scoped source.
Enabled installations become env.<APP> modules using the Instance call path; a
dotted method such as repos.list is env.<APP>.repos.list(). Visitors see
only public read methods; owners see every discoverable method. A key sees only
the installations its own grants admit, each at the level (read/write) those
grants give it; Mycelium itself refuses a write call up front when the module’s
own grant is read (mycelium/src/access.ts). Call again to capture changes to
Releases, installation authority or the caller’s own grants. |
| function | oysterComputerTools() | Capture the host’s fixed Computer for one caller as a Knapsack source. The host decides whether the caller holds Computer access; the ComputerDO still checks its host-issued grant on every call. Null when the host has no Computer or the caller has no access. Grants name the captured module. |
| function | oysterMcpCatalogLoad() | Load the current catalog for an authenticated owner or key: installed App
methods, plus the host’s Computer when the caller holds Computer access. A key
sees exactly the installations and levels its own grants admit, and the Computer
only with its own computer.use grant; each App retains its own caller checks
regardless. App writes use the host’s approval record; stored approval of an
Agent’s App tools can permit headless App writes. The shared MCP server elicits
consent for explicitly confirmed operations, including every advertised
Workspace Computer call, even reads. Each call still re-admits the key, checks
current App approval and passes the App’s gate. |
AppMethodRefusedclass
Section titled “AppMethodRefused”Why an App method call from the MCP catalog was refused.
Extends
Section titled “Extends”Error
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new AppMethodRefused(code, detail?): AppMethodRefused;detail is the App’s own caller-facing refusal message, when it gave one.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
code |
string |
detail? |
string |
Returns
Section titled “Returns”Overrides
Section titled “Overrides”Error.constructor;Properties
Section titled “Properties”readonly name: "AppMethodRefused" = "AppMethodRefused";Overrides
Section titled “Overrides”Error.name;readonly code: string;ComputerControlPorttype alias
Section titled “ComputerControlPort”type ComputerControlPort = Readonly<{ list: Promise<{ computers: z.ZodArray< z.ZodObject< { computerId: z.ZodString; name: z.ZodString; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; }, z.core.$strict > >; nextOffset: z.ZodNullable<z.ZodNumber>; }>; state: Promise< | { state: z.ZodEnum<{ running: "running"; sleeping: "sleeping"; starting: "starting"; }>; } | { state: z.ZodLiteral<"queued">; position: z.ZodNumber; } >; start: Promise< | { state: z.ZodEnum<{ running: "running"; sleeping: "sleeping"; starting: "starting"; }>; } | { state: z.ZodLiteral<"queued">; position: z.ZodNumber; } >; create: Promise< | { kind: "created"; computer: { computerId: string; name: string; }; } | { kind: "uncertain" | "denied" | "conflict" | "invalid"; } >;}>;Host policy stays outside this family: Hub admits funded slots, standalone admits its current owner. Both call their durable fleet through this port. Keep the host contract independent of the Worker-only fleet lifecycle.
OysterMcpCatalogSnapshottype alias
Section titled “OysterMcpCatalogSnapshot”type OysterMcpCatalogSnapshot = Readonly<{ instructions: string; sources: readonly CapabilitySource[]; grants: Grants;}>;Captured capabilities and grants offered to one admitted MCP caller.
OysterCallerAccesstype alias
Section titled “OysterCallerAccess”type OysterCallerAccess = | Readonly<{ kind: "agent"; policy: AppToolPolicy; }> | Readonly<{ kind: "key"; keyId: string; byInstallation: ReadonlyMap<string, AppToolPolicy>; }> | null;The App-tool access one caller’s catalog capture used, re-checked at call time
against a fresh read. An Agent’s policy is one blanket level for every
installation (host.appToolPolicy); a key’s is its own grants, resolved per
installation (keyAppAccess) – an installation the key has no grant for is
captured as absent, never merely refused, so it is never listed at all.
ReleaseSurfacetype alias
Section titled “ReleaseSurface”type ReleaseSurface = Readonly<{ release: VerifiedRelease; api: NonNullable<VerifiedRelease["api"]>; declaredOperations: DeclaredOperations; toolSchemas: ReturnType<typeof appToolSchemas>;}>;What one Release contributes to every MCP catalog: its verified build, its declared operations and its compiled tool schemas.
AppSurfaceCachetype alias
Section titled “AppSurfaceCache”type AppSurfaceCache = (release) => Promise<ReleaseSurface | null>;Per-host memo of each installed Release’s catalog surface. A Release’s artifacts are immutable and content-addressed, so verifying the build, deriving its operations and compiling its tool schemas happens once per Release ID and artifact digest, not on every catalog capture: an MCP call captures the catalog several times (refresh, session acquire, the pre-call authority check), and redoing this for every installed App on each one exhausted a Durable Object’s CPU and memory. Only Release-derived facts are cached; installation authority, caller access and tool-family listings are still read fresh on every capture. A failed build is not cached.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
release |
Installation["release"] |
Returns
Section titled “Returns”Promise<ReleaseSurface | null>
computerControlSpecs()function
Section titled “computerControlSpecs()”function computerControlSpecs(port): object;One set of schemas and operations for MCP and direct broker invocation.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
port |
ComputerControlPort |
Returns
Section titled “Returns”object
| Name | Type | Default value | Description |
|---|---|---|---|
list |
object |
- | - |
list.replay |
"safe" |
- | - |
list.access |
"read" |
- | - |
list.description |
string |
"List a page of permitted Computers. Follow nextOffset for another page." |
- |
list.input |
ZodObject<{ limit: ZodDefault<ZodNumber>; offset: ZodDefault<ZodNumber>; }, $strict> |
computerPageSchema |
- |
list.output |
ZodObject<{ computers: ZodArray<ZodObject<{ computerId: ZodString; name: ZodString; createdAt: ZodNumber; updatedAt: ZodNumber; }, $strict>>; nextOffset: ZodNullable<ZodNumber>; }, $strict> |
teamComputerDirectorySchema |
- |
list.execute() |
(input, context) => Promise<{ computers: object[]; nextOffset: number | null; }> |
- | Return an admitted inventory page to MCP or the retained broker. |
state |
object |
- | - |
state.replay |
"safe" |
- | - |
state.access |
"read" |
- | - |
state.description |
string |
"Read runtime state without waking a Computer, including its live admission queue position." |
- |
state.input |
ZodObject<{ computerId: ZodString; }, $strict> |
fleetComputerId |
- |
state.output |
ZodDiscriminatedUnion<[ZodObject<{ state: ZodEnum<{ running: "running"; sleeping: "sleeping"; starting: "starting"; }>; }, $strict>, ZodObject<{ state: ZodLiteral<"queued">; position: ZodNumber; }, $strict>], "state"> |
computerStateSchema |
- |
state.execute() |
(input, context) => Promise< | { state: "running" | "sleeping" | "starting"; } | { state: "queued"; position: number; }> |
- | Return liveness without waking the runtime. |
start |
object |
- | - |
start.replay |
"unsafe" |
- | - |
start.description |
string |
"Start a hosted Computer through ordinary admission. Waits until connected; poll computers.state while queued. Safe to retry." |
- |
start.input |
ZodObject<{ computerId: ZodString; }, $strict> |
fleetComputerId |
- |
start.output |
ZodDiscriminatedUnion<[ZodObject<{ state: ZodEnum<{ running: "running"; sleeping: "sleeping"; starting: "starting"; }>; }, $strict>, ZodObject<{ state: ZodLiteral<"queued">; position: ZodNumber; }, $strict>], "state"> |
computerStateSchema |
- |
start.execute() |
(input, context) => Promise< | { state: "running" | "sleeping" | "starting"; } | { state: "queued"; position: number; }> |
- | Admit and start this Computer. |
create |
object |
- | - |
create.replay |
"unsafe" |
- | - |
create.description |
string |
"Create a Computer with an optional friendly name. Request identity is generated automatically. If the outcome is uncertain, retry with its returned requestId and the original name input; do not start a second creation." |
- |
create.input |
ZodObject<{ name: ZodDefault<ZodNullable<ZodString>>; requestId: ZodDefault<ZodNullable<ZodString>>; }, $strict> |
fleetCreate |
- |
create.output |
ZodDiscriminatedUnion<[ZodObject<{ kind: ZodLiteral<"created">; requestId: ZodString; computer: ZodObject<{ computerId: ZodString; name: ZodString; }, $strict>; }, $strict>, ZodObject<{ kind: ZodEnum<{ denied: "denied"; uncertain: "uncertain"; conflict: "conflict"; invalid: "invalid"; }>; requestId: ZodString; }, $strict>], "kind"> |
fleetCreation |
- |
create.execute() |
(input, context) => Promise< | { kind: "created"; requestId: string; computer: { computerId: string; name: string; }; } | { kind: "denied" | "uncertain" | "conflict" | "invalid"; requestId: string; }> |
- | Mint one identity or preserve the requestId for an uncertain retry. |
appBindingName()function
Section titled “appBindingName()”function appBindingName(installationId): string;An installation ID as a guest binding name: spawn-git becomes SPAWN_GIT.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
installationId |
string |
Returns
Section titled “Returns”string
appSurfaceCache()function
Section titled “appSurfaceCache()”function appSurfaceCache(host): AppSurfaceCache;Make one AppSurfaceCache for a host whose artifact store and capabilities stay fixed.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
host |
Pick<OysterHost, "artifacts" | "capabilities"> |
Returns
Section titled “Returns”oysterAppSnapshot()function
Section titled “oysterAppSnapshot()”function oysterAppSnapshot( host, surfaces, principal, installations, access, sessionId?, familyListingCache?,): Promise< Readonly<{ modules: Readonly<Record<string, ModuleRegistration>>; levels: Readonly<Record<string, AppToolPolicy["level"]>>; fences: Readonly<Record<string, string>>; effects: Readonly< Record<string, Readonly<Record<string, "read" | "write" | "external">>> >; }>>;Derive the current principal’s admitted App modules and grants.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
host |
Pick<OysterHost, | "installations" | "instances" | "artifacts" | "guestLimits" | "backgroundOriginKey" | "computerId" | "capabilities" | "appToolPolicy" | "keys"> |
- |
surfaces |
AppSurfaceCache |
- |
principal |
OysterPrincipal |
- |
installations |
readonly Readonly<{ installationId: string; instanceId: InstanceId | null; appId: AppId; release: { releaseId: ReleaseId; appId: AppId; artifact: { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }; }; releasePin: "pinned" | "floating"; authority: { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: …; id: …; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }; status: "enabled" | "disabled" | "deleted"; visibility: "private" | "public"; approvedAnonymousMethods: readonly Readonly<{ name: string; digest: Sha256Digest; }>[]; anonymousApproval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }>[] |
- |
access |
OysterCallerAccess |
- |
sessionId? |
string |
- |
familyListingCache? |
Map<string, unknown> |
Shares one tool-family listing per Instance across the two appModules passes one oysterAppMethods call can make (the eager grants/version pass, and a session-scoped re-derivation); never shared across separate calls, so it never serves another request’s listing. |
Returns
Section titled “Returns”Promise<Readonly<{ modules: Readonly<Record<string,
ModuleRegistration>>; levels: Readonly<Record<string,
AppToolPolicy["level"]>>; fences:
Readonly<Record<string, string>>; effects:
Readonly<Record<string, Readonly<Record<string, "read" |
"write" | "external">>>>; }>>
oysterAppMethods()function
Section titled “oysterAppMethods()”function oysterAppMethods( host, principal, access, surfaces, preloadedInstallations?,): Promise< Readonly<{ id: string; acquire: (context) => Promise< Readonly<{ snapshot: CapabilitySourceSnapshot; release: () => Promise<void>; }> >; }> & object>;Capture installed App methods for MCP or agents as one principal-scoped source.
Enabled installations become env.<APP> modules using the Instance call path; a
dotted method such as repos.list is env.<APP>.repos.list(). Visitors see
only public read methods; owners see every discoverable method. A key sees only
the installations its own grants admit, each at the level (read/write) those
grants give it; Mycelium itself refuses a write call up front when the module’s
own grant is read (mycelium/src/access.ts). Call again to capture changes to
Releases, installation authority or the caller’s own grants.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
host |
Pick<OysterHost, | "installations" | "instances" | "artifacts" | "guestLimits" | "backgroundOriginKey" | "computerId" | "capabilities" | "appToolPolicy" | "keys" | "approvals"> |
principal |
OysterPrincipal |
access |
OysterCallerAccess |
surfaces |
AppSurfaceCache |
preloadedInstallations? |
readonly Readonly<{ installationId: string; instanceId: InstanceId | null; appId: AppId; release: { releaseId: ReleaseId; appId: AppId; artifact: { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }; }; releasePin: "pinned" | "floating"; authority: { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage"; capabilityApproved: true; operations: readonly string[]; resources: "tenant-scope" | readonly Readonly<…>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }; status: "enabled" | "disabled" | "deleted"; visibility: "private" | "public"; approvedAnonymousMethods: readonly Readonly<{ name: string; digest: Sha256Digest; }>[]; anonymousApproval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }>[] |
Returns
Section titled “Returns”Promise<Readonly<{ id: string; acquire: (context) =>
Promise<Readonly<{ snapshot: CapabilitySourceSnapshot; release: ()
=> Promise<void>; }>>; }> & object>
oysterComputerTools()function
Section titled “oysterComputerTools()”function oysterComputerTools(host, principal): Promise< | Readonly<{ id: string; acquire: (context) => Promise<Readonly<{ snapshot: CapabilitySourceSnapshot; release: () => Promise<...>; }>>;}> & object| null>;Capture the host’s fixed Computer for one caller as a Knapsack source. The host decides whether the caller holds Computer access; the ComputerDO still checks its host-issued grant on every call. Null when the host has no Computer or the caller has no access. Grants name the captured module.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
host |
Pick<OysterHost, "computerId" | "computer"> |
principal |
OysterPrincipal |
Returns
Section titled “Returns”Promise< | Readonly<{ id: string; acquire: (context) =>
Promise<Readonly<{ snapshot: CapabilitySourceSnapshot; release: ()
=> Promise<…>; }>>; }> & object | null>
oysterMcpCatalogLoad()function
Section titled “oysterMcpCatalogLoad()”function oysterMcpCatalogLoad(host): (principal) => Promise<Readonly<{ instructions: string; sources: readonly Readonly<{ id: string; acquire: (context) => Promise<Readonly<{ snapshot: ...; release: ...; }>>; }>[]; grants: Grants;}>>;Load the current catalog for an authenticated owner or key: installed App
methods, plus the host’s Computer when the caller holds Computer access. A key
sees exactly the installations and levels its own grants admit, and the Computer
only with its own computer.use grant; each App retains its own caller checks
regardless. App writes use the host’s approval record; stored approval of an
Agent’s App tools can permit headless App writes. The shared MCP server elicits
consent for explicitly confirmed operations, including every advertised
Workspace Computer call, even reads. Each call still re-admits the key, checks
current App approval and passes the App’s gate.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
host |
Pick<OysterHost, | "installations" | "instances" | "artifacts" | "guestLimits" | "backgroundOriginKey" | "computerId" | "computer" | "computerControl" | "capabilities" | "appToolPolicy" | "keys" | "workflows"> |
Returns
Section titled “Returns”(principal) => Promise<Readonly<{ instructions: string; sources:
readonly Readonly<{ id: string; acquire: (context) =>
Promise<Readonly<{ snapshot: …; release: …; }>>; }>[];
grants: Grants; }>>