Doc version 1.0 · English (authoritative source) · Updated 2026-06-27 · Translations: 中文 · 日本語 · Русский · Français · Español · 한국어. If a translation conflicts with this English version, the English version governs.
Gotong — from gotong-royong, the Malay–Indonesian tradition of a whole village shouldering work together (Chinese: 共同) — a self-hosted substrate where people and AI agents collaborate as equal participants, and organizations federate without handing over their keys, data, or billing.
Gotong is not an agent — and not another agent framework. It's the layer underneath them: a registry, a message bus, a task router, a governed federation link, and an append-only transcript. LangGraph / CrewAI agents, CLI coding agents (Claude Code, Codex), and humans all plug in as the same Participant. The Hub keeps the signals flowing and the boundaries enforced — it never runs the LLM, so every decision stays with the participants.
Most AI tools give you two options: hand everything to a cloud you don't control, or wire it all together yourself. Gotong is the third option — AI you can point at your home, your family, or your money, because the boundaries are real and yours:
- A human is in the loop where it matters. Reversible actions (turn off the lights) just happen; irreversible ones (lock the door, spend money, send a child's data across a link) wait for a person to confirm in an inbox. The workflow can't skip the gate.
-
Your keys and data stay on your disk. Credentials live encrypted in your own
.gotong/directory. Federating with another hub shares a capability, not your vault. - Nothing decides in the dark. Every dispatch and result is an append-only transcript you can read. The framework never runs the model, so there's no hidden judgment call.
→ See the flagship templates for hubs a non-technical person can import and run today (smart home, café ops, a family learning hub, a personal coding hub), each with the governance gate shown plainly and a one-command demo. Want to share your own? templates/community/templates/.
- The Hub is dumb on purpose. It does not run LLMs or own agent loops. It routes messages, dispatches tasks, persists the transcript, and emits events. Decisions stay with participants.
-
Humans are first-class. A human is a
Participantlike an agent is. The Hub's async / long-running primitives apply to both. -
One interface, two deployment shapes. Agents implement the same
Participantcontract whether they run in-process or across the network. Local and remote agents share the same registry and the same scheduler. - Pluggable scheduling. Three task-routing strategies out of the box: explicit assignment, capability matching, and broadcast claiming.
-
Bring your own LLM. A small
LlmAgentbase class + a neutralLlmProviderinterface let you back an agent with Claude, GPT, or any other model without touching the Hub.
Self-hosted, file-first, and governed for multi-org use. A workspace is a directory on disk (.gotong/) — drop the directory and the space is gone; copy it and you've handed the room to a teammate; restarts are transparent. On top of that: a per-org credential vault, cross-org federation with per-link trust contracts (capability allowlist · data-class gate · quota · revocation), human-in-the-loop approval inboxes, and a usage / cost ledger. The Hub still never runs an LLM — every decision stays with the participants.
The npm packages are scoped @gotong/*; the Python SDK is gotong on PyPI. License: MIT.
Lost? Start at
docs/OVERVIEW.md— a single page that ties usage, license, agent on-boarding, template downloads, multi-user teams, and multi-team federation into one narrative. The table below is the by-role drill-down.
| You are… | Read this | TL;DR |
|---|---|---|
| 🧭 First time here | docs/OVERVIEW.md |
5-minute map of every concept + a "small-team workflow" walkthrough. |
| 🧑 A worker / admin joining a room | docs/HUMAN.md |
Open the URL the operator gave you; pick a nickname; you're in. |
| 🤖 Writing an agent to plug in | docs/AGENT.md |
@gotong/sdk-node or Python gotong. Subclass AgentParticipant. |
| 🧩 Bringing in an LLM agent without writing code |
docs/TEMPLATES.md + templates/
|
YAML manifest → paste / upload in admin UI → host spawns it for you. Two sets: project-original (templates/agents/) and CC0/MIT community-adapted (templates/community/). |
| ⭐ Just want a hub that does something useful |
docs/zh/FLAGSHIP-TEMPLATES.md (zh) |
Curated, trust-framed gallery — import one and it works. Smart home, café ops, family learning, personal coding. Each shows what it can/can't touch + a no-key demo. |
| 🔧 Running the server | docs/DEPLOY.md |
pnpm host for local, Caddy + systemd for public. |
| 🚀 Going live (3 topologies) |
docs/zh/GO-LIVE.md + deploy/
|
Home host + IM, cloud host + IM, or cloud + direct IP. Copy deploy/.env.home / .env.cloud, follow the runbook. IM bridge is outbound long-poll → a NAT'd home box needs no tunnel. (Runbook is zh; English pending.) |
| 🪢 Federating two hubs (team → org) | docs/FEDERATION.md |
TeamBridgeAgent makes a whole sub-Hub appear upstream as one agent — keeps internal members / keys / sub-tasks private. |
| 🔌 Driving a Hub from Claude Desktop / Cursor / Cline | docs/MCP.md |
@gotong/mcp-server is an MCP bridge — 5 tools (list / dispatch / evaluate / leaderboard / tasks). Add 5 lines to your MCP client config. |
| 🧰 Giving your agents the MCP tool ecosystem | docs/MCP.md |
@gotong/mcp-client lets your Gotong agents attach Filesystem / GitHub / Slack / Postgres / any MCP server. LlmAgent runs a multi-turn tool-use loop out of the box (v0.3+) — just pass tools: toolset and Claude / GPT decide when to call which tool. |
| ⚖️ Worried about license / commercial use | docs/LICENSE-FAQ.md |
MIT throughout. Embeddable in closed-source / SaaS. Community templates are CC0 + MIT. |
| 🧠 Designing on top of it |
docs/ARCHITECTURE.md + docs/PROTOCOL.md
|
Hub is dumb on purpose; wire protocol is v1.0. |
| 📊 Sizing a deployment |
docs/PERFORMANCE.md + docs/zh/CLOUD-RESOURCE-FOOTPRINT.md
|
Pre-launch baseline numbers + how to rerun the load test against your own hardware. The zh doc adds a real production measurement (Feishu + MiMo, single hub on a 2 vCPU / 2 GiB box) with per-load capacity estimates and upgrade triggers — steady state is ~110–160 MiB RAM and ~0 CPU because inference runs on the LLM provider, not the host. |
| 🛟 Operating in production | docs/OPERATIONS.md |
Backup/restore playbook, disaster-recovery drill, secret.key handling, troubleshooting. |
| 📡 Monitoring + alerts | docs/MONITORING.md |
Prometheus scrape config, 7 alert rules with runbooks, Grafana dashboard JSON. |
| Host-managed (no code) | External SDK (your code) | |
|---|---|---|
| You do | Paste / upload a YAML manifest in admin UI | Write AgentParticipant.handleTask, call connect(url, agents)
|
| Where it runs | Inside the Hub process (LocalAgentPool) | Anywhere on the network |
| What it can do | LLM tasks via Anthropic / OpenAI / Mock providers | Anything — LLMs, scrapers, private data, ML models, scripts |
| API key lives | Encrypted in .gotong/secrets.enc.json (per-agent or workspace default) |
Wherever your code reads it |
| On restart | Auto-respawned by LocalAgentPool
|
Your code reconnects (SDK has built-in auto-retry) |
| Best for | End users • standard roles • one-click templates | Developers • private logic • cross-language workers |
| Read | docs/TEMPLATES.md |
docs/AGENT.md |
Both paths plug into the same Hub. Mix freely — a room can have host-managed writer-zh next to your private SDK-connected rag-agent.
What this project is — and what it refuses to become: CHARTER.md. Contributing? See CONTRIBUTING.md. Security issues: SECURITY.md. Version history: CHANGELOG.md.
Learn by watching → LEARN.md curates the best community-made videos, talks, and tutorials, each credited to its author. Everyone who builds and spreads Gotong → CONTRIBUTORS.md — because reach is real work, and we recognize it.
New here?
QUICKSTART.mdis the do-this → see-that ladder: clone → a real multi-participant result on screen in ~1 min (no key, no Docker) → your own browser hub → a thinking LLM agent. The install matrix below is the reference; the ladder is the fast path.
The path that needs no terminal, no Node, no Docker on the machine that runs it. A maintainer builds a self-contained portable bundle once:
node scripts/build-portable.mjs # → dist-portable/Gotong-macos-arm64/Then hand the whole Gotong-macos-arm64/ folder to anyone. They double-click
Gotong.command → the browser opens the 5-minute setup wizard. The bundle
ships its own pinned Node runtime + the compiled host + a real on-disk
node_modules (including the native SQLite binding), so it runs the full
identity-backed host on a machine with nothing installed. Data lives in
~/.gotong (outside the folder), so replacing the bundle never loses data.
Built on demand, not a committed/published download yet (that's the post-1.0
plan) — for now "download & run" means build the folder once, share the folder.
macOS arm64 this round. Full write-up: docs/zh/PORTABLE-BUNDLE.md.
# A. Docker (recommended — no Node setup, works on macOS / Windows / Linux)
docker compose up
# → http://127.0.0.1:3000 + admin URL printed in the logs
# → state persists under ./data
# B. From source (cloned repo, full demo set available)
pnpm install
pnpm build
pnpm hostBoth boot the same binary. Open the printed admin URL → save the token → you're in.
First-run nicety (new). After boot the host prints a prominent next-step banner pointing at the loopback setup wizard, and on a local (loopback) first run it opens your browser there for you:
┌─ 下一步 / Next step ──────────────────────────
打开浏览器完成 5 分钟设置 (设置向导,无需 token):
Open your browser to finish the 5-minute setup:
→ http://127.0.0.1:3000
设置向导在本机回环 (loopback) 上运行。
The setup wizard runs on loopback only.
└───────────────────────────────────────────────
(已自动打开浏览器 / browser opened — GOTONG_OPEN_BROWSER=0 关闭)
GOTONG_OPEN_BROWSER controls the auto-open: unset = auto (first local run
only), 1/always = every start, 0/never = off. It is also forced off
whenever the host is network-exposed — a headless server never pops a browser,
and the wizard isn't reachable there anyway (that path uses the admin-token
file). The banner itself always prints.
💡 Distribution. No
npm publishat this stage — Docker (A) and source (B) are the two supported install paths. The earlier "queued for v2.1" npm plan has been descoped; the registry choice (npm / JSR / source-only) is an open decision tracked in RELEASE-CHECKLIST. Pre-built single-file binaries for macOS / Windows are a planned but non-blocking item — Docker already covers the "click and run" cross-platform case.
CLI flags (from a built repo):
pnpm exec gotong-host --help # full env-var reference
pnpm exec gotong-host --version # current host versionAfter it boots, follow docs/OVERVIEW.md for the "what now" walkthrough.
Won't start? Run a pre-flight check before booting — it inspects the exact
GOTONG_* env the host reads (Node version, ports actually free to bind, data dir
writable, master key) and prints, per check, ✓ / ⚠ / ✖ with a one-line fix:
pnpm exec gotong doctor # report only
pnpm exec gotong doctor --fix # also auto-creates a missing data dir (the one safe, reversible repair)And if a boot does fail, the host turns the common, recoverable failures
(port already in use, no permission to bind a port, missing/invalid master key,
data dir not writable, disk full) into a one-line human message naming which
GOTONG_* var to change — not a stack trace. See the troubleshooting section in
docs/zh/GO-LIVE.md §十一.
Verify the key probe works (no real key needed). The most common first-run trap is a pasted LLM key that silently doesn't work. The setup wizard catches this with a one-click "去补 key" rescue path; this command walks that same probe end to end so you know the rescue path is wired before you onboard:
pnpm check:onboarding # hermetic — proves a bad/empty key → "go add a key", a network error → "check the URL"
ANTHROPIC_API_KEY=… pnpm check:onboarding # also round-trips a REAL key over the wire (opt-in; skipped without one)It's hermetic by default (no network, no spend) and never logs your key.
Exit 0 = every check that ran passed. The opt-in real-key check mirrors the
live gate's env contract (OPENAI_API_KEY + OPENAI_BASE_URL=https://api.deepseek.com
-
GOTONG_LIVE_OPENAI_MODEL=deepseek-chatfor the DeepSeek path).
Got a fresh Ubuntu/Debian box? One command fetches the code (the repo is public) and provisions a systemd service:
curl -fsSL https://raw.githubusercontent.com/Emir-Aksoy/Gotong/main/deploy/cloud-quickstart.sh \
| sudo bash -s -- --clone
# already have a checkout on the box: sudo bash deploy/cloud-quickstart.sh
# preview first, mutates nothing: bash deploy/cloud-quickstart.sh --dry-runIt installs Node + pnpm, builds, creates the gotong service user and data
dir, drops in /etc/gotong.env (from deploy/.env.cloud),
and installs a systemd unit that mirrors docs/zh/DEPLOY.md
§C.4. It stops one step short of starting — the env file ships with the
domain / master key / host-allowlist blank, and exposing an unconfigured box is
unsafe. It prints the safe last mile: fill the env, run
scripts/cloud-harden.sh (perimeter check), put Caddy
- a firewall in front, then
systemctl enable --now gotong.
There is no browser "one-click deploy" button while the repo is private (those need a public repo or a provider account pre-linked to your git). This copy-pasteable bootstrap is the real, testable equivalent. Full runbook — topology, IP-exposure risks, IM member onboarding:
docs/zh/GO-LIVE.md.
如果你就一个人, 想把 Gotong 当成"我的 AI 桌面"用 (不是给团队开 hub),
直接 docker compose up 就行 — host 第一次启动检测到只有你一个用户,
自动进入个人模式:
docker compose up
# → http://127.0.0.1:3000/admin?token=<打印出来>
# → 首屏顶部不显示 "owner" 角色 chip (个人用户不需要看见组织角色)
# → 副标题写"我的 AI 桌面"(不是"管理员控制台")
# → 设置 tab 出现 [升级到团队模式] 按钮 — 哪天想拉人就点一下个人模式与团队模式的差别就两点:
- 主页副标题文案不同 / role chip 隐藏
- 设置里多个升级按钮
所有 admin tab 都还在(用户管理 / peer / 配额 / audit 全可见), 但你不会被这些概念占满屏幕。需要时再用。
GOTONG_MODE=team 可以强制 pin 团队模式(即使只有一个用户);
GOTONG_MODE=personal 反过来——多用户时也强制 pin 个人模式(罕见,
通常给 dev / 测试场景)。
升级到团队后, 自动出现"邀请用户"流程, 跟着导出 admin URL 给团队成员;
路径见下一节 5-min personal growth workflow 或 docs/zh/OVERVIEW.md。
The first ready-to-run shipped experience. 7 教练 (访谈 + 身体 / 心理 / 目标 / 资源 / 关系 + 综合规划师) 跑一遍 → 一份 markdown 12 周墙上计划落到磁盘。Default LLM 是 DeepSeek(国内可达、便宜)。
1. 装好 host (Docker 或源码,见上)
2. 打开打印的 admin URL → 进 admin
3. 申请 DeepSeek API key: https://platform.deepseek.com (新用户送 10 元额度,够跑几十次)
4. Admin → 工作流 tab → 点 [导入团队 (bundle)] → 点 [🎁 用内置模板:个人成长]
→ 粘贴 DeepSeek key → [导入]
(7 个 agent 一键创建,workflow 自动注册)
5. 工作流卡片上点 [开始] → 弹 4 段表单 (现状 / 愿望 / 卡点 / 这次最想想清楚什么)
6. 派发 → 等 ~3.5 分钟 (7 次 DeepSeek API call)
7. 工作流 tab 滚到底 → "成长报告" 面板 → 点 [下载]
或: <space>/services/artifact/file/agent/growth-synthesist/reports/<caseId>/<date>.md
报告里有:画像 + 身体/心理/目标/资源/关系 五份维度分析 + 一句话发展路径 + 12 周墙上计划 (主线 + 副线,每周做什么) + 5 个权衡判断 + "做不到怎么办" 降级方案 + "v2 跑工作流时建议你回答的 5 个种子问题"(下次回来用)。
🙏 关于隐私 / 数据:你的 4 段自述会发给 DeepSeek (中国大陆服务器) 做推理。Workflow 跑完后,所有产出落在你自己电脑的
.gotong-*/services/目录,不会上传任何云。每位教练都设计成有边界的陪伴者 — 身体教练触及红旗(持续胸痛 / 不明出血等)会让你找医生;心理教练触及风险信号会给出 24h 危机热线(全国 400-161-9995 / 马来西亚 Befrienders 03-7956 8144)。这不是医生 / 心理咨询师 / 财务顾问 / 关系治疗师的替代品。
想换 Anthropic Claude 或 OpenAI?编辑 templates/teams/personal-growth-team.yaml,把每个 agent 的 provider / baseURL / model 改掉就行 — system 提示词跟 vendor 无关。
Structured logging is on by default — JSON line per event when stdout is piped (for jq / Loki / ELK / Datadog), pretty-printed when stdout is a terminal. Three env vars control it:
GOTONG_LOG_LEVEL=info # silent | trace | debug | info (default) | warn | error | fatal
GOTONG_LOG_FORMAT=json # json | pretty (default: auto by TTY)
GOTONG_LOG_DISABLED=1 # hard-off escape hatchFilter by component with jq once you've got JSON output:
pnpm host 2>&1 | jq 'select(.comp == "local-agents")'Once you've pnpm install && pnpm build-ed, every collaboration pattern in the framework has a runnable demo:
# in-process demos (no network)
pnpm demo # two mock agents + one mock human
pnpm demo:broadcast # three reviewers race, losers cancelled
# persistence demos
pnpm demo:persist:fresh && pnpm demo:persist:resume
pnpm demo:persist:sqlite:fresh && pnpm demo:persist:sqlite:resume
# remote agents
pnpm demo:remote # host + worker in separate processes
pnpm demo:remote:python # Node host + Python worker (cross-language)
pnpm demo:cli-human # terminal-as-human approval loop
# LLM-backed agents
pnpm demo:llm # LlmAgent + mock provider (no API key needed)
pnpm demo:llm:real # real Claude/GPT (needs ANTHROPIC_API_KEY/OPENAI_API_KEY)
# v2.0 full stack — web UI + agent admission + tasks panel
pnpm demo:open-space
pnpm demo:federated-team # one Hub joins another Hub as a single agentBeyond the pattern demos above, five examples/ cases are complete, copy-able hubs —
each ships a deterministic no-key demo and a one-file loadable template (agents + workflows
- KB wiring). Three personal ("我的 AI 桌面"), two organization (team-mode):
# personal hubs (router LLM orchestrates sub-agents / CLIs)
pnpm demo:personal-coding-hub # routes Claude Code + Codex on a shared repo
pnpm demo:personal-research-hub # compiles raw sources into a linked Obsidian wiki
pnpm demo:battle-monk-training # a growth coach writing state into a persistent Codex
# organization hubs (declarative workflows + surface.me self-service + human: HITL approval)
pnpm demo:cafe-ops # 奶茶/咖啡店: onboarding / shifts / overtime, manager approves
pnpm demo:warband-club # a fan club collaborating over one shared archivePick one, see the deterministic demo, then go live with real DeepSeek + Obsidian —
the full catalog and go-live runbook is docs/zh/HANDS-ON-HUBS.md.
import { Hub, Space } from '@gotong/core'
// v2.0: bind to a directory; admins, workers, transcript all live here
const { space, adminToken } = await Space.openOrInit('.gotong', {
name: 'my-space',
adminDisplayName: 'Operator',
})
console.log(`Admin URL once: http://localhost:3000/admin?token=${adminToken}`)
const hub = new Hub({ space })
await hub.start()
hub.register(new MyAgent())
hub.register(new MyHumanAdapter())
const result = await hub.dispatch({
from: 'admin',
strategy: { kind: 'capability', capabilities: ['draft'] },
payload: { topic: 'why TypeScript' },
})
// for tests / in-process demos with no persistence:
const tmp = Hub.inMemory()Host process (the Hub):
import { Hub } from '@gotong/core'
import { serveWebSocket } from '@gotong/transport-ws'
const hub = new Hub()
await hub.start()
await serveWebSocket(hub, { port: 4000 })Worker process (any agent, anywhere):
import { AgentParticipant, connect } from '@gotong/sdk-node'
class MyAgent extends AgentParticipant {
constructor() { super({ id: 'a1', capabilities: ['draft'] }) }
protected async handleTask(task) { return { text: '…' } }
}
await connect({ url: 'ws://hub.example.com:4000', agents: [new MyAgent()] })The Hub's dispatch(...) calls reach the remote agent identically to a local one. See docs/PROTOCOL.md for the wire format and examples/remote-agent for a runnable two-process demo.
The Hub does not call LLMs. LlmAgent does — it's a thin base class that wires a Task into an LlmProvider and turns the response into a TaskResult. Swapping vendors is a one-line change.
import { Hub } from '@gotong/core'
import { LlmAgent } from '@gotong/llm'
import { AnthropicProvider } from '@gotong/llm-anthropic'
import { OpenAIProvider } from '@gotong/llm-openai'
const hub = new Hub()
await hub.start()
// Claude writes drafts
hub.register(new LlmAgent({
id: 'writer',
capabilities: ['draft'],
provider: new AnthropicProvider(), // reads ANTHROPIC_API_KEY
system: 'You write one terse sentence.',
}))
// GPT reviews them
hub.register(new LlmAgent({
id: 'reviewer',
capabilities: ['review'],
provider: new OpenAIProvider(), // reads OPENAI_API_KEY
system: 'You return one revision suggestion.',
}))
const draft = await hub.dispatch({
from: 'system',
strategy: { kind: 'capability', capabilities: ['draft'] },
payload: { topic: 'distributed agents' },
})Override buildRequest(task) to customize prompt assembly (retrieved context, few-shot examples) or parseResponse(response, task) to post-process (JSON extraction, validation re-prompt). Override handleTask(task) for full control — multi-step reasoning, retries, structured outputs. See packages/llm and the two demos in examples/llm-mock and examples/llm-real.
Anchor the hub to a .gotong/ directory; admin identity, worker accounts, and gated agent admissions all live there. Web UI splits into two views (/ worker, /admin admin). Hub restarts are transparent — cookies still work, admins are still admins, transcripts grow rather than restart.
import { Hub, Space } from '@gotong/core'
import { serveWebSocket } from '@gotong/transport-ws'
import { serveWeb } from '@gotong/web'
const { space, adminToken } = await Space.openOrInit('.gotong', {
name: 'my-space',
adminDisplayName: 'Operator',
config: { gating: 'admin-approval' },
})
console.log(`Admin URL once: http://localhost:3000/admin?token=${adminToken}`)
const hub = new Hub({ space })
await hub.start()
await serveWebSocket(hub, { port: 4000, gating: (await space.config()).gating })
await serveWeb(hub, { port: 3000 })
// admin = /admin?token=<TOKEN> | worker = /- Admin signs in once with the token, then drives the room: approve / reject pending agent admissions, dispatch tasks via any of the three strategies, see all tasks in a filterable panel with a Retry button on failed rows, write evaluations attached to specific tasks.
-
Worker picks a nickname + capabilities at
/, becomes aHumanParticipant. Aworkers.jsonrow + an HttpOnly cookie remember them across reloads and restarts. -
Agent connects to the WebSocket port; with
gating: 'admin-approval'they hang in pending until an admin acts.
Full runnable demo in examples/open-space. pnpm demo:open-space spins host + agent in one terminal, then point a browser at the two URLs it prints.
An agent can declare what state it wants the host to keep on its behalf. Three first-party "services" ship today; the plumbing is plugin-from-day-1 so adding a fourth is a separate npm package.
# templates/agents/industry-coach-with-memory.yaml
schema: gotong.agent/v1
agent:
id: industry-coach
capabilities: [intake]
provider: anthropic
model: claude-opus-4-7
system: |
Use memory.recall before answering; artifact.write the report
afterwards; cases.sql for structured industry comparisons.
uses:
- { type: memory, impl: file, config: { kinds: [episodic, semantic] } }
- { type: artifact, impl: file, config: { name: industry-reports } }
- { type: datastore, impl: sqlite, config: { name: cases, schema: "..." } }At spawn time the host resolves each uses: entry to a typed handle
the agent reads from ctx.memory, ctx.artifact, ctx.datastore.<name>.
Owner-based isolation is the default — two agents asking for memory:file
get two different stores. Data layout lives under <space>/services/:
<space>/services/
├─ plugins.json # which plugins to load (auto-seeded)
├─ memory/file/agent/<agentId>/ # one dir per (plugin, owner)
├─ artifact/file/agent/<agentId>/
└─ datastore/sqlite/agent/<agentId>/<name>.sqlite
Soft delete is a click in the admin "服务 / Services" tab; data moves
to per-plugin .trash/, lives 30 days, then a background sweeper
hard-deletes it. Restore is one POST until then. Full design is in
docs/services-rfc.md.
| Package | What it provides |
|---|---|
@gotong/services-sdk |
ServicePlugin contract, registry, loader. The seam plugin authors implement. |
@gotong/service-memory-file |
First-party memory:file — episodic / semantic / working as JSONL. |
@gotong/service-artifact-file |
First-party artifact:file — per-owner directories of files with MIME + size guards. |
@gotong/service-datastore-sqlite |
First-party datastore:sqlite — KV + raw SQL on one .sqlite per declared name. |
// my-plugin/src/index.ts
import type { ServicePlugin } from '@gotong/services-sdk'
class MyPlugin implements ServicePlugin {
readonly type = 'memory'
readonly impl = 'redis'
readonly version = '0.1.0'
async init(ctx) { /* open the redis pool */ }
async validateConfig(raw) { /* parse + reject bad shapes */ }
async attach(owner, config) { /* return a MemoryHandle */ }
async detach(owner) { /* close the per-owner cache */ }
async softDelete(owner) { /* return a TrashRef; the host stores it */ }
async restore(ref) { /* throws TrashRestoreConflictError on collision */ }
async hardDelete(ref) { /* irreversible */ }
async describe(owner) { /* admin UI snapshot — sizeBytes, preview */ }
async shutdown() { /* drain + close */ }
}
export default () => new MyPlugin()Drop the package name into <space>/services/plugins.json and restart
the host — loadPlugins dynamic-imports the entry, calls init, and
the plugin is available to every agent's yaml uses:. Plugin load
failures are non-fatal: a bad plugin shows up in the boot log but
doesn't crash the host.
Deployment note: the host resolves plugin packages from its own
node_modules/, so third-party plugins need to be installed where the host can see them —pnpm add my-org/gotong-redis-memoryin the host workspace, or apackage.jsondependency on the deploy image. Putting the package name inplugins.jsonalone is not enough if the package itself isn't on disk.
| Package | Purpose |
|---|---|
@gotong/core |
Hub, registry, scheduler, transcript, storage, Participant base classes |
@gotong/web |
Embeddable reference UI (HTTP + SSE + vanilla SPA) |
@gotong/host |
Production binary — env-driven, no demo state, ships gotong-host
|
@gotong/protocol |
Wire-protocol types + codec (zero runtime) |
@gotong/transport-ws |
Hub-side WebSocket transport |
@gotong/sdk-node |
Node SDK for remote agents (also exports TeamBridgeAgent) |
@gotong/llm |
LlmAgent base class + LlmProvider interface + MockLlmProvider
|
@gotong/llm-anthropic |
Anthropic Claude provider (peer dep: @anthropic-ai/sdk) |
@gotong/llm-openai |
OpenAI provider (peer dep: openai) |
@gotong/services-sdk |
Hub Services plugin contract (v2.2) — see the section above |
@gotong/service-memory-file |
First-party memory:file plugin (JSONL on disk) |
@gotong/service-artifact-file |
First-party artifact:file plugin (per-owner dirs, MIME-gated) |
@gotong/service-datastore-sqlite |
First-party datastore:sqlite plugin (KV + SQL) |
@gotong/mcp-server |
MCP (Model Context Protocol) bridge — let Claude Desktop / Cursor drive a Hub |
gotong (PyPI, in python-sdk/) |
Python SDK — connect Python agents to a Hub over the same wire protocol |
MIT for the project itself — see LICENSE.
- ✅ Commercial use, closed-source derivatives, internal SaaS embedding — all allowed.
-
⚠️ Retain the LICENSE file + copyright notice in your distribution. - Third-party prompt templates under
templates/community/carry their own (compatible) licenses — CC0 1.0 and MIT — aggregated verbatim intemplates/community/LICENSE-NOTICES.md.
Common questions ("can I embed in closed-source", "do I have to attribute community templates", "is fork+rename allowed") are answered in docs/LICENSE-FAQ.md.