fulcrum-sessions
v1.3.0
Published
Local proxy server that manages multiple Claude Code sessions with Telegram integration, LinkedIn posting, voice transcription, and Unsplash image search through a single bot connection per machine
Maintainers
Readme
fulcrum-sessions
Local proxy server that manages multiple Claude Code sessions with Telegram integration, LinkedIn posting, voice transcription, and Unsplash image search through a single bot connection per machine.
Quick Start
npm install -g fulcrum-sessions
fulcrum-sessions setup
fulcrum-sessions start
fulcrum-sessions installPrerequisites
1. Create a Telegram Bot
Each machine needs its own bot to avoid polling conflicts.
- Open Telegram and message @BotFather
- Send
/newbot - Choose a name (e.g. "My Agent")
- Choose a username (e.g.
my_agent_bot) - Copy the bot token (e.g.
1234567890:AAHxyz...)
2. Create a Telegram Forum Group
- Create a new Telegram group
- Go to group settings > Group Type > select "Forum"
- This enables topic-based threads (one per Claude session)
3. Add the Bot to the Group as Admin
- Go to your group settings > Administrators > Add Administrator
- Search for your bot by username
- Grant these permissions: Post Messages, Manage Topics
- Important: After adding the bot, send a message in the General topic (e.g.
/start@your_bot_username). The bot cannot see the group until it receives at least one message there.
4. Get the Group ID
- Add @RawDataBot to your group temporarily
- It will reply with group info including the chat ID (a negative number like
-1001234567890) - Remove RawDataBot after getting the ID
Setup
First-time setup
# Install globally
npm install -g fulcrum-sessions
# Run interactive setup (installs Claude Code hooks)
fulcrum-sessions setupThe setup command:
- Writes a session-start hook to
~/.claude/hooks/ - Patches
~/.claude/settings.jsonto wire up the hook - Each new Claude Code session auto-registers with the proxy and creates a Telegram topic
Configure your bot
Edit ~/.fulcrum-sessions/config.json:
{
"botToken": "YOUR_BOT_TOKEN_HERE",
"groupId": "YOUR_GROUP_ID_HERE"
}Or use environment variables:
TELEGRAM_BOT_TOKEN— Bot token from BotFatherTELEGRAM_GROUP_ID— Group chat ID (negative number)FULCRUM_PORT— Override default port 3847
Start the daemon
fulcrum-sessions startInstall as system service (auto-start on boot)
fulcrum-sessions install- macOS: installs a launchd service (
com.fulcrum.sessions) - Linux: adds a cron
@rebootentry
The daemon includes a watchdog that auto-restarts on crash with backoff (max 5 crashes in 60s before 60s cooldown).
CLI Commands
fulcrum-sessions start # Start the daemon
fulcrum-sessions stop # Stop the daemon
fulcrum-sessions status # Show status + active sessions
fulcrum-sessions register --name "Name" # Create a topic and register session
fulcrum-sessions setup # Install Claude Code hooks
fulcrum-sessions install # Install as system service
fulcrum-sessions linkedin-auth # Configure LinkedIn OAuth
fulcrum-sessions linkedin-post --text "x" # Post to LinkedIn
fulcrum-sessions linkedin-status # Check LinkedIn authREST API
All endpoints served on localhost:3847 by default.
Sessions
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /sessions | List all registered sessions |
| POST | /sessions | Create session + Telegram topic. Body: {"name": "Session Name"} |
| GET | /sessions/:topicId/stream | SSE stream for a topic |
| POST | /sessions/:topicId/send | Send message to topic. Body: {"text": "Hello"} |
| DELETE | /sessions/:topicId | Unregister a session |
| GET | /health | Health check |
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /auth/linkedin | Start OAuth flow |
| GET | /auth/linkedin/callback | OAuth callback |
| GET | /auth/linkedin/status | Check auth status |
| POST | /linkedin/post | Create post. Body: {"text": "Post text"} |
Unsplash
| Method | Endpoint | Description | |--------|----------|-------------| | GET | /unsplash/search?q=keyword&count=5 | Search photos |
SSE Stream Format
Connect with: curl -N http://localhost:3847/sessions/:topicId/stream
Events are JSON objects:
- Text:
{"type":"text","updateId":123,"username":"user","firstName":"Name","text":"hello"} - Voice:
{"type":"voice","updateId":124,"username":"user","firstName":"Name","duration":9,"transcript":"transcribed text"} - Photo:
{"type":"photo","updateId":125,"username":"user","firstName":"Name","caption":"","localPath":"/tmp/..."} - Reply context: messages include
"replyTo":{"messageId":123,"text":"original","from":"user"}when replying
Keepalive comments (: keepalive) sent every 15 seconds.
Recommended monitor pattern for Claude Code
Use a retry loop so daemon restarts do not disconnect:
while true; do curl -N http://localhost:3847/sessions/TOPIC_ID/stream 2>/dev/null | grep --line-buffered "^data:"; sleep 2; doneMulti-Machine Setup
Each machine needs its own Telegram bot to avoid getUpdates 409 conflicts. Two machines sharing the same bot token will fight over the polling connection.
- Create a separate bot for each machine via @BotFather
- Add each bot to the same Telegram group as admin
- Send a message mentioning each bot in the group to activate them
- Configure each machine's
~/.fulcrum-sessions/config.jsonwith its own bot token
Voice Transcription
Voice messages are automatically downloaded and transcribed using Whisper (tiny model). Requires:
whisperCLI installed locallyffmpegfor audio conversion
Data Storage
All data stored in ~/.fulcrum-sessions/:
| File | Purpose |
|------|---------|
| config.json | Bot token, group ID, LinkedIn creds |
| sessions.json | Registered sessions (persists across restarts) |
| linkedin.json | LinkedIn OAuth tokens |
| pid | Daemon process ID |
| daemon.log | Daemon stdout/stderr |
Troubleshooting
Bot gets 409 Conflict
Another process is polling the same bot. Stop all other getUpdates connections (other fulcrum-sessions instances, scripts, Telegram MCP servers).
Bot gets "chat not found"
The bot has not been activated in the group. Send a message in the group mentioning the bot: /start@your_bot_username
Sessions not registering
Check that the Claude Code hook is installed: cat ~/.claude/hooks/fulcrum-session-start.sh. If missing, run fulcrum-sessions setup.
Voice transcription fails
Ensure whisper and ffmpeg are installed and in PATH. The daemon uses the tiny model for speed.
License
MIT
