Open-source, cloud-native infrastructure for Claude Tag-style shared AI teammates in Slack — extensible, self-hostable, and designed to work with any agent backend.
Inspired by the Claude Tag pattern: instead of a private chatbot per person, a Slack channel gets one shared teammate that everyone can tag, watch, redirect, and hand work to.
OpenTag owns the Slack collaboration layer mapping Slack teams, channels, threads, and users into agent routing decisions, thread sessions, shared-vs-personal identities, workspace policy, and Slack-native audit records.
OpenTag delegates cloud-native agent execution to kagent, which already runs any model (OpenAI, Anthropic, Gemini, Bedrock, Ollama, …), any agent framework (ADK, CrewAI, LangGraph, or bring-your-own), A2A, memory, tools, and observability. A small, backend-agnostic interface keeps the door open to other agent platforms beyond kagent later.
Status: alpha (intentionally — see the roadmap). Channel mentions, DMs, channel-scoped memory, background tasks, and proactive routines work today.
Claude Tag popularized the "shared AI teammate in a Slack channel" model. OpenTag brings that interaction model to open, cloud-native, self-hostable infrastructure with pluggable agent backends. It keeps the Slack-side collaboration contract explicit — which channel may use which agent, which Slack thread maps to which agent session, whether a channel uses shared memory, and what Slack-native audit record is written — while kagent handles the cloud-native agent runtime underneath.
- Shared Slack teammate — one
@OpenTagper channel, not one bot per person - Thread-scoped sessions — each thread is its own coherent conversation
- Channel-scoped service identity — anyone can pick up a teammate's thread
- Personal identity for DMs — direct messages run as the individual user
- Channel-scoped memory — the teammate remembers a channel over time
- Background tasks — delegate long work; results post back to the thread
- Proactive routines — scheduled prompts that post results unprompted
- Any model & agent framework — via kagent (OpenAI, Anthropic, Gemini, Bedrock, Ollama; ADK, CrewAI, LangGraph, BYO) today; pluggable for other agent platforms later
- Governance controls — default-deny routing, DM policy, per-channel turn caps
- JSONL audit trail — who asked, which agent ran, the outcome
- Cloud-native deployment — container image + Helm chart
- Extensible — kagent fully supports the MCP protocol, which allows you to use tools from any MCP server.
| OpenTag | Managed Claude Tag-style | |
|---|---|---|
| Shared Slack teammate | ✓ | ✓ |
| Open source | ✓ | ✗ |
| Self-hostable | ✓ | ✗ |
| Any model / agent framework | ✓ (via kagent) | limited |
| Cloud-native self-hosting | ✓ | managed only |
| Extensible runtime | ✓ | limited |
| Governance + audit | ✓ | ✓ |
Comparison reflects OpenTag's current and near-term scope; see the roadmap for what's shipped vs. planned.
Slack (Socket Mode)
│ @OpenTag mention (in a thread) / DM
▼
ChatProvider ──► core ──► AgentBackend (kagent)
├─ Slack routing channel → kagent agent
├─ Slack identity channel service ID / DM user ID
├─ thread sessions Slack thread → kagent contextID
├─ Slack governance default-deny, DM policy, turn caps
└─ Slack audit user/channel/thread → outcome
Identity is per channel, work is per thread:
| Behavior | How it works |
|---|---|
| One teammate per channel | a ChannelBinding → one kagent agent + one org service identity |
| Work happens in a thread | one kagent session per Slack thread (contextID = hash(team,channel,threadTS)) |
| Channel mention vs DM | channel → org service identity; DM → the user's personal identity |
| Delegate & walk away | long tasks are tracked in the background and posted back to the thread when done |
| Proactive teammate | scheduled routines run a prompt and post results without being asked |
| Spend caps + audit | best-effort per-channel turn meter + JSONL audit trail |
A channel mention runs under a shared service identity, so anyone in the channel can pick up a thread someone else started, while each thread stays its own coherent session.
OpenTag gets channel-scoped memory for free from this identity model. kagent
keys an agent's memory by (agent, user_id), and every mention in a channel runs
under the same user_id (the channel service identity) against the same
agent — so facts the agent learns in one thread are available in others, and
persist across restarts (kagent stores them).
Two things to know:
- The bound agent must have memory enabled — i.e. configured with kagent's memory tools and an embedding config. kagent generates the embeddings and does recall/save itself; OpenTag does not run an embedder.
sharedMemory(per binding, defaulttrue) controls the lever OpenTag owns:trueshares one identity across the whole channel (cross-thread memory);falseisolates each thread.
- Delegate and walk away. If a request doesn't finish inline, OpenTag tracks the task and posts the result back into the thread when it completes.
- Routines run a prompt on an interval and post the result to a channel
without anyone asking (see
routinesin the config). - Manage standing work from Slack:
@OpenTag triggers(orstatus) — list the channel's running tasks and routines.@OpenTag stop <id>— cancel a task or routine by id.
- Go 1.26+
- A reachable kagent server (its
/api/a2a,/api/sessionsendpoints) - A Slack app with Socket Mode enabled
Point OpenTag at any kagent server. For local dev, port-forward it:
kubectl port-forward -n kagent svc/kagent 8083:8083
# sanity check an agent's A2A card:
curl http://localhost:8083/api/a2a/<namespace>/<name>/.well-known/agent-card.jsonCreate an app from the ready-made manifest at
examples/slack-app-manifest.yaml
(https://api.slack.com/apps → "Create New App" → "From a manifest"). Then:
- Install the app to your workspace; copy the Bot User OAuth Token (
xoxb-…). - Generate an App-Level Token with
connections:write(xapp-…). - Invite the bot to a channel and note the channel id.
cp config.example.yaml config.yaml # edit bindings + org id
export SLACK_APP_TOKEN=xapp-...
export SLACK_BOT_TOKEN=xoxb-...
make run # or: go run ./cmd/opentag -config config.yamlIn Slack: @OpenTag summarize the open incidents — OpenTag opens a thread, runs
the bound kagent agent, and streams the reply. Anyone in the channel can reply
in that thread to continue the same session.
A Helm chart lives in deploy/helm/opentag. It renders your config into a
ConfigMap and injects the Slack tokens from a Secret:
helm install opentag deploy/helm/opentag \
--set slack.appToken=$SLACK_APP_TOKEN \
--set slack.botToken=$SLACK_BOT_TOKEN \
--set config.kagent.baseURL=http://kagent.kagent.svc.cluster.local:8083 \
--set config.org.id=acmeSet existingSecret to use a Secret you manage (keys appToken, botToken),
and put bindings/routines under config.* (see values.yaml).
make test
make vet
make buildSee CONTRIBUTING.md for the contribution workflow.
Apache-2.0. See LICENSE.
OpenTag is an independent open-source project. It is not affiliated with, sponsored by, or endorsed by Anthropic. "Claude Tag" is referenced only to describe the shared-AI-teammate interaction pattern OpenTag is inspired by; any trademarks are the property of their respective owners.
