## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat connectors let people start and continue agent tasks from other services. > - A Slack conversation needs access to its surrounding discussion and Slack collaboration tools. > - The agent must use the linked requester's access and keep private material within its permitted audience. > - This pull request adds Slack tools through the existing connector contribution and approval framework. > - People can ask an invited bot to read a discussion, create follow-up tasks, and collaborate in Slack. ## Linked Issues or Issue Description **Subsystem affected** Chat connectors, connector runtime, tool gateway, and connection Settings/Access. **Problem or motivation** Slack-origin tasks can receive messages but cannot inspect the rest of a channel or act through the originating bot. People must paste context or configure a separate integration. **Proposed solution** Supply typed Slack tools and a bundled skill only to the originating task and assigned agent. Resolve the linked requester on the server. Check bot and requester access before reads and writes. Use existing durable actions and approvals. Retrieved messages remain source material. **Alternatives considered** Slack's user-OAuth MCP server does not replace the customer-created chat bot. An unrestricted Web API proxy would not provide suitable permission or publication boundaries. **Roadmap alignment** This extends the existing MCP Tool Gateway & Apps work with a provider contribution. It does not add a task dispatcher or a separate Slack task lifecycle. Related: #11144 covers generic per-user MCP grant execution; this change binds Slack bot operations to chat-origin tasks. ## What Changed - Add 39 typed Slack tools, a method/scope matrix, a bundled skill, and shared native/HTTP execution. - Bind tools to company, endpoint, task, run, assigned agent, and admitted linked requester. Check membership and revocation on each call and before queued writes. - Add paginated reads, bounded history search, source links, messages, file uploads, reactions, pins, bookmarks, topics, canvases, lists, and approved channel operations. - Restrict private-source publication, including automatic replies and uploaded deliverables. Keep other people's bot DMs inaccessible. - Reuse action receipts, idempotency, approvals, and reconciliation. Suppress an identical explicit-send/final-reply duplicate. Return governed results through their verified originating conversation. - Add endpoint-bound personal search OAuth storage and lifecycle. Keep native real-time search disabled until a runtime meets Slack's transient-result requirements. Current runtimes use bounded history search. - Show capabilities, scope upgrades, and personal search authorization in Settings/Access and Storybook. Document provider and runtime limits. ## Verification - Current head `0eb21cba4`: CI checks pass and Greptile is 5/5 with no unresolved findings. One unchanged rapid-callback timing test passed on a single CI retry. - Approval presentation regressions cover board-comment precedence and exact Slack publication; the expanded database assertion passed in CI. The local PostgreSQL startup probe later became unavailable, so that final assertion was verified in CI. Slack setup and failed-run retry browser tests also passed locally. - Full workspace typecheck and build passed. Server typecheck/build passed again after the approval routing fix. - Broad local suites passed in separate groups: server 12,958 tests, UI 6,555, shared 770, skills catalog 20, and other workspace packages 2,652. CLI and serialized server checks passed after environment/timeout retries. These are composite results, not one uninterrupted green full-suite invocation. - PostgreSQL authority regression covers admitted identity, cross-company/task/agent rejection, recovery, retained-session revocation, OAuth refresh/disconnect races, approval execution, exact publication lineage, retries, uncertain sends, and duplicate suppression. - Gateway/response regressions cover separate-origin approval batches and durable continuation. Focused provider, access, search, native runtime, route, and AgentMail regressions pass. - Storybook capability, missing-scope, OAuth configuration, authorization, and disconnect states were inspected in the browser. - Live staging: read a channel decision and full thread, create exactly two assigned backlog tasks, add a reaction, paginate discovery to exhaustion, and return bounded search matches with source links and coverage. - Live staging: create/edit/read a canvas and list, inspect the canvas in Slack, post/edit one message, and create a channel only after approval. New channels remain disabled for responses. - Live staging: read a response-disabled channel from the requester's DM; writes to that channel were denied. The test setting was restored. - Final live retest passed: explicit file upload and exact content read-back; approved deletion of only the disposable bot message; continuation confirmation returned to the original Slack thread without repeating the action. - Optional OAuth, private multi-user boundaries, native RTS, and CLI provider execution are not fully live-qualified. The staging agent initially supplied malformed tool arguments; valid arguments succeeded, and the tool/skill descriptions now emphasize UUID write keys. ## Risks - Existing Slack apps must add scopes and reinstall for new capabilities. Provider plans and document permissions can still restrict operations. - Instances need an independent `PAPERCLIP_TOOL_ACTION_SIGNING_SECRET` for governed tool actions. The staging instance was configured with explicit operator approval; fleet provisioning is a separate gap. - Native RTS is not exposed on current transcript-retaining runtimes. Bounded history scans are deliberately reported as incomplete. Inline file reads support text/canvas content up to 256 KiB; other types return metadata. - Private document edits fail closed when the full audience cannot be verified. Uncertain effects other than posts/uploads require inspection instead of blind retries. - Shared approval-delivery code now separates outcomes by source run to preserve origin boundaries. No database migration is required. - A separate completion-validator gap remains when the agent cites a prior run's registered artifact during finalization. It asked for registration again even though Slack delivery was confirmed. This change does not add a connector-specific task-completion policy. ## Model Used OpenAI GPT-6 through Codex, with repository tools, code execution, and browser testing. The exact deployed model identifier and context-window size were not exposed in the session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
8.1 KiB
Slack tools for Slack-origin tasks
A linked person can mention the bot and ask it to read the discussion, summarize decisions, and create assigned follow-up tasks. Task creation, assignment, approvals, and completion remain normal Paperclip operations. Slack contributes provider tools and a bundled skill; it does not introduce another task lifecycle.
Authority and channel access
The controller resolves company, endpoint, assigned agent, task, run, and accepted linked requester from the admitted Slack event and immutable run identity context. Tool arguments cannot supply those identities or credentials. Recovery can follow the original context within the same task and agent. A new board-authored request cannot inherit an earlier Slack sender's authority.
Reads require current bot membership and requester access. Full workspace members can read public channels where the bot belongs; guests, private channels and Slack Connect conversations require verified requester membership. Membership checks paginate and fail closed. Other people's bot DMs are never exposed.
Allowed Channels controls responses and writes, not reads. Invite the bot to another shared channel to make it readable without enabling responses there. Retrieved messages, files, names, topics, canvases and list records are source material. Unlinked participants cannot start work, approve actions or grant access.
Private-source markers are recorded before returning private content. They restrict both explicit tool writes and automatic publications, including uploads. Research across private channels must originate in the requester's DM. Private material can be published only in its source channel or that requester's DM. Shared document edits after private research fail closed because Slack does not provide a complete sharing audience through file metadata; use a message or upload instead.
Each call rechecks live authority. Queued writes recheck again before transport. Authorization and capability revisions participate in session compatibility and signed approvals. Removing a tool profile binding does not get undone by resolving a retained session. Disconnecting an identity or disabling a connection revokes access for retained runs too.
Tools and scope upgrades
The reviewed, strict method/scope/argument matrix is
packages/shared/src/slack-tools.ts.
It is the source for tool descriptors, validation, policy catalog and Storybook.
There is no arbitrary Slack method executor, user impersonation or workspace-admin
tool. User search credentials never authorize writes.
- Discovery: channels, channel details, members, user identities and emoji.
- Reading: paginated history, threads, individual messages, source links and linked files. Text files up to 256 KiB are available inline. Other files return metadata with an explicit limitation; do not claim their contents were read.
- Search: bounded channel history by text, author and time. File mode matches linked filenames/titles, not file contents. Coverage includes page cursors, inspected time bounds and omitted matches. Use the returned continuation time if matching results were truncated. Thread replies require separate reads.
- Collaboration: bot messages/replies, edits to its own messages, task-attachment uploads (up to 20 MiB), reactions, pins, bookmarks, topics and purposes.
- Documents: canvas creation, text reading, section lookup and edits; bot-owned lists, text records, renaming and approved channel sharing. Slack plan and document permissions apply. Lists need a separate approved share before others can use them.
- Governed actions: deleting the bot's messages, deleting bookmarks, creating channels, inviting people and granting list access require approval. New channels remain disabled for ongoing responses. The bot cannot join an existing channel, invite itself or enable a destination.
New manifests request collaboration scopes. Existing bots keep their current permissions and Settings identifies missing scopes. Add them under OAuth & Permissions → Bot Token Scopes in Slack and reinstall the app. Scope possession alone is not a guarantee: Slack feature availability, destination access and Paperclip per-action policy still apply.
Delivery and retry behavior
Native and HTTP tool calls pass through the same existing policy/approval gateway. Mutations receive durable action receipts. Idempotency keys are scoped to company, connection, task and requester, and cannot be reused with different arguments.
Ordinary writes rejected by Slack with a definite rate limit can retry with the
same arguments and key after Retry-After, during the same authorized run. Policy
and current access are checked again. An uncertain transport outcome is never
blindly resent. slack_delivery reconciles posts by their client message ID and
uploads by their recorded file ID; unresolved operations remain uncertain.
An identical automatic final response is suppressed after an explicit send, or
held while that send's delivery remains unresolved. Distinct summaries, progress,
questions and blockers continue through existing routing.
Optional personal search authorization
Connection managers may configure the Slack application's Client ID and Client
Secret in Access. Register the displayed HTTPS callback URL and user scopes
search:read.public, search:read.private and search:read.files in Slack.
A linked person can then connect or disconnect their own search grant. State,
secret bindings, refresh and grants reuse the existing connection infrastructure.
Grants bind company, endpoint, Slack workspace, linked Slack identity and app
configuration revision. Concurrent disconnect invalidates in-flight callbacks.
No DM-search scopes are requested.
Native RTS search is not enabled on current runtimes. Slack's Real-time Search API requires transient handling of retrieved data. Current native and CLI/sandbox runtimes retain tool transcripts. The provider implementation and search-only OAuth flow are present, but RTS results must not enter the ordinary gateway until an entire runtime/provider path is qualified: no raw results in logs, model transcripts, replay snapshots, indexes or artifacts. Recovery must re-fetch. Access displays this limitation even when a personal grant is connected.
The transient provider implementation uses the verified event's short-lived, memory-only action token for bot searches, and optional personal OAuth for private search. It checks every returned workspace/channel/user/date and verifies file shares with the bot's credentials. Model-authored modifiers are not an access boundary. Slack limits RTS to internal or directory-published apps and applies separate search and plan limits. Bounded history remains available without OAuth.
Native and CLI execution
The connector runtime contributes tools only to verified Slack tasks. The bundled
skills/slack/SKILL.md and generated adjacent
TOOLS.json provide the equivalent HTTP interface for CLI/sandbox adapters:
POST /api/companies/:companyId/slack/tasks/:issueId/tools
Authorization: Bearer <agent run key>
X-Paperclip-Run-Id: <run ID>
{"tool":"slack_history","arguments":{"channel":"C123","limit":50}}
Company/task path parameters are checked against the authenticated run and admitted request. Bot and OAuth secrets stay server-side. Other providers and the separate Slack MCP connection retain their existing behavior.
Verification
Automated coverage includes admitted-request binding and recovery, wrong company, agent and task, revocation, approval after a run completes, missing scopes, membership pagination, private publication boundaries, rate-limit retries, uncertain delivery, OAuth refresh and disconnect races. Native RTS provider tests use fixtures; they do not qualify production transcript handling.
Storybook: Connections → Slack → Task tools includes capabilities, permission upgrades, OAuth configuration, connect and connected states. Live staging evidence and outstanding limitations are tracked in the dated implementation checklist.