211 lines
7.4 KiB
Markdown
211 lines
7.4 KiB
Markdown
# Discord-Claude Gateway
|
|
|
|
An event-driven agent runtime that connects Discord to Claude via the [Claude Agent SDK](https://docs.anthropic.com/en/docs/agent-sdk/overview). Inspired by [OpenClaw](https://github.com/nichochar/open-claw)'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+
|
|
- **Discord Bot Token** — [Create a bot](https://discord.com/developers/applications) with Message Content Intent enabled
|
|
- **Anthropic API Key** — Get one from [console.anthropic.com](https://console.anthropic.com/) (this is separate from a Claude Code CLI subscription)
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Set required environment variables
|
|
export DISCORD_BOT_TOKEN=your-discord-bot-token
|
|
export ANTHROPIC_API_KEY=your-anthropic-api-key
|
|
|
|
# Create config directory with persona files
|
|
mkdir config
|
|
```
|
|
|
|
Create at minimum `config/soul.md` and `config/identity.md`:
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
```bash
|
|
# Start the gateway
|
|
npm run dev
|
|
```
|
|
|
|
## Configuration
|
|
|
|
All settings are via environment variables:
|
|
|
|
| Variable | Required | Default | Description |
|
|
|----------|----------|---------|-------------|
|
|
| `DISCORD_BOT_TOKEN` | Yes | — | Discord bot token |
|
|
| `ANTHROPIC_API_KEY` | Yes | — | Anthropic API key from [console.anthropic.com](https://console.anthropic.com/) |
|
|
| `ALLOWED_TOOLS` | No | `Read,Write,Edit,Glob,Grep,WebSearch,WebFetch` | Comma-separated Agent SDK tools |
|
|
| `PERMISSION_MODE` | No | `bypassPermissions` | Agent SDK permission mode |
|
|
| `QUERY_TIMEOUT_MS` | No | `120000` | Query timeout in milliseconds |
|
|
| `MAX_CONCURRENT_QUERIES` | No | `5` | Max simultaneous Agent SDK 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:
|
|
|
|
```markdown
|
|
## 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:
|
|
|
|
```markdown
|
|
## 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:
|
|
|
|
```markdown
|
|
## 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
|
|
|
|
```bash
|
|
# Run tests
|
|
npm test
|
|
|
|
# Run in dev mode
|
|
npm run dev
|
|
|
|
# Build
|
|
npm run build
|
|
|
|
# Start production
|
|
npm start
|
|
```
|
|
|
|
## API Key vs Claude Code Subscription
|
|
|
|
The Claude Agent SDK requires an **Anthropic API key** (`ANTHROPIC_API_KEY`), which is separate from a Claude Code CLI subscription. Get one at [console.anthropic.com](https://console.anthropic.com/). API usage is billed per-token.
|
|
|
|
The SDK also supports:
|
|
- **Amazon Bedrock**: set `CLAUDE_CODE_USE_BEDROCK=1` + AWS credentials
|
|
- **Google Vertex AI**: set `CLAUDE_CODE_USE_VERTEX=1` + GCP credentials
|
|
- **Azure AI Foundry**: set `CLAUDE_CODE_USE_FOUNDRY=1` + Azure credentials
|
|
|
|
## License
|
|
|
|
MIT
|