Slack bot: multiple @-mentionable identities backed by mecatl agent definitions
@kantord is already working on this.
Since Sep 3, 2026.
- Dominant language
- Go
- Stars
- 152
- Forks
- 16
- Avg merge
- 14h 48m
- Merged PRs (30d)
- 536
Description
Summary
Explore letting the Slack bot example (#883) spawn multiple, independently @mention-able bot identities in a workspace — one per mecatl agent definition (.mecatl/agents/*.md / .claude/agents/*.md) — instead of a single fixed identity. E.g. @foobar and @barbaz each respond as their own named persona, backed by the same self-hosted bot process.
Came out of a design discussion while building #883; genuinely bigger than that issue's scope, tracked separately.
Why this needs more than Slack-side plumbing
Confirmed live (see #883's DESIGN.md for the discipline this repo now uses — verify Slack platform claims before relying on them):
- A single Slack app has exactly one bot user / one
@mentionhandle.chat:write.customizeonly changes a posted message's display name/avatar — it does not create a separately-taggable identity. Multiple identities need multiple Slack apps. - Slack does support creating apps programmatically:
apps.manifest.create(scopeapp_configurations:write) can create a new app — new bot user, new credentials — without a human clicking "Create New App" each time. - Two distinct mechanisms exist here, confirmed against Slack's own docs:
- Self-serve, no gating: a human generates a personal App Configuration Token (12h TTL, refreshable via
tooling.tokens.rotate) and callsapps.manifest.createdirectly. Works today, no Slack approval, for a single operator managing their own workspace(s) — our use case. - Gated "manager app" model (
invalid_manager_app,managed_app_limit_reachederrors, confirmed real): an installed app itself creating child apps across many different customers' workspaces at scale (the SaaS/ISV pattern — e.g. reportedly how NanoClaw/LangChain Fleet work). Needs Slack to enable "manager app support" on the calling app's home team; no documented self-serve enrollment found. Not needed for this issue's scope (single-operator, self-hosted), but relevant if this ever became a hosted product.
- Self-serve, no gating: a human generates a personal App Configuration Token (12h TTL, refreshable via
Separately, mecatl itself has no concept of a top-level session running "as" a named agent definition today. An AgentDef (name, model pin, memory, MCP servers, limits) is only reachable as a delegated subagent (the Subagent tool's agent: parameter) — there's no agent field on CreateSessionRequest/sessions.create(). Without that, there's no clean way to make a whole Slack-bot-identity's session actually be that persona (model pin, catalog, prompt) rather than just its written description pasted into a prompt.
Proposed shape (draft, needs its own design pass before implementation)
- mecatl-core + SDK: top-level sessions pinned to an
AgentDef. ExtendCreateSessionRequest/sessions.create()with anagent: <name>selector, reusing the existingbuildAgentDefEnginescoped-engine construction (model/catalog/prompt/memory/limits) already built for the Subagent-delegation case — routing it through session creation instead of only reachable via delegation. Proto/contract regen (task generate),engine/api/*.txtupdate if the surface is core-facing. - Slack-facing metadata on the
AgentDef(display name, avatar). Open question, unverified: can an avatar actually be set programmatically for aapps.manifest.create-created app? Slack's manifest schema appeared to have no icon field when checked manually via the dashboard for #883 — if that holds for manifest-created apps too, avatar-setting needs a separate, currently-unidentified API call. - Expose the new
agentsession-create field through@stacklok/mecatl-sdk— straightforward follow-on to (1). - A reconciliation loop (k8s-operator-style: diff desired state — AgentDefs carrying Slack identity metadata — against existing child Slack apps; create missing, retire removed) in the Slack bot example itself, or a small standalone tool.
- Credential storage:
apps.manifest.createreturnsclient_id/client_secret/signing_secretonce — needs a durable, encrypted-at-rest store per identity, not just in-memory. - Delete is destructive: default to stopping the identity's Socket Mode connection rather than calling
apps.manifest.delete, unless hard teardown is explicitly wanted. - Open question, unverified: does
apps.manifest.createalone yield a usable bot token, or is a follow-up OAuth-install step still required per child app (even if scriptable)? This directly bounds how automated step 4 can actually be.
- Credential storage:
Non-goals (for now)
- The gated "manager app" / multi-workspace SaaS model — out of scope unless this becomes a hosted product later.
- Any change to the existing single-identity Slack bot in #883 — this is additive, not a replacement.
See also
- #883 (the single-identity Slack bot example this grew out of) — its
DESIGN.mdhas the live-verification discipline this issue should follow before implementing. - #882, #881, #821 (the SDK/plan/umbrella chain #883 traces to)
Fully or partially written by an AI agent.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.