pumble-mcp

nitindermohan/pumble-mcp
0 starsCommunity

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

A standalone MCP server providing AI agents with full access to the Pumble messaging platform via OAuth2 and the Pumble SDK, including messaging, files, channels, search, scheduling, and real-time events.

README.md

<div align="center">

<img src="image.png" alt="pumble-mcp — Full Pumble Platform Access for AI Agents" width="100%"/>

<br/>

![TypeScript](https://www.typescriptlang.org/) ![MCP](https://modelcontextprotocol.io) ![Node.js](https://nodejs.org/) ![Pumble SDK](https://github.com/CAKE-com/pumble-node-sdk) ![License: MIT](https://opensource.org/licenses/MIT) ![Tests](#testing)

A standalone MCP server that gives AI agents complete access to the Pumble messaging platform.<br/> Built on the official Pumble SDK and the Model Context Protocol.

Getting Started · Tools · Real-Time Events · Architecture · Configuration · Development

</div>

---

Why pumble-mcp?

The existing Pumble MCP server wraps ~8 API endpoints with API-key auth. It can't touch files, receive events, manage channels, search messages, or schedule anything.

pumble-mcp exposes the entire platform — 33 tools across messaging, files, channels, users, search, scheduling, and real-time events — using OAuth2 and the full Pumble SDK for capabilities the REST API alone cannot provide.

| Capability | Existing MCP | pumble-mcp | |---|:---:|:---:| | Messages (send, read, edit, delete, threads) | Partial | Full | | File operations (upload, download, list) | — | SDK-exclusive | | Real-time events (subscribe, poll) | — | WebSocket | | Channel management (create, add/remove members) | — | Full | | Search with text/channel/user/date filters | — | Full | | Scheduled messages (create, edit, cancel) | — | Full | | User status and groups | — | Full | | HTTP transport for N8N / webhooks | — | Streamable HTTP | | Auth model | API key | OAuth2 | | Total tools | ~8 | 33 |

---

Getting Started

Prerequisites

  • Node.js 22+ (LTS)
  • A Pumble workspace where you have admin access

1. Clone and install

git clone https://github.com/nitindermohan/pumble-mcp.git
cd pumble-mcp
npm install

2. Register a Pumble app

npx pumble-cli login     # Authenticate with your Pumble account
npx pumble-cli create    # Register a new bot app

This creates .pumbleapprc with your app credentials (APP_ID, APP_KEY, CLIENT_SECRET, SIGNING_SECRET).

3. Configure environment

cp .env.example .env

Fill in the credentials from .pumbleapprc:

PUMBLE_APP_ID=your_app_id
PUMBLE_APP_KEY=your_app_key
PUMBLE_APP_CLIENT_SECRET=your_client_secret
PUMBLE_APP_SIGNING_SECRET=your_signing_secret

4. Authorize and register events

Run once via pumble-cli to authorize the bot in your workspace and push event subscriptions to Pumble's platform:

npx pumble-cli

Wait for Websocket connected and App is updated, then Ctrl+C.

5. Build and run

npm run build
node dist/index.js

6. Connect to your AI client

<details> <summary><strong>Claude Code</strong></summary>

Add to .mcp.json in your project root:

{
  "mcpServers": {
    "pumble": {
      "command": "node",
      "args": ["dist/index.js"],
      "cwd": "/path/to/pumble-mcp"
    }
  }
}

</details>

<details> <summary><strong>Claude Desktop</strong></summary>

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "pumble": {
      "command": "node",
      "args": ["/absolute/path/to/pumble-mcp/dist/index.js"],
      "cwd": "/absolute/path/to/pumble-mcp"
    }
  }
}

</details>

<details> <summary><strong>N8N (HTTP transport)</strong></summary>

Set MCP_TRANSPORT=http (or both) in .env, optionally set MCP_BEARER_TOKEN, then point N8N's HTTP Request node at:

POST http://localhost:3456/mcp
Authorization: Bearer YOUR_TOKEN

</details>

---

🔧 Tools

Messaging — Read, write, and manage messages across channels and threads

| Tool | Description | |------|-------------| | pumble_send_message | Send a message to a channel. Accepts #channel-name or channel ID. | | pumble_reply_message | Reply to a specific message in a thread. | | pumble_list_messages | List recent messages in a channel with cursor-based pagination. | | pumble_get_message | Fetch a single message by its timestamp ID. | | pumble_get_thread_replies | Fetch all replies in a message thread. | | pumble_edit_message | Edit a message the bot previously sent. | | pumble_delete_message | Delete a message the bot previously sent. |

Direct Messages — Private conversations with individuals or groups

| Tool | Description | |------|-------------| | pumble_send_dm | Send a direct message to a user. Accepts email address or user ID. | | pumble_send_group_dm | Send a group DM to multiple users at once. |

Channels — Create and manage workspace channels

| Tool | Description | |------|-------------| | pumble_list_channels | List all channels the bot belongs to, with pagination. | | pumble_get_channel | Get channel details by #name or ID. | | pumble_create_channel | Create a new PUBLIC or PRIVATE channel. | | pumble_add_channel_members | Add one or more users to a channel. | | pumble_remove_channel_member | Remove a user from a channel. |

Users — Workspace user information and bot identity

| Tool | Description | |------|-------------| | pumble_list_users | List all users in the workspace with roles and status. | | pumble_get_bot_identity | Get the bot's own user ID, display name, and workspace info. | | pumble_list_user_groups | List user groups and their members. | | pumble_set_status | Set the bot's custom status with emoji, text, and optional expiration. |

Reactions — Emoji reactions on messages

| Tool | Description | |------|-------------| | pumble_add_reaction | Add an emoji reaction (e.g. :thumbsup:) to any message. | | pumble_remove_reaction | Remove a previously added emoji reaction. |

Files — Upload, download, and browse files (SDK-exclusive)

| Tool | Description | |------|-------------| | pumble_upload_file | Upload a file (base64-encoded) to a channel with an optional message. | | pumble_download_file | Download a file by URL and return its base64 content. | | pumble_list_files | List files shared in a channel. |

Note: File operations are only available through the Pumble SDK with OAuth2 auth. The REST API alone does not expose file endpoints.

Search — Find messages across the workspace

| Tool | Description | |------|-------------| | pumble_search_messages | Full-text search with filters for channel, user, date range, and pagination. |

Scheduled Messages — Send messages at a future time

| Tool | Description | |------|-------------| | pumble_create_scheduled_message | Schedule a message for future delivery to any channel. | | pumble_list_scheduled_messages | List all pending scheduled messages. | | pumble_edit_scheduled_message | Edit the content or timing of a pending scheduled message. | | pumble_delete_scheduled_message | Cancel a scheduled message before it sends. |

Real-Time Events — Subscribe and poll for live workspace activity

| Tool | Description | |------|-------------| | pumble_subscribe_events | Subscribe to one or more event types. Returns a subscription ID for polling. | | pumble_poll_events | Poll for events buffered since the last poll for a given subscription. | | pumble_list_subscriptions | List all active event subscriptions with their types and cursor positions. | | pumble_unsubscribe_events | Remove a subscription and stop buffering its events. |

System

| Tool | Description | |------|-------------| | pumble_health_check | Check server version, auth status, workspace name, and connection health. |

---

📡 Real-Time Events

pumble-mcp connects to Pumble via socket mode WebSocket and buffers incoming events in an in-memory ring buffer (1000 events, oldest evicted first). AI agents subscribe to event types and poll for new events at their own pace — no push endpoint or public URL required.

  AI Agent                   pumble-mcp                     Pumble
     │                           │                             │
     │── subscribe(NEW_MESSAGE) ─▶│                             │
     │◀── subscription_id ───────│                             │
     │                           │◀── WebSocket: NEW_MESSAGE ──│
     │                           │   (buffered in EventStore)  │
     │── poll(subscription_id) ──▶│                             │
     │◀── [event1, event2] ──────│                             │

Supported event types:

| Event | Triggered when... | |-------|-------------------| | NEW_MESSAGE | A message is posted in any channel the bot belongs to | | UPDATED_MESSAGE | A message is edited | | REACTION_ADDED | Someone adds an emoji reaction to a message | | CHANNEL_CREATED | A new channel is created in the workspace | | APP_UNINSTALLED | The bot app is uninstalled from the workspace | | APP_UNAUTHORIZED | A user revokes the bot's authorization | | WORKSPACE_USER_JOINED | A new user joins the workspace |

Example flow:

// 1. Subscribe to events
pumble_subscribe_events({ event_types: ["NEW_MESSAGE", "REACTION_ADDED"] })
// → { subscription_id: "sub_a1b2c3d4", event_types: [...] }

// 2. Poll periodically
pumble_poll_events({ subscription_id: "sub_a1b2c3d4" })
// → { events: [{ eventType: "NEW_MESSAGE", payload: {...}, ... }], count: 3 }

// 3. Unsubscribe when done
pumble_unsubscribe_events({ subscription_id: "sub_a1b2c3d4" })
// → { unsubscribed: true }

---

Architecture

                      ┌──────────────────────────────────────────────┐
                      │                 pumble-mcp                   │
                      │                                              │
  Claude/CLI ──stdio──▶  McpServer ──▶ 33 Tools ──▶ PumbleClient ──▶── Pumble API
                      │      │                          │            │
  N8N/HTTP ───http──▶  McpServer     EventStore ◀── SDK WebSocket ◀─── Pumble Events
                      │              (ring buffer)                   │
                      └──────────────────────────────────────────────┘

Key design decisions:

  • Dual transport — stdio for Claude Desktop/Code, Streamable HTTP for N8N and remote consumers. Same 33 tools on both.
  • EventStore singleton — One ring buffer shared across all transports. Subscribe on stdio, poll from HTTP — it just works.
  • Socket mode — The Pumble SDK handles WebSocket connection, ping/pong keepalive, message ack, and automatic reconnection. No public URL or tunnel needed.
  • stderr-only logging — stdout is reserved exclusively for MCP JSON-RPC. The Pumble SDK's internal console.log calls are redirected to stderr at process start.
  • OAuth2 with token mutex — Concurrent API calls serialize through a mutex to prevent race conditions on single-use refresh tokens.

---

Customizing the Bot Identity

Edit manifest.json to change how the bot appears in your Pumble workspace:

{
  "name": "my-custom-bot",
  "displayName": "My Custom Bot",
  "botTitle": "Team Assistant"
}

Then sync to Pumble:

npx pumble-cli    # Pushes manifest changes to Pumble
# Wait for "App is updated", then Ctrl+C

---

Configuration

Environment Variables

| Variable | Required | Default | Description | |----------|:--------:|---------|-------------| | PUMBLE_APP_ID | Yes | — | App ID from .pumbleapprc | | PUMBLE_APP_KEY | Yes | — | App key for WebSocket authentication | | PUMBLE_APP_CLIENT_SECRET | Yes | — | OAuth2 client secret | | PUMBLE_APP_SIGNING_SECRET | Yes | — | Request signature verification secret | | PUMBLE_TOKEN_STORE_PATH | No | .pumble-tokens.json | Path to OAuth2 token storage | | MCP_TRANSPORT | No | stdio | Transport mode: stdio, http, or both | | MCP_HTTP_PORT | No | 3456 | Port for HTTP transport | | MCP_BEARER_TOKEN | No | — | Bearer token for HTTP transport auth (strongly recommended) | | LOG_LEVEL | No | info | Logging verbosity: error, info, debug |

Required Bot Scopes

These scopes are configured in manifest.json and registered during app creation:

messages:read    messages:write    messages:edit    messages:delete
channels:list    channels:read    channels:write
users:list       user:read
reaction:read    reaction:write
workspace:read   files:write       attachments:write   status:write

---

Development

npm run dev           # Run with tsx (hot reload)
npm run build         # Compile TypeScript
npm test              # Run all 175 tests
npm run test:watch    # Watch mode
npm run test:coverage # Code coverage report
npm run typecheck     # Type check without emitting

Testing

| Suite | Tests | Coverage | |-------|------:|----------| | Unit | 39 | EventStore, event listeners, auth, config, logger | | Integration | 128 | All 33 tools via in-process MCP server + InMemoryTransport | | Live | 8 | End-to-end against a real Pumble workspace |

npm test                              # Unit + integration (no network)
npx tsx tests/live/run-live-tests.ts  # Live tests (requires credentials)

Project Structure

src/
  index.ts              Entry point — boot sequence, console.log redirect
  server.ts             MCP server setup (stdio + Streamable HTTP transports)
  config.ts             Environment validation with Zod schemas
  logger.ts             stderr-only logger (stdout reserved for MCP JSON-RPC)
  main.ts               pumble-cli entry point for event registration
  pumble/
    auth.ts             OAuth2 setup, token mutex, SDK event handler wiring
    client.ts           PumbleClient — unified wrapper for all SDK operations
    resolvers.ts        Smart resolution: #channel-name → ID, email → user ID
  events/
    event-store.ts      Ring buffer (1000 capacity) with subscription-cursor polling
    event-listeners.ts  Bridges SDK event callbacks → EventStore.push()
  tools/
    index.ts            Tool registration hub (routes to all modules below)
    health.ts           pumble_health_check
    channels.ts         5 channel management tools
    users.ts            4 user and bot identity tools
    messages.ts         5 message read tools
    messages-mutate.ts  2 message write tools (edit, delete)
    reactions.ts        2 reaction tools
    dms.ts              2 direct message tools
    files.ts            3 file operation tools (SDK-exclusive)
    search.ts           1 search tool with multi-filter support
    scheduled.ts        4 scheduled message tools
    events.ts           4 real-time event subscription tools
tests/
  setup.ts              Mock PumbleClient and EventStore factories
  unit/                 Pure logic tests — no network, no SDK
  integration/          Full MCP pipeline tests via InMemoryTransport
  live/                 Real Pumble workspace end-to-end tests

---

Tech Stack

| Component | Technology | Version | |-----------|------------|---------| | Runtime | Node.js | 22 LTS | | Language | TypeScript | 5.9 | | MCP Protocol | @modelcontextprotocol/sdk | 1.29.x | | Pumble Platform | pumble-sdk | 1.1.x | | HTTP Transport | Express + @modelcontextprotocol/express | 4.x | | Schema Validation | Zod | 4.x | | Testing | Vitest | 4.x | | Auth | OAuth2 via pumble-cli | — |

---

Disclaimer

This project was largely vibe-coded with Claude Code (Anthropic's AI coding agent). The entire development lifecycle — architecture, implementation, testing, debugging, and documentation — was driven through conversational AI-assisted development. All code was reviewed, tested (175 automated tests), and validated against a live Pumble workspace.

---

License

MIT

Related MCP servers

Browse all →