Discord-Claude Gateway

An event-driven agent runtime that connects Discord to Claude via the Claude Agent SDK. Inspired by OpenClaw's architecture — a gateway in front of an agent runtime with markdown-based personality, memory, and scheduled behaviors.

How It Works

Discord Users ──► Discord Bot ──► Event Queue ──► Agent Runtime ──► Claude Agent SDK
                                      ▲                                    │
                  Heartbeats ──────────┤                                    │
                  Cron Jobs ───────────┤              ┌─────────────────────┘
                  Hooks ───────────────┘              ▼
                                              Markdown Config Files
                                         (soul, identity, memory, etc.)

All inputs — Discord messages, heartbeat timers, cron jobs, lifecycle hooks — enter a unified event queue. The agent runtime reads your markdown config files fresh on each event, assembles a dynamic system prompt, and calls the Claude Agent SDK. The agent can write back to memory.md to persist facts across sessions.

Prerequisites

  • Node.js 18+
  • Claude Code CLIInstall Claude Code and sign in with your subscription
  • Discord Bot TokenCreate a bot with Message Content Intent enabled

Quick Start

# Install dependencies
npm install

# Make sure Claude Code CLI is installed and you're signed in
claude --version

# Set required environment variables
export DISCORD_BOT_TOKEN=your-discord-bot-token

# Create config directory with persona files
mkdir config

Create at minimum config/soul.md and config/identity.md:

# config/identity.md
echo "# Identity

- **Name:** Aetheel
- **Vibe:** Helpful, sharp, slightly witty
- **Emoji:** ⚡" > config/identity.md

# config/soul.md
echo "# Soul

Be genuinely helpful. Have opinions. Be resourceful before asking.
Earn trust through competence." > config/soul.md
# Start the gateway
npm run dev

Configuration

All settings are via environment variables:

Variable Required Default Description
DISCORD_BOT_TOKEN Yes Discord bot token
CLAUDE_CLI_PATH No claude Path to the Claude Code CLI binary
ALLOWED_TOOLS No Read,Write,Edit,Glob,Grep,WebSearch,WebFetch Comma-separated Claude Code tools
PERMISSION_MODE No bypassPermissions Claude Code permission mode
QUERY_TIMEOUT_MS No 120000 Query timeout in milliseconds
MAX_CONCURRENT_QUERIES No 5 Max simultaneous Claude queries
CONFIG_DIR No ./config Path to markdown config directory
MAX_QUEUE_DEPTH No 100 Max events in the queue
OUTPUT_CHANNEL_ID No Discord channel for heartbeat/cron output

Markdown Config Files

Place these in your CONFIG_DIR (default: ./config/). The gateway reads them fresh on every event — edit them anytime, no restart needed.

File Purpose Required
identity.md Agent name, role, specialization Yes
soul.md Personality, tone, values, behavior defaults Yes
agents.md Operating rules, safety boundaries, cron jobs, hooks No
user.md Info about you: name, preferences, context No
memory.md Long-term memory (agent can write to this) No (auto-created)
tools.md Tool configs, API notes, usage limits No
heartbeat.md Proactive check definitions No
boot.md Bootstrap configuration No

Missing optional files are created with default headers on first run.

Heartbeat Config (heartbeat.md)

Define proactive checks the agent runs on a timer:

## check-email
Interval: 1800
Instruction: Check my inbox for anything urgent. If nothing, reply HEARTBEAT_OK.

## check-calendar
Interval: 3600
Instruction: Review upcoming calendar events in the next 24 hours.

Interval is in seconds (minimum 60).

Cron Jobs (in agents.md)

Define scheduled tasks with cron expressions:

## Cron Jobs

### morning-briefing
Cron: 0 9 * * *
Instruction: Good morning! Check email, review today's calendar, and give me a brief summary.

### weekly-review
Cron: 0 15 * * 1
Instruction: Review the week's calendar and flag any conflicts.

Hooks (in agents.md)

Define lifecycle hook instructions:

## Hooks

### startup
Instruction: Read memory.md and greet the user.

### shutdown
Instruction: Save any important context to memory.md before shutting down.

Discord Commands

Command Description
@bot <message> Send a prompt by mentioning the bot
/claude <prompt> Send a prompt via slash command
/claude-reset Reset the conversation session in the current channel

Architecture

The system has 5 input types (inspired by OpenClaw):

  1. Messages — Discord mentions and slash commands
  2. Heartbeats — Timer-based proactive checks
  3. Cron Jobs — Scheduled events with cron expressions
  4. Hooks — Internal lifecycle triggers (startup, shutdown, agent_begin, agent_stop)
  5. Webhooks — External system events (planned)

All inputs enter a unified FIFO event queue → processed sequentially by the agent runtime → state persists to markdown files → loop continues.

Project Structure

src/
├── index.ts                  # Entry point
├── gateway-core.ts           # Main orchestrator
├── config.ts                 # Environment variable loader
├── discord-bot.ts            # Discord.js wrapper
├── event-queue.ts            # Unified FIFO event queue
├── agent-runtime.ts          # Core processing engine
├── markdown-config-loader.ts # Reads config files from disk
├── system-prompt-assembler.ts# Assembles system prompt from configs
├── session-manager.ts        # Channel-to-session bindings
├── channel-queue.ts          # Per-channel sequential processing
├── response-formatter.ts     # Message splitting for Discord's 2000 char limit
├── error-formatter.ts        # Safe error formatting
├── heartbeat-scheduler.ts    # Recurring timer events
├── cron-scheduler.ts         # Cron-expression scheduled events
├── hook-manager.ts           # Lifecycle hook events
├── bootstrap-manager.ts      # First-run file validation/creation
└── shutdown-handler.ts       # Graceful SIGTERM/SIGINT handling

Development

# Run tests
npm test

# Run in dev mode
npm run dev

# Build
npm run build

# Start production
npm start

Claude Code CLI vs API Key

This gateway uses the Claude Code CLI (claude -p) instead of the Anthropic API directly. This means:

  • You use your existing Claude Code subscription — no separate API key needed
  • Just sign in with claude in your terminal and you're good to go
  • The gateway shells out to claude -p "prompt" --output-format json for each query
  • Set CLAUDE_CLI_PATH if claude isn't in your PATH

License

MIT

Description
No description provided
Readme 870 KiB
Languages
TypeScript 70.9%
JavaScript 13.8%
CSS 12.1%
HTML 1.7%
Shell 1.5%