Architecting Claude in Slack, with Salesforce at the center
Architecture decisions behind a Slack assistant connecting team conversations, Google Drive, and Salesforce work.

We recently installed the Salesforce connector in Claude. That gave us a way to work with Salesforce information inside a Claude conversation, but it also raised a practical question: what about the teammates who spend more of their day in Slack?
Our team needed a shared place to understand project context, collaborate on decisions, and initiate work. Salesforce remains where that work is managed. Google Drive holds supporting documents. Slack is where many of the conversations happen.
Moving everyone into another application for AI assistance would leave that split largely intact. We wanted Claude available where the team was already discussing the work, with connections to the systems that explain and record it.
That led us to a custom Slack Bolt application.
The app is still in development, with an early pilot expected soon. This is an account of its architecture and the reasons behind it, not a report of measured productivity gains.
Keep Salesforce responsible for the work
The starting decision was to extend the team’s workflow without creating another place to manage project records.
Slack provides the conversation and interaction layer. Claude helps interpret requests and assemble relevant information. Google Drive supplies document context. Salesforce remains the system of record for the work itself.
A work item initiated in Slack should become a Salesforce record. It should not exist only as a convincing message from an assistant.
That distinction shapes the integrations. The app supports conversational assistance, but it also adds slash commands and forms for specific work-related actions. A teammate can ask for project context in a thread, then use a structured interaction to create a work item for delegation.
The goal is to reduce the distance between discussing work and recording it, while preserving the ownership and tracking that already exist in Salesforce.
Put Bolt at the boundary, not at the center of every decision
Slack Bolt handles the Slack-facing part of the application: mentions, direct messages, thread follow-ups, commands, and interactive views.
Behind that interface sits an agent runtime. It manages the conversation with Claude, handles tool requests, records the turn, and decides whether to continue or stop.
The major responsibilities are separated:
- The Slack adapter receives interactions and routes them into sessions.
- The runtime coordinates model calls and tool execution.
- The model provider supplies Claude’s responses and tool requests.
- The tool registry exposes approved capabilities through native plugins and MCP connections.
- The session store preserves conversation history and diagnostic events.
- The reporter sends progress updates and final answers back to Slack.
This separation keeps Slack event handling from becoming the place where every integration and business rule accumulates. A change to Salesforce connectivity should not require rewriting the conversation loop. A change to message formatting should not change how tools execute.
Claude is the initial model provider and the intended experience. The provider still sits behind a replaceable service contract. That preserves a way to change the model integration without rebuilding the rest of the app.
The application uses Socket Mode for its Slack connection. Slack events and interactions can reach it without a public HTTP request endpoint. That simplifies the Slack transport, although the external systems’ OAuth callbacks still need appropriate routing. Socket Mode does not eliminate all hosting or connectivity requirements.
Treat a thread as a conversation boundary
A team assistant needs to know which conversation a message belongs to.
The app maintains sessions around the Slack workspace, channel, and thread. Work runs serially within a session, while separate sessions can run concurrently. This prevents overlapping turns from competing to update the same conversation history without forcing unrelated conversations into one queue.
The bot responds to mentions, direct messages, and follow-ups in threads it has engaged with. It does not retrieve earlier channel history or treat the entire workspace as background context.
That is a useful limit. Inviting an assistant into a conversation should not imply that it has read everything the team has ever discussed.
There is another boundary when personal data connections enter the picture. With Drive enabled, context is isolated by the requesting Slack user and the relevant connection and folder-pin revisions. Participants establish their own context rather than inheriting another person’s retrieved material simply because they share a thread.
The thread organizes the collaboration. It does not grant permission to every source discussed within it.
Connect documents and records without confusing their roles
Google Drive and Salesforce answer different kinds of questions.
A project document might explain scope, assumptions, or an agreed approach. A Salesforce record might show assigned work and its current status. Bringing both into a conversation helps the assistant explain the work with more than a single system’s view.
The Drive connector uses individual OAuth connections. Channels can pin relevant folders and choose on-demand or automatic context. The folder selection is shared, but retrieval uses the requesting person’s Google credentials and checks their channel membership. A folder pin is a context choice, not an access grant.
Salesforce uses a dedicated connector to its hosted MCP capabilities, with personal sign-in for each user. OAuth and MCP have different jobs here. OAuth establishes the user’s authorized connection; MCP provides the protocol for discovering and invoking exposed capabilities.
This is a custom Slack application calling Claude and connected systems. It is not the Claude application’s Salesforce connector running inside Slack, and feature parity should not be assumed. The aim is to bring comparable work-oriented access into another primary team interface.
Both connectors contribute to one Slack Home page. That gives users a common place to manage their connections instead of making each integration invent its own onboarding experience.
Generic MCP connections deserve separate treatment. Those can use operator-configured credentials rather than individual identities. Connecting a server does not automatically give it the same permission model as the personal Salesforce and Drive connectors.
Separate tools, skills, and enforceable policy
One of the most useful architectural distinctions is between what the assistant can do and how we want it to approach the task.
Tools provide capabilities. Skills describe procedures. Policy hooks enforce application rules.
A document-reading tool retrieves content. An engagement-brief skill tells Claude how to organize that content, cite facts, and identify missing information. A policy hook can deny an operation before the tool executes.
Keeping these separate makes team procedures easier to maintain. A better status-update format should not require changing the Google Drive integration. A new document-reading capability should not require duplicating every procedure that might use it.
Skills live in Markdown files. Initially, the model sees their names and descriptions; it loads the full instructions and supporting references when needed. This avoids putting every team’s procedure into every model request.
The important limit is that skill selection remains model-directed. A sentence in a skill is guidance, not a security control. Mandatory restrictions belong in executable policy and authorization checks.
Plugins provide the extension mechanism around those responsibilities. They declare dependencies, register tools, contribute context, and attach lifecycle hooks. Missing dependencies and duplicate services fail startup rather than producing a partially assembled application.
These plugins are trusted application code. They are not sandboxed, so adding one deserves the same review as adding any other code that runs with the application’s privileges.
Use conversation for understanding and forms for known actions
Natural language is useful when the request needs interpretation: explain a project’s context, compare supporting information, or identify what remains unclear.
For a known action, structured input can be better.
The app includes slash-command entry points for creating work items and submitting project health information. Forms give the user an explicit place to supply required details rather than asking the model to infer them from a long thread.
Consider an intended pilot workflow. A teammate asks Claude to summarize an engagement using accessible project documents and relevant Salesforce information. They review the answer and identify work to delegate. A structured command then collects the information needed to create that work in Salesforce.
That is an illustrative workflow, not a claim that the full sequence has passed a live pilot. It explains why the architecture includes both conversation and conventional application controls.
There is also no built-in general approval workflow in this version. A form is not a substitute for one. Sensitive operations need explicit controls before exposure, and a read-only pilot is a reasonable starting point wherever those controls remain incomplete.
Make failure behavior part of the design
Once an assistant can change records, failure handling becomes part of the user experience.
The runtime bounds its model-and-tool loop, validates tool arguments, applies timeouts, and supports cancellation. MCP capabilities require explicit exposure in configuration; connecting a server does not expose every discovered tool by default.
MCP standardizes tool discovery and invocation. The application still owns the decisions about which tools to expose, how to authorize their use, and when a person must confirm an action.
Persistence is equally deliberate. SQLite stores sessions, completed turns, duplicate-message keys, and diagnostic events. The deployment model is one process per database on local disk. That keeps the initial operating footprint small without pretending to provide distributed execution.
After a restart, unfinished turns are marked interrupted. The app does not automatically replay their tool actions.
That matters because a Salesforce write could succeed even if the response never reaches Slack. Retrying the whole conversation could duplicate the action. The safer recovery is to check the external result before issuing a fresh request.
Duplicate-message suppression helps with repeated deliveries, but it does not establish exactly-once execution across external systems. Cancellation cannot undo a completed write either.
These limits should be visible to the team. A stopped conversation and a rolled-back business transaction are different things.
Keep the data-sharing boundary visible
Personal OAuth connections solve only part of the privacy problem.
A user may have access to a document that other channel members cannot open. If the assistant summarizes that document in a channel, the answer is visible there. Permission to retrieve information is not automatically permission to share it with that audience.
The current design checks source access and isolates context, but its channel answers remain visible to channel participants. Channel selection, permitted content, and output-sharing controls therefore need attention before the pilot expands.
Data also travels beyond the source systems. Retrieved content used in reasoning goes to the configured model provider, and local journals can contain inputs, model requests, and tool outputs. Diagnostic retention is bounded, while completed conversation history persists.
Source permissions, provider data handling, and local storage policy all belong in the rollout review. Encrypting connection tokens does not settle those other questions.
Measure less reconstruction and better follow-through
The productivity case rests on specific tasks, not message volume.
For project context, the intended benefit is less time searching folders, opening records, and assembling a briefing before a useful discussion can begin. Source links should make checking the answer easier, too.
For delegation, the intended benefit is a shorter path from an agreed action in Slack to a work item in Salesforce. The record should retain the structure needed for ownership and tracking.
Shared skills may also reduce repeated explanation. The team can maintain a common procedure for a brief or status update instead of teaching the assistant the same format in every conversation.
The pilot should test those expectations. Useful measures include time to a source-backed answer, corrections needed before a work item is usable, and how often users still have to switch applications to finish the task. Permission failures and duplicate records matter as much as speed.
The architecture gives us a way to test this without replacing the systems the team already uses. Bolt brings the interaction into Slack. Claude works with authorized context. Salesforce continues to hold the work.
If the pilot succeeds, a teammate should be able to move from “What is happening on this project?” to “Here is the work we agreed to assign” with less searching and re-entry, while still being able to inspect the sources and verify the resulting record.