Atlas

Interaction Plugins

Add MCP server and Slack bot surfaces to Atlas via plugins.

Interaction plugins add new surfaces for users to communicate with Atlas beyond the web UI and API.

MCP Server

The MCP interaction plugin wraps the @atlas/mcp server package as an Atlas plugin, managing its lifecycle (initialization, health checks, teardown). It supports two transports: stdio for local tools like Claude Desktop and Cursor, and SSE (Streamable HTTP) for browser-based or remote MCP clients.

Tool bridging and resource registration are handled internally by @atlas/mcp -- this plugin is a thin lifecycle wrapper that makes it configurable via atlas.config.ts.

Prerequisites

  • @atlas/plugin-mcp-interaction -- the plugin package (workspace dependency)
  • @atlas/mcp -- the underlying MCP server (pulled in automatically via dynamic import)
  • @modelcontextprotocol/sdk -- MCP protocol SDK (required for stdio transport)

Configuration

OptionTypeDefaultDescription
transport"stdio" | "sse""stdio"Transport type. stdio communicates via stdin/stdout (JSON-RPC). sse starts a Streamable HTTP server.
portnumber8080Port for the SSE transport server. Ignored when transport is stdio.

Usage

import { defineConfig } from "@atlas/api/lib/config";
import { mcpPlugin } from "@atlas/plugin-mcp-interaction";

export default defineConfig({
  plugins: [
    mcpPlugin({ transport: "stdio" }),
  ],
});

For SSE transport with a custom port:

export default defineConfig({
  plugins: [
    mcpPlugin({ transport: "sse", port: 9090 }),
  ],
});

Transport modes

stdio -- The default. The MCP server communicates over stdin/stdout using JSON-RPC. Use this when connecting from local tools (Claude Desktop, Cursor, etc.) that launch Atlas as a subprocess. The plugin creates a single StdioServerTransport and connects it during initialize().

SSE -- Starts a standalone HTTP server that accepts Streamable HTTP connections. Use this for browser-based MCP clients or remote access. Each SSE session gets its own MCP server instance, managed internally by @atlas/mcp. The plugin tracks the HTTP server handle for graceful shutdown.

Both transports use dynamic imports to avoid pulling in @atlas/mcp and its transitive dependencies at module evaluation time. The MCP server is only created when initialize() is called.


Slack Bot

The Slack interaction plugin integrates Slack as a full interaction surface for Atlas. Users can ask questions via slash commands (/atlas), continue conversations in threads, approve or deny actions via Block Kit buttons, and install the bot across multiple workspaces via OAuth.

This plugin uses the routes() interface to mount Hono routes directly into the Atlas API server, and receives runtime dependencies (agent execution, conversation persistence, action approval) via config callbacks rather than importing from @atlas/api.

Prerequisites

  • @atlas/plugin-slack-interaction -- the plugin package (workspace dependency)
  • A Slack app configured with slash commands and Events API subscriptions
  • Either a bot token (single-workspace) or OAuth credentials (multi-workspace)

Configuration

OptionTypeRequiredDescription
signingSecretstringYesSlack signing secret for request verification. Found in your Slack app's Basic Information page.
botTokenstringConditionalBot token for single-workspace mode (xoxb-...). Required if clientId/clientSecret are not set.
clientIdstringConditionalClient ID for multi-workspace OAuth. Required (with clientSecret) if botToken is not set.
clientSecretstringConditionalClient secret for multi-workspace OAuth. Required (with clientId) if botToken is not set.
executeQueryfunctionYesCallback that runs the Atlas agent on a question and returns structured results. Signature: (question, options?) => Promise<SlackQueryResult>.
checkRateLimitfunctionNoOptional rate limiting callback. Signature: (key) => { allowed: boolean }.
conversationsConversationCallbacksNoOptional conversation persistence callbacks (create, addMessage, get, generateTitle).
actionsActionCallbacksNoOptional action framework callbacks (approve, deny, get).
scrubErrorfunctionNoOptional error scrubbing callback to strip sensitive information from error messages.

Either botToken (single-workspace) or both clientId and clientSecret (multi-workspace OAuth) must be provided. The config schema validates this constraint at factory call time.

Usage

import { defineConfig } from "@atlas/api/lib/config";
import { executeAgentQuery } from "@atlas/api/lib/agent-query";
import { slackPlugin } from "@atlas/plugin-slack-interaction";

export default defineConfig({
  plugins: [
    slackPlugin({
      signingSecret: process.env.SLACK_SIGNING_SECRET!,
      botToken: process.env.SLACK_BOT_TOKEN,
      executeQuery: executeAgentQuery,
    }),
  ],
});

For multi-workspace OAuth with conversation persistence and action approval:

import { defineConfig } from "@atlas/api/lib/config";
import { executeAgentQuery } from "@atlas/api/lib/agent-query";
import { slackPlugin } from "@atlas/plugin-slack-interaction";

export default defineConfig({
  plugins: [
    slackPlugin({
      signingSecret: process.env.SLACK_SIGNING_SECRET!,
      clientId: process.env.SLACK_CLIENT_ID!,
      clientSecret: process.env.SLACK_CLIENT_SECRET!,
      executeQuery: executeAgentQuery,
      conversations: myConversationCallbacks,
      actions: myActionCallbacks,
    }),
  ],
});

Mounted routes

The plugin mounts the following Hono routes under the plugin's base path:

MethodPathDescription
POST/commandsSlash command handler (/atlas)
POST/eventsSlack Events API (thread follow-ups, url_verification)
POST/interactionsBlock Kit action buttons (approve/deny actions)
GET/installOAuth install redirect (multi-workspace mode)
GET/callbackOAuth callback (multi-workspace mode)

Database schema

The Slack plugin declares two tables that are auto-migrated to the Atlas internal database at boot:

  • slack_installations -- Stores OAuth installations for multi-workspace mode (team_id, bot_token, installed_at)
  • slack_threads -- Maps Slack threads to Atlas conversations (channel_id, thread_ts, conversation_id)

The executeQuery callback is the bridge between the Slack plugin and the Atlas agent. It receives the user's question and optional prior messages (for threaded conversations), runs the agent, and returns structured results that the plugin formats into Block Kit messages. The host application is responsible for providing this callback -- see executeAgentQuery in @atlas/api/lib/agent-query for the reference implementation.

On this page