Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

openui-slack

Generative UI in Slack, powered by OpenUI-lang.

Ask in plain English and the bot replies with a native, interactive Slack card - fields, buttons that actually do things, and real charts - instead of a wall of markdown. An LLM composes the interface as OpenUI-lang; this app compiles it to Slack Block Kit and runs the interaction loop.

/agent  a card with a counter and +1 / -1 / reset buttons
/agent  a bar chart of tasks by status: 5 todo, 3 in progress, 8 done, with a refresh button
@openui-agent  give me a sprint status card with key metrics

Clicking a button updates the same message in place - state lives server-side, no new messages and no model call per click.

For how it all fits together, see ARCHITECTURE.md.

Capabilities

  • Generative UI - the model composes each layout from a curated component set (headers, sections, field grids, context, dividers, images, buttons, charts).
  • Interactive state - buttons carry actions (@Set, @Reset) that run server-side and re-render the message via chat.update.
  • Real charts - bar / line / pie / area rendered to PNG with axes, value labels, and legends.
  • Socket Mode - outbound WebSocket, so no public URL and no webhooks.
  • Two entry points - the /agent slash command and @mentions.

Setup

Prerequisites

  • Node.js 18+
  • A Slack workspace where you can install an app
  • An OpenAI API key

1. Install

git clone <your-repo-url> openui-slack
cd openui-slack
npm install

2. Create the Slack app

Socket Mode means no public URL - the bot opens an outbound WebSocket.

Go to api.slack.com/appsCreate New AppFrom an app manifest, pick your workspace, and paste:

display_information:
  name: OpenUI Agent
features:
  bot_user:
    display_name: openui-agent
    always_online: true
  slash_commands:
    - command: /agent
      description: Ask the OpenUI agent
      usage_hint: "[your request]"
      should_escape: false
oauth_config:
  scopes:
    bot:
      - commands          # /agent slash command
      - app_mentions:read # @mentions
      - chat:write        # post, chat.update, ephemeral
      - files:write       # upload chart images
      - reactions:write   # react to the triggering message
settings:
  event_subscriptions:
    bot_events:
      - app_mention
  interactivity:
    is_enabled: true      # button clicks -> block_actions over the socket
  socket_mode_enabled: true
  org_deploy_enabled: false
  token_rotation_enabled: false

Then:

  1. App-level token - Basic Information → App-Level Tokens → Generate, scope connections:write → copy the xapp-… value.
  2. Install - Install App → Install to Workspace → Allow → copy the Bot User OAuth Token xoxb-….
  3. Invite the bot to a channel so it can post and be mentioned there: /invite @openui-agent.

3. Configure env

Copy .env.example to .env and fill in:

OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-5.5
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...

4. Run

npm run dev      # watch mode
# or
npm start        # run once

Then in Slack: /agent a bar chart of tasks by status with a refresh button, or @openui-agent ….

Dev tools (no tokens needed)

npm run smoke    # drive the reactive loop headlessly (state + action + re-render)
npm run chart    # render each chart type to chart-<type>.png

Configuration

Env var Purpose
OPENAI_API_KEY OpenAI credentials (required)
OPENAI_MODEL Model id (default gpt-5.5)
SLACK_BOT_TOKEN Bot User OAuth token xoxb-… (required)
SLACK_APP_TOKEN App-level token xapp-… for Socket Mode (required)
MCP_URL Optional. MCP server for live data via Query(), bridged with npx mcp-remote (e.g. https://mcp.linear.app/sse)

Limitations

  • State is in-memory. Buttons on messages posted before a restart are acknowledged but do nothing. Swap the Map in src/store.ts for Redis to make it durable.
  • No modals or rich input forms - Slack routes those through modals, not yet supported here.
  • Reply-only, single workspace - responds to commands and mentions; no proactive posting or multi-tenant OAuth.

Live data (optional)

Set MCP_URL to an MCP server and the agent's Query() calls run against it. On boot, index.ts connects (via npx mcp-remote, which handles hosted OAuth on first run), registers the server as the tool provider, and lists its tools in the prompt. Then a request like /agent a snapshot of my open issues fetches real data. Without MCP_URL, the agent invents plausible data.

Roadmap

  • Mutations - run a Mutation() tool from a button (@Run); reads (Query()) work today.
  • Query arrays into tables - a column-projection Table bound to query rows.
  • Streaming - stream model output and debounce chat.update.
  • Durable state - Redis-backed message store.

License

MIT - see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages