A TypeScript toolkit for shipping AI agents that are multi-tenant-safe, without complex infrastructure. Curated memory, human-gated learning, and a real execution sandbox.
Most agent harnesses are built for local use: one developer, one machine, one trust boundary. Shipping agents into production is different. One mistake can delete files, leak secrets, or cross tenant boundaries.
You stay in control of auth, tenancy, and the tools the agent can reach. Your users get a real agent that can run code and improve over time, inside an isolated home.
No huge cloud bill. No fancy infrastructure.
| Pillar | What you get |
|---|---|
| Secure by default | Prompt-injection, promptware, and exfiltration scanning on every memory and skill write. Threats never reach the system prompt. |
| Sandboxed execution | Per-tenant AgentFS volumes and bash-tool guardrails. Destructive commands, secret exfil, and non-allowlisted network egress are blocked before they run. |
| Production multi-tenancy | One isolated filesystem, memory, skill library, transcript store, and audit trail per tenant. A bug in tenant A cannot touch tenant B. |
| Self-improving under approval | A background curator distills sessions into durable memory and reusable skills. Writes stage for human review by default. Hosts can set curator.autoApprove when end users are not the right reviewers. |
Your app authenticates the user and maps them to a stable tenantId. Never
take tenantId from the client body alone.
npm i @socialrobot-io/agent-kit-node @socialrobot-io/agent-kit-next ai
npm i @ai-sdk/anthropic # or openai / deepseek / …Hono / Express: omit @socialrobot-io/agent-kit-next.
Config — agents/ next to app/ by default. Custom folder:
withAgentKit(config, { agentsDir: "src/agents" }).
// next.config.ts
import type { NextConfig } from "next";
import { withAgentKit } from "@socialrobot-io/agent-kit-next";
export default withAgentKit({} satisfies NextConfig);Agents — one folder per agent. What goes in SOUL.md / AGENTS.md:
Getting started.
agents/
chat/
SOUL.md
AGENTS.md
skills/ optional
Backend — createAgentKit once at module scope. It owns the per-tenant
home cache and opens a fresh session per request (state lives on disk), so the
route just calls kit.session(tenantId, sessionId).
// lib/kit.ts
import { anthropic } from "@ai-sdk/anthropic";
import { createAgentKit, loadAgent } from "@socialrobot-io/agent-kit-node";
export const kit = createAgentKit({
agent: await loadAgent("chat"),
model: anthropic("claude-sonnet-4-5"),
});// app/api/chat/route.ts
import {
convertToModelMessages,
createUIMessageStreamResponse,
toUIMessageStream,
type UIMessage,
} from "ai";
import { requireUser } from "@/lib/auth";
import { kit } from "@/lib/kit";
export const runtime = "nodejs";
export async function POST(req: Request) {
const { tenantId } = await requireUser(req);
const { messages, id: sessionId } = (await req.json()) as {
messages: UIMessage[];
id: string; // useChat
};
const session = await kit.session(tenantId, sessionId);
const result = session.stream(await convertToModelMessages(messages));
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}Working demo: examples/example-app.
Same agents/ layout and kit as above.
// src/server.ts
import { Hono } from "hono";
import { requireUser } from "./auth";
import { kit } from "./kit";
const app = new Hono();
app.post("/chat", async (c) => {
const { tenantId } = await requireUser(c);
const { sessionId, text } = await c.req.json<{
sessionId: string;
text: string;
}>();
const session = await kit.session(tenantId, sessionId);
const turn = await session.run([{ role: "user", content: text }]);
return c.json({ text: turn.text });
});
export default app;agent-kit composes existing libraries. The Vercel AI SDK
shapes most of the live API (ModelMessage, session.run / session.stream,
toolApproval, and AI SDK UI useChat).
| Layer | Library | What you feel in the API |
|---|---|---|
| Model loop | ai (Vercel AI SDK) |
Messages, run / stream, tools, UI approval |
| Model providers | AI SDK providers or @ai-sdk/gateway |
Pass a LanguageModel, or a string id via the Gateway |
| Tenant volume | AgentFS | One SQLite filesystem per tenant |
| Sandbox shell | bash-tool + just-bash | bash / readFile / writeFile behind guardrails |
If you already use the AI SDK, agent-kit slots in as the tenant home, memory, skills, and sandbox around that loop.
More: install notes, how the loop works, demo commands, security, and all guides.
MIT. See NOTICE for third-party attribution.
