Skip to content
API reference

mcp

Import
import * as api from "@fungi.computer/oyster/mcp";
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.

Why an App method call from the MCP catalog was refused.

  • Error
Signature
new AppMethodRefused(code, detail?): AppMethodRefused;

detail is the App’s own caller-facing refusal message, when it gave one.

Parameter Type
code string
detail? string

AppMethodRefused

Signature
Error.constructor;
Signature
readonly name: "AppMethodRefused" = "AppMethodRefused";
Signature
Error.name;
Signature
readonly code: string;

ComputerControlPorttype alias

Section titled “ComputerControlPort”
Signature
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”
Signature
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”
Signature
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”
Signature
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”
Signature
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.

Parameter Type
release Installation["release"]

Promise<ReleaseSurface | null>

computerControlSpecs()function

Section titled “computerControlSpecs()”
Signature
function computerControlSpecs(port): object;

One set of schemas and operations for MCP and direct broker invocation.

Parameter Type
port ComputerControlPort

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()”
Signature
function appBindingName(installationId): string;

An installation ID as a guest binding name: spawn-git becomes SPAWN_GIT.

Parameter Type
installationId string

string


appSurfaceCache()function

Section titled “appSurfaceCache()”
Signature
function appSurfaceCache(host): AppSurfaceCache;

Make one AppSurfaceCache for a host whose artifact store and capabilities stay fixed.

Parameter Type
host Pick<OysterHost, "artifacts" | "capabilities">

AppSurfaceCache


oysterAppSnapshot()function

Section titled “oysterAppSnapshot()”
Signature
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.

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.

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()”
Signature
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.

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; }>[]

Promise<Readonly<{ id: string; acquire: (context) => Promise<Readonly<{ snapshot: CapabilitySourceSnapshot; release: () => Promise<void>; }>>; }> & object>


oysterComputerTools()function

Section titled “oysterComputerTools()”
Signature
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.

Parameter Type
host Pick<OysterHost, "computerId" | "computer">
principal OysterPrincipal

Promise< | Readonly<{ id: string; acquire: (context) => Promise<Readonly<{ snapshot: CapabilitySourceSnapshot; release: () => Promise<…>; }>>; }> & object | null>


oysterMcpCatalogLoad()function

Section titled “oysterMcpCatalogLoad()”
Signature
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.

Parameter Type
host Pick<OysterHost, | "installations" | "instances" | "artifacts" | "guestLimits" | "backgroundOriginKey" | "computerId" | "computer" | "computerControl" | "capabilities" | "appToolPolicy" | "keys" | "workflows">

(principal) => Promise<Readonly<{ instructions: string; sources: readonly Readonly<{ id: string; acquire: (context) => Promise<Readonly<{ snapshot: …; release: …; }>>; }>[]; grants: Grants; }>>