The SDK that turns work APIs into interfaces agents can work with.
Compile APIs and events. Keep context and policy in your application. Leave the mind to the agent.
OpenMatter is an open, embeddable TypeScript SDK for putting external agents into chat, issue trackers, code hosts, kanban systems, forms, documents, and scheduled work.
The executable foundation composes two replaceable boundaries: WorkIntegration normalizes work-platform events and effects; AgentDriver maps durable Sessions and Turns to ACP, managed runtimes, or custom agent SDKs. Application code owns context construction, policy, and orchestration.
Work Profiles and OpenAPI compilation remain a directional integration layer; no compiler package is claimed as executable yet. Arbitrary SaaS semantics cannot be inferred from OpenAPI alone.
Immutable facts, explicit transitions. Events, ContextProjection inputs, Turn inputs, permission decisions, Reactions, and effect intents are durable values rather than live mutable objects. Session, lease, and delivery state may change only through named, fenced state transitions. The runtime takes deep snapshots at asynchronous and durable boundaries; TypeScript readonly alone is not treated as immutability.
native event agent runtime
│ ▲
▼ │
WorkIntegration.ingest AgentDriver Stream
│ │
▼ │
WorkEvent → ContextProjection → Session → Turn │
│ │
└──────── application handler ─────────────┘
│
▼
Reaction
│
▼
WorkEffect intents
│
▼
WorkIntegration.deliver
Every domain-complete accepted WorkEvent reaches one terminal Reaction. A reaction may contain replies, reactions, forms, approvals, work-item mutations, or no effects at all. Infrastructure failures leave recoverable claims instead of manufacturing false domain outcomes.
Directional Work Profiles may later describe operations, events, Resource identities, authority, risk, and provider bindings as portable JSON. Those artifacts complement the code-first runtime; they do not replace its authorization or context decisions.
@openmatter/core,@openmatter/store,@openmatter/integration, and@openmatter/agentdefine the immutable records and three Effect-native ports.@openmatter/runtimeprovides the Event → Context → Session → Reaction → Effect lifecycle.@openmatter/store-memory,@openmatter/integration-mock, and@openmatter/agent-mockare executable test/reference adapters.@openmatter/integration-slackis the first real Work Integration, including signed HTTP ingress, messages, reactions, slash commands, and forms.@openmatter/orchestrationincludes the Claude Tag-style Scope/WorkThread/Session preset.@openmatter/host-cloudflareand@openmatter/host-localbind the same application to Worker Queues or Slack Socket Mode.examples/basic,examples/slack-cloudflare, andexamples/slack-localshow the three executable composition shapes.
See Project structure for dependency direction and package ownership.
import { Effect } from "effect";
import { makeMockAgentDriver } from "@openmatter/agent-mock";
import { makeMockIntegration } from "@openmatter/integration-mock";
import { createOpenMatter } from "@openmatter/runtime";
import { makeMemoryStore } from "@openmatter/store-memory";
const chat = makeMockIntegration({ id: "chat" });
const worker = makeMockAgentDriver({ id: "worker", output: "Hello" });
const app = createOpenMatter({
store: makeMemoryStore(),
integrations: { chat: chat.integration },
agents: { worker: worker.driver },
});
app.on("chat.message.received", (work) =>
Effect.gen(function* () {
const context = yield* work.context.project({
scopeId: "project:openmatter",
workThreadId: "discussion:runtime",
items: [work.context.event()],
grants: ["chat.message.reply"],
});
const result = yield* work
.agent("worker")
.session({
scopeId: context.scopeId,
workThreadId: context.workThreadId,
privacyPartition: "team",
})
.turn({ context, allow: context.grants });
const reply = yield* work.effect(context, {
integrationId: "chat",
operation: "message.reply",
input: { text: result.output ?? null },
});
return work.react.effects([reply]);
}),
);
await app.acceptFrom("chat", nativeWebhookBody);This is the executable v0 surface. Real platform, durable-store, and Agent Driver adapters replace the mocks without changing handler semantics. The SDK provides conventions and typed boundaries, not a closed configuration language.
OpenMatter composes two semantic interfaces:
- Work Integration maps provider events, references, context, capabilities, authentication, and effects into OpenMatter.
- Agent Driver maps sessions, turns, event streams, permissions, cancellation, and results to ACP, Claude managed runtimes, in-process SDKs, or custom agents.
ACP is the first open Agent Driver binding. HTTP, WebSocket, webhooks, polling, and SDK calls are transport choices of a binding, not new core domains.
A Matter is a durable identity for “the thing being worked on.” It may be represented by a Linear issue ID, GitHub pull request, URL, channel thread, team alias, natural-language phrase, or several of these at once.
OpenMatter does not require every mention to resolve. Unknown or ambiguous references retain their raw text and provenance until application code, a deterministic resolver, an agent proposal, or a user confirmation links them.
Proactive behavior enters through a scheduler/source adapter; it is not a special kind of agent or a timer hidden inside the Runtime:
app.on("schedule.issue-patrol.tick", (work) => {
// Build context and optionally invoke an agent exactly as for a webhook event.
return work.react.none("Nothing requires attention");
});
// Cloud scheduler, queue consumer, cron process, or test adapter:
await app.accept(scheduleAdapter.tick("issue-patrol", scheduledAt));Every domain-complete WorkEvent reaches one immutable terminal Reaction.
Operation delivery has its own durable receipts; a reaction with no effects is
still explicit and observable. Infrastructure failures keep recoverable claims
instead of manufacturing a false domain result.
OpenMatter keeps distinct concepts distinct:
ResourceAddressidentifies a provider resource.Matteridentifies the durable thing being worked on and may link several provider resources.AgentScopeowns shared authority, policy, bindings, and candidate context.WorkThreadowns the structured continuity of one piece of work across events and providers.ContextProjectionis the authorized snapshot delivered to one Turn.AgentSessionis an external runtime continuity handle, not the only durable source of truth.
A Channel is not automatically a Scope, WorkThread, or Agent Session. Multiple channels can share a Scope; one Matter can connect a message thread, issue, pull request, and document.
OpenMatter does not implement another agent brain. AgentDriver maps OpenMatter sessions, turns, operation grants, event streams, permissions, and cancellation to:
- Agent Client Protocol;
- managed-agent runtimes;
- in-process SDKs;
- MCP-backed tools;
- custom agents.
The agent owns reasoning, planning, transcript, and private tool state. OpenMatter owns work-side context, authority, continuity, reactions, and effect receipts.
The core Runtime owns no server, scheduler, queue, or process loop. Optional host adapters translate platform lifecycle into the same application boundary:
- Cloudflare receives signed Slack HTTP requests, returns URL-verification
challenges, and enqueues verified native inputs before running the Agent in a
Queue consumer. See
examples/slack-cloudflare. - A local Node process uses Slack's official Socket Mode SDK, so it needs no
public webhook URL. See
examples/slack-local.
Both modes share makeSlackIntegration() and installClaudeTag(). Switching
transport does not change Scope, ContextProjection, Session, Reaction, or
effect semantics. A Cloudflare deployment must inject a durable
OpenMatterStore; store-memory is intentionally not a production database.
The Queue host provides durable ingress retries; the local Socket Mode host
acknowledges before durable acceptance and is intentionally best-effort unless
the application adds its own durable queue.
Cloudflare Cron, EventBridge, Kubernetes CronJob, and Node timers keep their own registration, overlap, retry, and wake-up semantics. OpenMatter does not embed a scheduler. Each decoded tick follows the same Scope, Matter, WorkThread, Session, Turn, and Reaction lifecycle.
All durable fields use one portable JsonValue contract. Integration-native payloads, Agent handles, and provider receipts remain available, but adapters must encode them as JSON instead of leaking live SDK objects into storage.
- Not a connector catalog that must hand-code every SaaS.
- Not a partial wrapper around Activepieces, Zapier, or another workflow runtime.
- Not another prompt graph, planner, or model SDK.
- Not a replacement for ACP, OpenAPI, AsyncAPI, GraphQL, or MCP.
- Not a mandatory Hub, SaaS control plane, credential service, database, queue, or cloud.
- Not a closed JSON workflow DSL.
- Product and architecture brief
- Executable Effect runtime architecture
- Current design decisions
- Domain model
- SDK shape
- Work Profiles, bindings, and Matter references
- Agent runtime and session lifecycle
- Executable technical design
- Standards and platform references
- Package structure
- Slack, Claude Tag preset, and deployment hosts
- Directional Work Profile layer: architecture and draft specification
Important
OpenMatter has an executable v0 vertical slice. Its contracts remain pre-stable until they are exercised by real integrations, Agent Drivers, durable stores, and a conformance harness.
The repository now contains the first runnable vertical slice:
- Effect Schema domain contracts;
- Effect Service/Layer ports for storage, work integrations, and agent drivers;
- persisted context projections with provenance, grants, and digests;
- authority/privacy-bound Agent Sessions and validated OpenMAEvent streams;
- enforced grants for Agent turns and provider operations;
- leased event/session/effect claims with full-lifecycle heartbeat renewal and stale-worker fencing;
- insert-once terminal Reactions, immutable authorized Effect intents, retry receipts, and outbox recovery;
- stable logical Turns, checkpointed Agent streams, durable permission decisions, and idempotent Session creation;
- memory storage, mock work-platform, and mock agent adapters;
- the same execution pipeline for request/serverless and long-lived sources.
Run it with:
pnpm install
pnpm check