Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
O

OpenTag

> 编程语言
Open source

OpenTag

723 stars0 likes1 views
WebsiteGitHub

About

OpenTag

https://github.com/user-attachments/assets/46fb9854-7540-4756-a33f-fe97810f80d4

The Channels SDK starter application

Channels SDK brings any AG-UI agent into Slack and Microsoft Teams. Its README shows you the pieces. OpenTag is those pieces assembled into something you would actually deploy — and it is built to be taken, not just read.

Clone it Customize it Ship it
A working knowledge-work agent in one quick start: managed Channel, Node runtime, Python LangGraph agent, connected tools, and native Slack UI. The agent, the persona, the tools, and the UI are each one file or one directory. Point it at your own agent without touching the Channel lifecycle. Two Railway services, pinned SDK versions, graceful shutdown, and a live Slack harness — production shape, not demo shape.

Deployment options:

  • Railway: the existing two-service deployment in .railway/railway.ts.
  • AWS: one private ECS Fargate task with Secrets Manager and CloudWatch-to-Datadog log forwarding. See Deploy on AWS.

Release images publish as ghcr.io/copilotkit/opentag-agent and ghcr.io/copilotkit/opentag-runtime.

Slack and Microsoft Teams are supported today. Discord, Telegram, and WhatsApp are coming soon.

See it work

Every frame below is this repository running in a real Slack workspace.

Native UI from a file Approval before a write Research with sources
A .csv becomes a Slack chart and an insight, not a wall of numbers. Linear and Notion writes pause for a human. The button resumes the LangGraph run. Live web research comes back as a table with the links it used.

Quick start

Prerequisites: Node.js 22+, pnpm, Python 3.12, uv, a CopilotKit account, an OpenAI API key, and a Slack workspace you can install an app into.

OpenTag's channel can run two ways:

  1. Managed channel runner — a CopilotKit Intelligence Channel runs the connection and takes care of the durable-data concerns: delivery, state, and concurrency. Free plan available; this quick start uses it.
  2. Your own channel runner — build and operate one on the open-source Channels SDK. See the Channels SDK docs for how to do that.

1. Install dependencies

bash
pnpm install

2. Create the managed Channel

Do this before touching Slack. The Channel is what generates a Slack app manifest already pointed at the right Request URL, so creating the Slack app first means creating the wrong one.

Two ways to do it. Both end in the same place.

Let your coding agent drive it

bash
npx --yes copilotkit@latest channels setup

That installs a channels-setup skill and copies a one-line prompt to your clipboard (--no-clipboard prints it instead). Paste it into your agent:

Use the channels-setup skill to set up a Channel for this project.

The skill is deliberately a pointer rather than a copy of the steps: it fetches its workflow from at run time, so it cannot go stale against the CLI. It covers the whole path — selecting the project, creating and reconciling the Channel, walking you through the Slack console handoff, and proving a real mention gets a reply. It hands every secret back to you; it never asks you to paste one into chat.

It writes .agents/skills/channels-setup and a skills-lock.json, both already gitignored here. Note that it installs to every coding agent it detects with no way to narrow the list. To install for one agent only, use the equivalent command, which takes the same prompt:

bash
npx --yes copilotkit@latest skills onboard --channels --agent claude-code

The skill will also carry you through the rest of this quick start. One thing to watch: its workflow is written for a project starting from nothing, so it has phases for building the agent and writing the Channel runtime. OpenTag already has both — agent/ and server.ts. Point your agent at the existing code to verify and run, not to rewrite.

Or run it yourself

bash
npx --yes copilotkit@latest project select
bash
npx --yes copilotkit@latest channels add --name open-tag --display-name "OpenTag" --adapter slack --json

channels add declares the Channel in .copilotkit/channels.json, creates it on the server, and returns a JSON envelope with one of three states:

  • completed — the adapter is attached. Continue to step 3.
  • blocked — a normal pause waiting on you in the Slack console. Read nextAction: it carries the prefilled manifest link, the exact environment variable names to set, and the resumeCommand to run afterward. This exits 0.
  • failed — stop and read the error code. Do not continue.

--name is a slug and must match INTELLIGENCE_CHANNEL_NAME character for character. If you are running a fork against your own project, pick your own name — see Channel names claim deliveries.

For Microsoft Teams, use --adapter teams. Two Teams steps stay yours because nothing can work around them: granting tenant admin consent, and uploading the app package through Apps → Manage your apps → Upload an app.

Four Slack details that cost the most time

These apply on either path. Follow the CLI's emitted nextAction rather than remembered Slack steps, and watch for:

  • Leave Socket Mode off. Managed delivery never uses it, and a Slack app with Socket Mode on installs green and delivers nothing to the Request URL — so nothing reaches Intelligence and nothing reaches your runtime. It is the one failure here that looks exactly like success. See setup.md.
  • After creating the app from the link, open OAuth & Permissions and choose Reinstall to Workspace. Slack applies the manifest's real scopes only on reinstall.
  • Take the Bot User OAuth Token (xoxb-) from OAuth & Permissions, not the token shown in the app-creation modal, and the Signing Secret from Basic Information → App Credentials. Those two values are all the Slack adapter wants — there is no app-level xapp- token anywhere on this path.
  • The signing secret is reissued on reinstall. If auth fails right after a reinstall, suspect a stale stored secret before a missing scope.

3. Configure the environment

bash
cp .env.example .env

Set:

dotenv
OPENAI_API_KEY=sk-...
AGENT_URL=http://localhost:8123/
INTELLIGENCE_API_KEY=cpk-...
INTELLIGENCE_CHANNEL_NAME=open-tag
# Optional: assign OpenTag Threads to an existing Learning Container.
INTELLIGENCE_LEARNING_CONTAINER_ID=support-quality
# Optional: use another user-facing identity, such as Kite.
AGENT_DISPLAY_NAME=OpenTag

Both the Node runtime and the Python agent load this one root .env; Railway supplies the same values as service variables. Tavily, GitHub, PostHog, Linear, and Notion are optional — see Optional research sources.

INTELLIGENCE_API_URL and INTELLIGENCE_GATEWAY_WS_URL already default to the production Intelligence endpoints in app/env.ts, so leaving them unset is correct.

INTELLIGENCE_LEARNING_CONTAINER_ID is also optional. When set, it must name an existing Learning Container in the project selected by INTELLIGENCE_API_KEY; when omitted, OpenTag does not assign Threads to a Learning Container.

4. Run the stack

bash
pnpm dev

The predev hook syncs the locked Python environment and installs Playwright's Chromium. pnpm dev then runs the Python agent with reload enabled and the Node runtime in watch mode. The runtime waits for its Intelligence connection to become ready before its HTTP listener accepts traffic.

5. Invite the bot

/invite @OpenTag

Installed in the workspace is not the same as present in a conversation. Slack emits no app_mention at all for a channel the app is not a member of, so without this OpenTag looks broken while behaving correctly.

Prove it works

A Channel that installs cleanly and answers nothing is the most expensive failure available here, because it looks finished. Three checks separate the two. Send them from a real human account:

  1. Mention it. @OpenTag what changed in the last deploy? — expect a useful, model-backed reply.
  2. Follow up without mentioning it, in that same thread — expect a reply. A mention subscribes the thread; unmentioned messages run the agent only in already-subscribed threads.
  3. Send an unmentioned message in a fresh conversation — expect silence. A reply here means the trigger rules are wrong.

If any of those fail, in this order:

bash
npx --yes copilotkit@latest channels status --json

It reports declaration, source, server, adapter, environment, and lifecycle diagnostics. Resolve every one. Two of its warnings are expected for OpenTag and are not faults: it flags INTELLIGENCE_API_URL and INTELLIGENCE_GATEWAY_WS_URL as unset because app/env.ts defaults them in code rather than in .env.

bash
LOG_LEVEL=debug pnpm runtime

The runtime logger defaults to error, while every Channel lifecycle breadcrumb is emitted at warn — including channel "" requires setup, the single highest-value diagnostic here. At the default level it is written and discarded.

Note that the runtime does not hot-reload Channel wiring. After editing a handler, the agent, or the Channel, restart the process and confirm online again before retesting. A stale process answering with the old behavior is indistinguishable from a change that did not work.

Channel names claim deliveries

Managed delivery is claim-based: two runtimes declaring the same Channel name in the same Intelligence project race per delivery, and the loser silently receives nothing. The tell is a Slack reply your terminal knows nothing about.

INTELLIGENCE_CHANNEL_NAME defaults to open-tag, whic

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

TypeScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言