stacklok / stacklok/mecatl

Slack bot: multiple @-mentionable identities backed by mecatl agent definitions

Open
#1,053 0 comments 0 reactions 1 assignee View on GitHub

@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 @mention handle. chat:write.customize only 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 (scope app_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 calls apps.manifest.create directly. 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_reached errors, 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.

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)

  1. mecatl-core + SDK: top-level sessions pinned to an AgentDef. Extend CreateSessionRequest/sessions.create() with an agent: <name> selector, reusing the existing buildAgentDefEngine scoped-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/*.txt update if the surface is core-facing.
  2. Slack-facing metadata on the AgentDef (display name, avatar). Open question, unverified: can an avatar actually be set programmatically for a apps.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.
  3. Expose the new agent session-create field through @stacklok/mecatl-sdk — straightforward follow-on to (1).
  4. 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.create returns client_id/client_secret/signing_secret once — 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.create alone 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.

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.md has 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.