Part of Amplifier Constellation.
Give an existing ACP agent its own Slack presence. Install one independent connector per Slack app, connect it to the agent's ACP endpoint, and invite that app into conversations. Slack owns the conversations; the agent owns its identity, instructions, tools and durable agent state.
This is a separate executable, installation folder and service. It can be used through its CLI, configuration files, HTTPS management API, or packaged browser interface. It does not require a fleet manager, Agent Instance, or the earlier workshop implementation.
Slack app ← Socket Mode → this connector ← standard ACP stdio → your agent
↑
optional management API + UI
Linux is the supported service host in this release. Windows, Mac, Linux, iOS and Android can use the browser interface and Slack clients. Native Windows/macOS service installation is future work.
Install Git, then clone the public source:
git clone https://github.com/microsoft/amplifier-acp-slack.git
cd amplifier-acp-slack
./install.sh --label "My agent"The installer builds a pinned dependency set, installs missing build prerequisites on apt-based Linux, installs a PAM policy if needed, copies its executable into a new private folder, and starts an unconfigured user service. It prints the URL and opens it when a local desktop is available. Existing folders are never silently overwritten. Python 3, systemd, and GitHub access are bootstrap requirements.
For an agent already installed with Agent Instance, the optional convenience flag prefills its ordinary ACP entrypoint and working directory:
./install.sh --label Helper \
--home "$HOME/.local/share/acp-slack-adapter/helper" \
--agent-home "$HOME/.local/share/agent-instance/first-agent"For another ACP implementation, enter its launch command, arguments, and working directory during setup. The agent must already be installed and authenticated. The connector neither copies its profile nor installs a replacement agent.
The random management port becomes stable after first startup. --port overrides
it; --bind defaults to LAN access. --public-url advertises an already-configured
HTTPS reverse proxy, including Tailscale Serve. It does not create that proxy.
Direct LAN HTTPS uses a private per-installation CA; /certificate/root.crt
downloads its public certificate. Prefer a trusted HTTPS hostname when available.
PAM sign-in uses the account that installed this connector. Passwords never travel
over an HTTP management listener.
Supported Slack attachments now become capability-checked ACP content, and native ACP image/audio/document outputs can become Slack files. See media behavior and limits. Existing Slack apps need the added files:read and files:write permissions authorized. The OpenCode validation demonstrates a genuinely independent ACP implementation through this adapter with real model turns and no live Slack posts.
- Open the printed URL and sign in. The installed agent is already selected.
- Choose Connect to Slack. Copy the short command into a conversation in your Slack workspace, approve Slack’s request, and enter its confirmation code here.
- The connector creates the agent’s app, obtains its message credentials, checks the ACP connection, and starts listening. Image updates use the same authorization.
- Invite the agent into a channel or open its direct messages.
Workspace app approval policies still apply. An administrator may need to approve installation. Each connector keeps its own authorization and renewal state; no shared Constellation service is involved. The first authorization downloads a checksum-verified Slack CLI into this installation. Python 3 and access to GitHub and Slack are required. The installed agent remains a standard ACP endpoint.
Advanced: use existing app credentials retains the manual manifest/token path. Existing connections keep their apps, credentials, and conversations. They can use Connect image updates when image access is missing, without reinstalling the app. Healthy connections show status and Open in Slack; additional controls live under Settings → Advanced. See onboarding for the flow and boundaries.
Enable Conversation context tools under Settings → Advanced to give an agent read-only navigation between a conversation, its parent messages, and thread replies. The connector supplies a small orientation on each turn and standard HTTP MCP tools when the ACP agent advertises support. A reachable, trusted HTTPS public URL is required for the agent host to call back.
An optional owner Slack member ID links the installation owner to their Slack identity. In that person's verified one-to-one DM, context can include channels both the owner and bot can access. Group conversations remain within their current channel. Another person's DM never joins the owner's context. Access is checked against Slack on retrieval, and source links and coverage accompany results.
To carry context into other experiences, register this provider with an agent
that supports the optional agent-instance.context/1 contract. Its provider ID
is slack:<connector-id>, base URL is the connector's public URL, and its scoped
credential has context access. The agent calls /context/v1/query; standard
ACP clients receive tools through ordinary MCP session setup. The optional
io.github.bkrabach.conversation ACP metadata passes a temporary audience grant,
never a Slack credential. Agents without that extension can still use the
connector's ordinary MCP tools within Slack.
Reading another conversation does not change where a reply is delivered. Agents and connectors do not read each other's databases. This is source retrieval, not an automatic merge of all sessions or a durable preference-memory system. See the continuity design for the contract and remaining work.
Slack Socket Mode makes an outbound connection, so Slack does not need a public URL to your machine. Slack Socket Mode
acp-slack-adapter --home /path/to/connection status
acp-slack-adapter --home /path/to/connection check --target all
acp-slack-adapter --home /path/to/connection stop
acp-slack-adapter --home /path/to/connection start
acp-slack-adapter --home /path/to/connection config get
acp-slack-adapter --home /path/to/connection api GET descriptor
acp-slack-adapter --home /path/to/connection api GET activity
acp-slack-adapter --home /path/to/connection api POST views --body-file view.jsonapi METHOD PATH --body-file FILE exposes the same operations as the UI, including
its display state. Credential values belong in private input files or password
fields, never command arguments. secret NAME --file FILE writes a named ACP
environment secret; acp.secret_env maps environment variables to those names.
Use config set --file FILE for online revision-checked updates. --offline is
available only while the service is stopped. Once a connection has been used,
changing the Slack identity or ACP endpoint requires another installation so an
unrelated agent cannot inherit its transcripts accidentally. Upgrading an agent
behind an unchanged entrypoint remains independent of this connector.
- Standard ACP initialization, session creation, prompt delivery and optional session loading. Generic ACP agents can return normal text in addressed mode.
- Independent sessions for simultaneous rooms/threads. If the agent cannot reload sessions, each invocation receives only that conversation's bounded Slack view.
- Persist-before-ack ingestion, event/message deduplication, self-echo suppression, per-conversation serialization, and bounded parallel conversations.
- Source edits, deletes and changed conversation scope are checked before delivery. A changed conversation can be reconsidered without silently losing an addressed request. Previously performed actions must not be blindly repeated.
- Explicit rate-limit retry. An ambiguous send is marked uncertain, not automatically retried. A matching Slack echo can confirm it. There is no exactly-once guarantee for external tool effects or a send already in flight when configuration changes.
- Meaningful activity and delivery outcomes. UI polling, draft updates and render acknowledgements do not fill the activity feed.
The connector supports interactive permissions and optional local client tools.
The single approval policy, acp.client.approvals_required, defaults to true.
The human who initiated a live turn can review and allow or deny its single-use
ACP tool requests in Slack, without a separate acp.client.approval_users list.
The connector owner can also explicitly decide through its dashboard/API using
separate administrator authority. Turning the policy off automatically selects
an advertised allow_once option for each eligible tool request and records the
decision without posting an approval card. It does not grant persistent permission,
supply credentials, enable client tools, or bypass agent/tool/service restrictions.
Sign-in and clarification questions still require interaction.
Filesystem and isolated Linux terminal callbacks are opt-in and bounded to local workspace roots. Agent-owned tools remain subject to the chosen agent's policy. Supported attachments are translated between Slack files and ACP content within the media capabilities and limits. Proactive cross-room posting is not implemented; this is not a general Slack automation API. Process/folder independence under one OS account does not isolate a hostile agent implementation.
Codex compatibility records two independent upstream Codex instances working through this connector without Agent Instance, including actual Slack tool tasks, restored sessions, concurrent rooms and the remaining client-capability limits.
Architecture and management boundary explains discovery, scoped access, embedding and semantic UI control. Validation records real process, browser, PAM and optional live-agent checks. The future fleet experience can attach to these interfaces; neither the agent nor connector needs that experience to keep working.
Note
This project is not currently accepting external contributions, but we're actively working toward opening this up. We value community input and look forward to collaborating in the future. For now, feel free to fork and experiment!
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit Contributor License Agreements.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
Ordinary ACP form and URL questions, including clarification and sign-in prompts,
appear as a Respond privately control regardless of
acp.client.approvals_required. Only the human who initiated the live turn can
open and answer its Slack dialog; no acp.client.approval_users list is required.
Other channel members see no question contents or answers. Automatic tool approval
does not answer questions or complete sign-in.
The operator may also inspect GET /api/v1/questions and explicitly answer via
POST /api/v1/questions/{id}/decision with {action, content?} using the separate
admin credential. That is recorded as an operator decision, not impersonation.
Supported agent login methods run on the same ACP connection and retry session setup once after explicit choice. Provider pages open only on a click; opening a page is consent, not proof of completed authentication. Terminal-only methods remain a host sign-in step. Prompts are never retried for authentication.
Question bodies and responses are memory-only. Cancellation, source edits, config changes, timeout, or process exit invalidate them. Controls are bound to the workspace, app, initiating person, message, and opened dialog. Slack limits on fields, choices, and URL length are enforced before display; unsupported schemas are rejected instead of silently dropping constraints. Secret inputs belong on the provider's page. Setup callbacks must use the current request ID or an already established session ID; tool-scoped questions require a known tool.
Validation uses independent ACP peers and a local Socket Mode service, including login, URL opening, typed answers, wrong-user/view rejection, invalid input and transcript isolation. Live Slack UI confirmation is a separate check.
Automatic Slack app portraits from compatible agents: agent images.
Verified, installation-local updates are available for Linux systemd installations. See Updating one Slack connector for the CLI, management API, and optional owner-DM agent controls.
Bounded agent collaboration and durable delivery waits: collaboration waits.