App SDK Contracts
Audience: third-party marketplace artifact authors. Everything here is
re-exported by @mnemose/app-sdk under the semver promise below.
Semver promise
- Schema fields are additive-only within a minor release: new optional
fields, new artifact kinds (
kindvalues), and new named exports may land in minors without notice. - Removing an export, removing/narrowing a field, or making an optional field required requires a major version bump and a migration note.
- The exported surface is pinned by a snapshot test
(
test/contract.test.ts); any snapshot diff must be called out in the PR.
Artifact kinds
Every marketplace artifact carries a kind discriminator
(MarketplaceArtifactKind). Absent kinds default to "app" for backwards
compatibility. Authoring guide stubs per kind:
| Kind | What it installs | Status |
|---|---|---|
app | Gateway module, console routes, jobs | Stable — validate with AppManifestSchema |
provider-config | LLM provider entry into llm_provider_config | Stub — lands with wave M-3 |
harness | Agent/model configuration preset (importable JSON, optional skills) | Stub — wave M-3 |
mcp-tool | MCP server registration via McpToolSpecSchema + installMcpTool | Stable (ADR 0014) |
skill / skillset | Behavior packs mounted at .agents/skills in the agent sandbox | Stub — wave M-3 |
cloud-provider | Cloud-adapter implementation + installer provisioning step | Stub — wave M-4 |
compute-provider | Isolated compute backend (MicroVM, Dynamic Workers) via contributes.backendKinds | Stable (ADR 0014) |
All kinds share one identity envelope today: author against
AppManifestSchema, set kind, and the catalog/loader dispatch on it.
Port interfaces
Apps interact with cloud infrastructure only through ports from
@mnemose/cloud-adapters/ports (re-exported as types): EventBus,
BlobStorage, Secrets, Kms, Scheduler, IaaS, IdentityProvider,
Workflow, CloudCredentials. Never import adapter implementations
directly; provisioning injects the tenant-bound implementations.
CQRS conventions
Commands and events flow over the platform bus per
docs/architecture.md:
- Commands are imperative requests (
do-thing), handled exactly once. - Events are past-tense facts (
thing-done) emitted on theEventBusport; apps declare emitted/consumed event names in the manifest’seventsarray. - New topics require registration only — core command/event topics are not modified (see ADR 0012 “functional waterline”).
Validation
Use the environment-agnostic helpers (safeParseAppManifest,
parseAppManifest, validateAppManifest, parseCatalogRegistry) — they run
on Node.js, Workers, and browsers. Gate CI on schema validation before
publishing any artifact.
Lifecycle commands and events
The full lifecycle command/event surface is re-exported from
@mnemose/app-sdk (single source of truth: @mnemose/domain, mirrored by
@mnemose/marketplace):
- Commands:
InstallApp,UninstallApp,EnableApp,DisableApp,UpdateAppConfig(union:AppLifecycleCommandSchema). - Events:
AppInstalled,AppUninstalled,AppEnabled,AppDisabled,AppConfigUpdated(union:AppLifecycleEventSchema).
Third-party code should parse outgoing lifecycle payloads with
AppLifecycleCommandSchema and validate incoming lifecycle facts with
AppLifecycleEventSchema rather than re-declaring these shapes. The
UpdateAppConfig command carries a full replacement config object plus an
optional semver version bump; it emits AppConfigUpdated once handled on
the platform command subscriber.
Compute providers (ADR 0014)
Compute-provider apps install isolated compute backends. The manifest’s
contributes.backendKinds array declares one or more backend kinds:
{ "kind": "compute-provider", "contributes": { "backendKinds": [{ "kind": "cf-sandbox", "schemaModule": "./schema.js", "adapterFactoryModule": "./adapter.js", "adapterFactoryExport": "createCfSandboxAdapter" }] }}At boot, the gateway module calls registerBackendKind() (to add the Zod
schema to the open SandboxComputeBackendSchema union) and
registerAdapterFactory() (to register the adapter factory in the
ExecutionAdapterRegistry). SandboxDO resolves the adapter by
backendKind at dispatch time.
Reference implementations in app-store/apps/:
cf-sandbox-provider— Cloudflare Sandbox SDK (Containers + DOs)dynamic-workers-provider— Dynamic Workers (isolated V8)microvm-provider— Remote MicroVM (libkrun, microsandbox)
MCP tool artifacts (ADR 0014)
MCP tool artifacts register MCP servers discoverable by the ToolRegistry.
Validate with McpToolSpecSchema and install via installMcpTool():
import { McpToolSpecSchema, parseMcpToolSpec } from "@mnemose/app-sdk";
const spec = parseMcpToolSpec({ specVersion: "1", id: "my-mcp-server", name: "My MCP Server", version: "1.0.0", transport: "http", endpoint: "https://my-server.example.com/mcp", tools: ["my-tool.search", "my-tool.execute"],});Service bindings (ADR 0014)
Apps can declare service bindings via contributes.serviceBindings —
HTTP, MCP, or GraphQL services that bind into sandboxes. The
dynamic-workers-provider app uses this to ship its search-and-execute
SDK as an MCP service.