<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: psychomafia.tiger</title>
    <description>The latest articles on Forem by psychomafia.tiger (@tigergethigher).</description>
    <link>https://forem.com/tigergethigher</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3855374%2Fa1d5b6fb-8b6b-4547-8d6b-86565564abcb.jpg</url>
      <title>Forem: psychomafia.tiger</title>
      <link>https://forem.com/tigergethigher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tigergethigher"/>
    <language>en</language>
    <item>
      <title>How to run Claude Code, Gemini, and Codex side-by-side from Discord</title>
      <dc:creator>psychomafia.tiger</dc:creator>
      <pubDate>Wed, 08 Apr 2026 06:27:02 +0000</pubDate>
      <link>https://forem.com/tigergethigher/how-to-run-claude-code-gemini-and-codex-side-by-side-from-discord-55a4</link>
      <guid>https://forem.com/tigergethigher/how-to-run-claude-code-gemini-and-codex-side-by-side-from-discord-55a4</guid>
      <description>&lt;p&gt;Last week I had Claude Code running a refactor in one terminal tab, Codex generating boilerplate in another, and Gemini reviewing a PR in a third. I alt-tabbed to check on Claude Code and it had been waiting for a permission prompt for 20 minutes. Codex had finished and I didn't notice. Gemini was halfway through but I couldn't tell from the tab title.&lt;/p&gt;

&lt;p&gt;Three agents, three terminal windows, zero visibility when I'm not staring at them.&lt;/p&gt;

&lt;p&gt;Claude Code is great for complex multi-file work but burns tokens on simple tasks. Codex is faster and cheaper for straightforward changes. Gemini handles code reviews well. I wanted to use all three, but managing them in separate terminals wasn't working. Especially when I step away from my desk.&lt;/p&gt;

&lt;p&gt;I set up OpenACP to run all three from Discord. My team already uses it, and threads keep each agent session separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this setup looks like
&lt;/h2&gt;

&lt;p&gt;OpenACP is a self-hosted bridge that connects AI coding agents to messaging platforms. For Discord specifically, it creates a forum channel where each agent session gets its own thread. You can run Claude Code in one thread, Codex in another, and Gemini in a third, all at the same time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discord Server
└── #openacp-sessions (forum channel)
    ├── Fix auth middleware race condition   (Claude Code)
    ├── Add user endpoint scaffolding        (Codex)
    └── Review PR #42 error handling         (Gemini)
└── #openacp-notifications
    └── Completion alerts with links back to threads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each thread shows real-time streaming: file reads, code writes, terminal commands, all as they happen. When an agent needs to write a file or run a command, Allow and Reject buttons show up in the thread. I approve from my phone and the agent continues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Discord
&lt;/h2&gt;

&lt;p&gt;The Discord setup takes about 10 minutes. You need a server where you have Manage Server permission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a bot on the Discord Developer Portal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to discord.com/developers/applications, create a new application, then go to Bot in the sidebar. Reset the token and copy it immediately. Under Privileged Gateway Intents, enable Message Content Intent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Generate an invite URL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to OAuth2 → URL Generator. Check &lt;code&gt;bot&lt;/code&gt; and &lt;code&gt;applications.commands&lt;/code&gt; under Scopes. Under Bot Permissions, check: Manage Channels, Send Messages, Send Messages in Threads, Create Public Threads, Manage Threads, Manage Messages, Embed Links, Attach Files, Read Message History, Use Slash Commands, Add Reactions.&lt;/p&gt;

&lt;p&gt;Or just use this permission integer in the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;https://discord.com/oauth2/authorize?client_id=YOUR_APP_ID&amp;amp;scope=bot+applications.commands&amp;amp;permissions=328565073936
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;YOUR_APP_ID&lt;/code&gt; with your Application ID from the portal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Invite the bot and grab the Guild ID&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the invite URL, select your server, authorize. Then enable Developer Mode in Discord settings (User Settings → Advanced), right-click your server name, copy the Server ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Install and configure OpenACP&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup wizard asks which platform you want. Pick Discord, paste the bot token, paste the Guild ID. It validates both and saves the config.&lt;/p&gt;

&lt;p&gt;Start it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenACP creates two channels automatically: &lt;code&gt;#openacp-sessions&lt;/code&gt; (a forum channel for sessions) and &lt;code&gt;#openacp-notifications&lt;/code&gt; (a text channel for completion alerts). The bot registers slash commands within seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing multiple agents
&lt;/h2&gt;

&lt;p&gt;By default OpenACP uses Claude Code. To add more agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp agents &lt;span class="nb"&gt;install &lt;/span&gt;gemini
openacp agents &lt;span class="nb"&gt;install &lt;/span&gt;codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These pull from the ACP registry. You can see everything available with &lt;code&gt;openacp agents&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running agents side-by-side
&lt;/h2&gt;

&lt;p&gt;Once you have multiple agents installed, open your Discord server and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/new claude ~/projects/backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new forum thread opens. It starts as "🔄 claude — New Session" while it initializes. Once you send your first message and the agent responds, it auto-renames to a short summary of the task, something like "Fix auth middleware race condition".&lt;/p&gt;

&lt;p&gt;While that's running, open a new thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/new codex ~/projects/backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Codex is working on the same project in a separate thread. You can give it a different task. Both agents run in parallel, each in their own isolated session.&lt;/p&gt;

&lt;p&gt;Need a code review? Third thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/new gemini ~/projects/backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three threads, three agents, one Discord server. Each one streams independently. When a session finishes, a completion notification goes to &lt;code&gt;#openacp-notifications&lt;/code&gt; with a link back to the thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the thread UI works
&lt;/h2&gt;

&lt;p&gt;Each thread shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tool call embeds&lt;/strong&gt; with a colored sidebar. Blue while the agent is working, green when done, red on error. These group all the file reads, writes, grep calls, and terminal commands into a single embed so the thread doesn't flood with individual messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action row buttons&lt;/strong&gt; below the embed: &lt;code&gt;Low&lt;/code&gt;, &lt;code&gt;Medium&lt;/code&gt;, &lt;code&gt;High&lt;/code&gt; to control how much detail you see, and &lt;code&gt;Cancel&lt;/code&gt; to abort. No slash commands needed for the common actions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permission buttons&lt;/strong&gt; when the agent wants to do something destructive. Allow or Reject, right there in the thread. If you're on your phone and the agent wants to run &lt;code&gt;rm -rf node_modules &amp;amp;&amp;amp; npm install&lt;/code&gt;, you see the full command and can decide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-naming&lt;/strong&gt; after the first prompt. The thread renames from "🔄 claude — New Session" to a short summary of the task, like "Fix auth middleware race condition".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Continuing or changing agents
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/newchat&lt;/code&gt; starts a fresh session in the same thread with the same agent and workspace. Useful when you want a clean slate without losing the conversation history above.&lt;/p&gt;

&lt;p&gt;To use a different agent, run &lt;code&gt;/new codex ~/projects/backend&lt;/code&gt; from any channel. It opens a fresh thread. There's no way to swap agents inside an existing thread, which honestly keeps things cleaner. Each thread is one agent, one task.&lt;/p&gt;

&lt;h2&gt;
  
  
  A workflow I use daily
&lt;/h2&gt;

&lt;p&gt;Morning. I have a PR to review and two bugs to fix.&lt;/p&gt;

&lt;p&gt;Thread 1: &lt;code&gt;/new gemini ~/projects/api&lt;/code&gt;. I send "Review the diff on branch feature/notifications, focus on error handling." Gemini reads the diff, posts comments in the thread. I read them on my phone over coffee.&lt;/p&gt;

&lt;p&gt;Thread 2: &lt;code&gt;/new claude ~/projects/api&lt;/code&gt;. I send "The webhook handler in src/webhooks/stripe.ts is silently swallowing errors. Fix it and add proper logging." Claude Code digs through the codebase, finds the issue, proposes a fix. I tap Allow when it wants to write the file.&lt;/p&gt;

&lt;p&gt;Thread 3: &lt;code&gt;/new codex ~/projects/api&lt;/code&gt;. I send "Add a GET endpoint at /api/v1/health that returns the server uptime and version." Simple task, Codex handles it in under a minute.&lt;/p&gt;

&lt;p&gt;All three finish at different times. Each one posts a completion notification to &lt;code&gt;#openacp-notifications&lt;/code&gt;. I check the results when I'm back at my desk, or from my phone if I'm still out.&lt;/p&gt;

&lt;p&gt;Total cost for the morning: usually under $5. OpenACP tracks per-session token usage and cost, and you can set monthly budget limits that pause the agent when hit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slash commands reference
&lt;/h2&gt;

&lt;p&gt;These register automatically when OpenACP starts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/new [agent] [workspace]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new session in a new thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/newchat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New session with same agent and workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/cancel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cancel the session in the current thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show session or system status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all active sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/menu&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open the control panel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/agents&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Browse available agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/install [name]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install an agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/handoff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Get a terminal command to continue locally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/dangerous&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggle auto-approve for all permission requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;`/outputmode [low&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{% raw %}`/tts [on&lt;/td&gt;
&lt;td&gt;off]`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/doctor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run system diagnostics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all commands&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Things to know
&lt;/h2&gt;

&lt;p&gt;Everything except the model API calls stays on your machine. No relay, no third-party storing your sessions. Swapping between agents doesn't change your messaging setup.&lt;/p&gt;

&lt;p&gt;Some things I ran into. The forum channel works best with Discord Community mode enabled. Without it, OpenACP falls back to a regular text channel with threads, which is less organized. Discord's rate limits on message edits mean streaming output sometimes lags a couple seconds behind the actual agent. And if you're running three agents simultaneously, you're paying three sets of API costs, so the budget limit feature is worth setting up early.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pick Discord during setup. The wizard validates your bot token, connects to your server, and creates the channels. Takes about 10 minutes total.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;https://github.com/Open-ACP/OpenACP&lt;/a&gt;&lt;br&gt;
Discord setup guide: &lt;a href="https://openacp.gitbook.io/docs/platform-setup/discord" rel="noopener noreferrer"&gt;https://openacp.gitbook.io/docs/platform-setup/discord&lt;/a&gt;&lt;br&gt;
ACP registry (browse agents): &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;https://agentclientprotocol.com/get-started/registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT licensed. I'm a contributor to OpenACP. Happy to answer questions about the multi-agent setup or Discord integration below.&lt;/p&gt;

</description>
      <category>discord</category>
      <category>ai</category>
      <category>opensource</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>How OpenACP talks to 28+ AI agents through one protocol — architecture of a self-hosted messaging bridge</title>
      <dc:creator>psychomafia.tiger</dc:creator>
      <pubDate>Mon, 06 Apr 2026 09:16:46 +0000</pubDate>
      <link>https://forem.com/tigergethigher/what-is-agent-client-protocol-acp-and-why-it-matters-for-developer-tools-5ck5</link>
      <guid>https://forem.com/tigergethigher/what-is-agent-client-protocol-acp-and-why-it-matters-for-developer-tools-5ck5</guid>
      <description>&lt;p&gt;I needed Claude Code to talk to Telegram. Not a chatbot — the actual coding agent, running on my machine, reading my files, writing code. I wanted to send it a task from my phone and get structured updates back, including permission prompts I could approve with a tap.&lt;/p&gt;

&lt;p&gt;Parsing terminal stdout wasn't going to cut it. I tried that approach early on and it kept breaking whenever the agent's output format changed.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;OpenACP&lt;/a&gt; and started contributing. What made it work where my hacky approach didn't was a protocol layer underneath: the Agent Client Protocol (ACP), an open standard that lets any client communicate with any compatible coding agent through structured JSON-RPC messages.&lt;/p&gt;

&lt;p&gt;Here's how the architecture works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: agents live in your terminal
&lt;/h2&gt;

&lt;p&gt;AI coding agents — Claude Code, Gemini CLI, Codex, and others — are powerful but they assume you're sitting at a terminal. Leave your desk and the agent hits a permission prompt? It waits. You come back 40 minutes later to find it's been idle the whole time.&lt;/p&gt;

&lt;p&gt;The workarounds people try: SSH into a tmux session on mobile (fragile), VPN + remote desktop (slow), or just hope nothing needs approval. None of these are actually good.&lt;/p&gt;

&lt;p&gt;What you want is a structured bridge: your messaging app on one side, the coding agent on the other, with a session manager in between that handles streaming, permissions, and multiple agents at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenACP's three layers
&lt;/h2&gt;

&lt;p&gt;OpenACP is a self-hosted bridge between messaging platforms (Telegram, Discord, Slack) and AI coding agents. Everything runs on your machine. The architecture has three layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────┐
│                    Your Phone                       │
│            Telegram / Discord / Slack               │
└──────────────────────┬─────────────────────────────┘
                       │
          Platform API (grammY / discord.js)
                       │
┌──────────────────────▼─────────────────────────────┐
│              Layer 1: Adapter                       │
│  Translates platform messages to internal events    │
│  Handles: buttons, topics/threads, streaming,       │
│  rate limiting, message chunking                    │
└──────────────────────┬─────────────────────────────┘
                       │
┌──────────────────────▼─────────────────────────────┐
│           Layer 2: Session Bridge                   │
│  Routes messages between adapters and agents        │
│  Manages: session lifecycle, prompt queue,          │
│  permission gates, cost tracking, parallel sessions │
└──────────────────────┬─────────────────────────────┘
                       │
            ACP protocol (JSON-RPC over stdio)
                       │
┌──────────────────────▼─────────────────────────────┐
│         Layer 3: Agent Connection                   │
│  Spawns agents as subprocesses, speaks ACP          │
│  Handles: initialize, session/new, session/prompt,  │
│  event streaming, permission relay                  │
└────────────────────────────────────────────────────┘
                       │
              Claude Code / Gemini CLI / Codex / ...
                       │
                  Your Codebase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer only talks to its neighbors. The adapter doesn't know which agent is running. The agent doesn't know whether it's talking to Telegram or Discord. The session bridge is the glue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: how agents actually communicate
&lt;/h2&gt;

&lt;p&gt;This is the part that was hardest to get right without a protocol.&lt;/p&gt;

&lt;p&gt;OpenACP spawns each agent as a subprocess and communicates over stdin/stdout using the Agent Client Protocol. ACP is built on JSON-RPC 2.0 — structured messages, not raw text.&lt;/p&gt;

&lt;p&gt;The lifecycle has three phases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Initialize&lt;/strong&gt; — OpenACP tells the agent what capabilities the client supports (file operations, terminal access) and the agent responds with what it can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"initialize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protocolVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"clientCapabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"readTextFile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"writeTextFile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"terminal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create session&lt;/strong&gt; — Point the agent at a working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"session/new"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/user/my-project"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Prompt&lt;/strong&gt; — Send a task. The agent streams back typed events as it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"session/prompt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"abc-123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fix the auth bug in middleware.ts"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While working, the agent sends back events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;agent_message_chunk&lt;/code&gt; — the agent's reasoning, streamed as it thinks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tool_call&lt;/code&gt; / &lt;code&gt;tool_call_update&lt;/code&gt; — file reads, writes, grep, terminal commands&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;usage_update&lt;/code&gt; — token counts and cost&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;plan&lt;/code&gt; — the agent's internal task plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the critical one: &lt;code&gt;request_permission&lt;/code&gt;. When the agent wants to do something that requires approval — write a file, run a destructive command — it sends a structured permission request. OpenACP turns that into a Telegram button or Discord interaction. The agent blocks until you respond.&lt;/p&gt;

&lt;p&gt;This is why the protocol matters. Without it, you're parsing terminal output trying to figure out if the agent is asking a question or just printing something. With ACP, a permission request is an explicit method call with structured options. There's no ambiguity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one protocol means 28+ agents
&lt;/h2&gt;

&lt;p&gt;Here's the real payoff.&lt;/p&gt;

&lt;p&gt;Because OpenACP speaks ACP, it works with every agent that also speaks ACP. The &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;ACP registry&lt;/a&gt; lists 28+ agents right now — Claude Code, Gemini CLI, Codex CLI, GitHub Copilot, Cursor, Cline, goose, Junie, Qwen Code, and more.&lt;/p&gt;

&lt;p&gt;Adding a new agent to OpenACP means registering it, not building a custom integration. When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp agents &lt;span class="nb"&gt;install &lt;/span&gt;gemini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenACP pulls the agent definition from the registry, resolves its distribution (npm, pip, or binary), and installs it. From that point on, you can spin up a Gemini session alongside your Claude Code session, each in its own Telegram topic or Discord thread.&lt;/p&gt;

&lt;p&gt;The typical setup: Claude Code running a longer task in one Telegram topic while you ask Gemini something quick in another. Same bridge, same interface, different agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick note: ACP is not MCP
&lt;/h2&gt;

&lt;p&gt;This confused me at first. Model Context Protocol (MCP) connects an AI model to tools — databases, APIs, browser automation. Agent Client Protocol (ACP) connects a user interface to a coding agent — prompts, streaming, permissions, sessions.&lt;/p&gt;

&lt;p&gt;They're complementary layers. Claude Code uses MCP internally to talk to tool servers, and speaks ACP externally to talk to whatever client is driving it — VS Code, a terminal, or OpenACP.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a session looks like end-to-end
&lt;/h2&gt;

&lt;p&gt;When I send "Fix the auth bug in middleware.ts" to my Telegram bot:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Telegram adapter&lt;/strong&gt; receives the message, identifies the session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session bridge&lt;/strong&gt; queues the prompt, routes it to the right agent instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent connection&lt;/strong&gt; sends &lt;code&gt;session/prompt&lt;/code&gt; to Claude Code via ACP&lt;/li&gt;
&lt;li&gt;Claude Code reads files → comes back as &lt;code&gt;tool_call&lt;/code&gt; events → streamed to Telegram&lt;/li&gt;
&lt;li&gt;Claude Code greps the codebase → &lt;code&gt;tool_call&lt;/code&gt; event → streamed&lt;/li&gt;
&lt;li&gt;Claude Code wants to write a fix → &lt;code&gt;request_permission&lt;/code&gt; → Approve/Deny button in Telegram&lt;/li&gt;
&lt;li&gt;I tap Approve from my phone&lt;/li&gt;
&lt;li&gt;Session bridge relays the approval → Claude Code writes the file → &lt;code&gt;end_turn&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total messages exchanged over ACP: dozens. Time I spent: one tap.&lt;/p&gt;

&lt;h2&gt;
  
  
  What stays local
&lt;/h2&gt;

&lt;p&gt;Everything except the model API call. Your code, sessions, config, and cost data stay on your machine. The agent calls Anthropic/Google/OpenAI for inference — that's the tradeoff — but the orchestration layer is fully yours. No relay, no third-party storing your session history.&lt;/p&gt;

&lt;p&gt;And because the bridge is protocol-based, swapping agents doesn't change anything else. Different subprocess, same messaging setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setup wizard handles the rest. &lt;a href="https://openacp.gitbook.io/docs/platform-setup" rel="noopener noreferrer"&gt;Platform guides in the docs.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;https://github.com/Open-ACP/OpenACP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://openacp.gitbook.io/docs" rel="noopener noreferrer"&gt;https://openacp.gitbook.io/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ACP registry: &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;https://agentclientprotocol.com/get-started/registry&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ACP spec: &lt;a href="https://agentclientprotocol.com/protocol/overview" rel="noopener noreferrer"&gt;https://agentclientprotocol.com/protocol/overview&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed. I'm a contributor to OpenACP — happy to answer questions about the architecture or the protocol integration.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>selfhosted</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Self-hosting AI coding agents: why it matters and how to do it</title>
      <dc:creator>psychomafia.tiger</dc:creator>
      <pubDate>Thu, 02 Apr 2026 03:28:04 +0000</pubDate>
      <link>https://forem.com/tigergethigher/self-hosting-ai-coding-agents-why-it-matters-and-how-to-do-it-2bd7</link>
      <guid>https://forem.com/tigergethigher/self-hosting-ai-coding-agents-why-it-matters-and-how-to-do-it-2bd7</guid>
      <description>&lt;p&gt;A few months ago I audited where my code was going.&lt;/p&gt;

&lt;p&gt;Not the deployed code. The code I was writing. Every snippet I pasted into a chat window, every file I attached to get a review, every prompt I sent while debugging at 2am - all of it passed through servers I had no visibility into. I wasn't paranoid about it. I just wanted to know.&lt;/p&gt;

&lt;p&gt;The answer was: a lot of places.&lt;/p&gt;

&lt;p&gt;That started me down the path of figuring out how to keep AI in my workflow without giving up control of what I was working on.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "self-hosted AI" actually means in 2026
&lt;/h2&gt;

&lt;p&gt;When people say self-hosted AI, they usually mean running a local model. Ollama, LM Studio, a quantized Llama on a machine with a decent GPU. That's one approach.&lt;/p&gt;

&lt;p&gt;But for coding work, local models still can't match Claude Code or Gemini CLI. Not in context windows, not in tool use, not in how well they understand large codebases.&lt;/p&gt;

&lt;p&gt;So I stopped thinking about self-hosting the model and started thinking about self-hosting everything around it.&lt;/p&gt;

&lt;p&gt;The agent runs on my machine. It reads my files locally. The API call goes to Anthropic or Google, I accept that tradeoff. But the session state, the conversation history, the permissions, the tooling layer? None of that needs to leave my control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pieces you actually want to own
&lt;/h2&gt;

&lt;p&gt;When you run &lt;code&gt;claude&lt;/code&gt; or &lt;code&gt;gemini&lt;/code&gt; in a terminal, the agent itself is already local. What's not local:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where you interact with it (usually a terminal you have to be physically at)&lt;/li&gt;
&lt;li&gt;How sessions are managed (you open and close them manually)&lt;/li&gt;
&lt;li&gt;How you approve or deny actions when you're not at your desk&lt;/li&gt;
&lt;li&gt;Whether you can run multiple agents in parallel&lt;/li&gt;
&lt;li&gt;Cost visibility (what did this session actually cost me?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are orchestration problems, not model problems. And orchestration is exactly what can and should be self-hosted.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenACP
&lt;/h2&gt;

&lt;p&gt;I started contributing to &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;OpenACP&lt;/a&gt; because it solves this specific layer.&lt;/p&gt;

&lt;p&gt;It's a self-hosted bridge that connects AI coding agents to Telegram, Discord, or Slack. You install it on your machine, point it at your workspace, and from that point on you interact with your agents through whatever messaging app you already use.&lt;/p&gt;

&lt;p&gt;The setup is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First run opens a setup wizard. You pick your platform, paste your bot token, choose a workspace, and pick a default agent. Takes about 5 minutes.&lt;/p&gt;

&lt;p&gt;After that, your Telegram (or Discord, or Slack) becomes the interface for your agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why messaging apps instead of a web UI
&lt;/h2&gt;

&lt;p&gt;I originally expected to build some kind of dashboard. But then I thought about when I actually need to interact with my agents: on my phone, on the bus, between meetings.&lt;/p&gt;

&lt;p&gt;I'm already in Telegram. My team is already in Discord. Building yet another web app to check on didn't make sense when the notification layer was already there.&lt;/p&gt;

&lt;p&gt;The practical upside is permission handling. If an agent wants to run &lt;code&gt;rm -rf&lt;/code&gt; or write to a sensitive file, it asks first. That prompt shows up as inline buttons in the chat, and I tap approve or deny from wherever I am. No need to rush back to a terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  One install, multiple agents
&lt;/h2&gt;

&lt;p&gt;OpenACP uses the &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;ACP registry&lt;/a&gt; to discover agents. Claude Code, Gemini CLI, Codex, Cursor, Cline, goose, and a bunch of others are all supported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp agents                     &lt;span class="c"&gt;# see what's available&lt;/span&gt;
openacp agents &lt;span class="nb"&gt;install &lt;/span&gt;gemini      &lt;span class="c"&gt;# install from registry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run different agents in different sessions at the same time. I usually have Claude Code running a longer task in one thread while I'm asking Gemini something quick in another. Each session gets its own topic/thread in the chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The daemon side
&lt;/h2&gt;

&lt;p&gt;Running this as a background service is what makes it actually useful day-to-day.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp start   &lt;span class="c"&gt;# start daemon&lt;/span&gt;
openacp stop    &lt;span class="c"&gt;# stop it&lt;/span&gt;
openacp status  &lt;span class="c"&gt;# check&lt;/span&gt;
openacp logs    &lt;span class="c"&gt;# tail logs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The daemon survives terminal sessions and starts on boot. Close your laptop, open it at a coffee shop, your agents are still there. Sessions persist too, so you reconnect and pick up where you left off.&lt;/p&gt;

&lt;p&gt;If something breaks, run &lt;code&gt;openacp doctor&lt;/code&gt;. It checks your config, bot token, agent installs, and daemon status, then tells you exactly what's wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  What stays private
&lt;/h2&gt;

&lt;p&gt;I want to be clear about what this doesn't do. The API calls to Anthropic or Google still happen. The model inference is not local.&lt;/p&gt;

&lt;p&gt;But here's what stays on your machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your code and files (the agent reads them locally)&lt;/li&gt;
&lt;li&gt;Your session history and conversation state&lt;/li&gt;
&lt;li&gt;Your config and credentials&lt;/li&gt;
&lt;li&gt;Your cost data and usage logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The orchestration layer is fully yours. There's no relay service sitting between you and your agent, and no vendor storing your session history on their end.&lt;/p&gt;

&lt;p&gt;The other side of this: if I decide to switch from Claude Code to Gemini for a project, I change one config value. The messaging setup, the sessions, the permissions, the cost tracking, all of that stays the same. I'm not locked into one agent vendor.&lt;/p&gt;

&lt;h2&gt;
  
  
  A typical day with this setup
&lt;/h2&gt;

&lt;p&gt;Morning. I open Telegram, send "review the PR on branch feature/auth" to my bot. Claude Code starts reading the diff, leaves comments in the chat. I read them on the train.&lt;/p&gt;

&lt;p&gt;Afternoon. I need to scaffold a new API endpoint. I open a second session, this time with Gemini. It generates the boilerplate, I review the output in Discord while in a meeting (don't tell my manager).&lt;/p&gt;

&lt;p&gt;Something fails in CI. I forward the error log to the bot, ask it to investigate. It greps through the codebase, finds the issue, proposes a fix. I approve the file write from my phone.&lt;/p&gt;

&lt;p&gt;End of day. &lt;code&gt;openacp api status&lt;/code&gt; shows me 3 sessions ran, roughly $4.20 in API costs. Everything's logged locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wizard asks 5 things: platform, bot token, workspace path, default agent, run mode. If you already have a Telegram bot from &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;, the whole thing takes under 5 minutes.&lt;/p&gt;

&lt;p&gt;For running it long-term, switch to daemon mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that it's just there. You message your bot and things happen.&lt;/p&gt;

&lt;p&gt;Detailed platform guides (Telegram, Discord, Slack) are in the &lt;a href="https://openacp.gitbook.io/docs/platform-setup" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;Source: &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;https://github.com/Open-ACP/OpenACP&lt;/a&gt;&lt;br&gt;
Docs: &lt;a href="https://openacp.gitbook.io/docs" rel="noopener noreferrer"&gt;https://openacp.gitbook.io/docs&lt;/a&gt;&lt;br&gt;
ACP registry: &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;https://agentclientprotocol.com/get-started/registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT licensed. I'm a contributor, happy to answer questions.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>selfhosted</category>
      <category>opensource</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>How to control Claude Code from Telegram, Discord, or Slack (self-hosted, open source)</title>
      <dc:creator>psychomafia.tiger</dc:creator>
      <pubDate>Wed, 01 Apr 2026 11:22:01 +0000</pubDate>
      <link>https://forem.com/tigergethigher/how-to-control-claude-code-from-telegram-discord-or-slack-self-hosted-open-source-1jk8</link>
      <guid>https://forem.com/tigergethigher/how-to-control-claude-code-from-telegram-discord-or-slack-self-hosted-open-source-1jk8</guid>
      <description>&lt;p&gt;My workflow broke the moment I stepped away from my desk.&lt;/p&gt;

&lt;p&gt;I had Claude Code running a large refactor. Left to grab lunch. By the time I came back, it had hit a permission prompt and been sitting idle for 15 minutes, waiting for me to press "yes" on a machine I wasn't at.&lt;/p&gt;

&lt;p&gt;That's why I started contributing to &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;OpenACP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Claude Code, Gemini CLI, Codex - these tools are powerful but they assume you're sitting at your terminal. The moment you're on your phone or away from your desk, you lose visibility and control.&lt;/p&gt;

&lt;p&gt;The workarounds people try: SSH into a tmux session (fragile on mobile), set up a VPN and remote desktop (slow), or just hope the agent doesn't get stuck. None of these are actually good.&lt;/p&gt;

&lt;p&gt;What I wanted: send a message from Telegram, see the agent's tool calls streaming in real time, and approve or deny actions from my phone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What OpenACP does
&lt;/h2&gt;

&lt;p&gt;OpenACP is a self-hosted bridge between your messaging platform and your AI coding agent. It uses the &lt;a href="https://agentclientprotocol.com" rel="noopener noreferrer"&gt;Agent Client Protocol (ACP)&lt;/a&gt; - an open standard for editor-agent communication - to connect agents like Claude Code, Gemini CLI, and Codex to Telegram, Discord, and Slack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You (Telegram / Discord / Slack)
  |
OpenACP (bridge + session manager)
  |
AI Agent (Claude Code, Codex, Gemini CLI, ...)
  |
Your Codebase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything runs on your machine. No cloud relay, no third party with access to your code, no subscription.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started: Claude Code on Telegram
&lt;/h2&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Node.js 20+ required. Claude Code needs to be installed separately.&lt;/p&gt;

&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First run opens an interactive setup wizard. It asks which platform you want (Telegram, Discord, Slack, or all three), your bot token, which workspace directory to use, which agent to default to, and whether to run in foreground or daemon mode.&lt;/p&gt;

&lt;p&gt;For Telegram you need a bot token from &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;. The wizard validates the token and auto-detects your chat ID - no config file editing.&lt;/p&gt;

&lt;p&gt;Once running, send any message to your bot. OpenACP creates a session, spawns Claude Code as an ACP subprocess, and streams everything back.&lt;/p&gt;

&lt;p&gt;Each session gets its own forum topic. You can run multiple agents in parallel, each in its own topic or thread depending on the platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1k83dzxga4eq7gf72z0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1k83dzxga4eq7gf72z0.png" alt="Control Panel showing OpenACP in Telegram with session management buttons" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What a session looks like
&lt;/h2&gt;

&lt;p&gt;When the agent is working, you see the tool calls as they happen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsv1dt9ggejljjgpoah2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsv1dt9ggejljjgpoah2.png" alt="Agent actively reading files, writing plans, dispatching tasks in real time" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;File reads, writes, grep calls, terminal commands - all streamed to your chat. If the agent needs to do something that requires approval, you get inline buttons in the message: Approve or Deny, right there on your phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtcsjenspi3u1ju1joxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtcsjenspi3u1ju1joxs.png" alt="Streaming tool calls including grep, Read File, Terminal, and Task" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's the thing that actually solved the lunch problem for me. I can now watch a long task from my phone and unblock it the moment it pauses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other agents
&lt;/h2&gt;

&lt;p&gt;OpenACP isn't specific to Claude Code. It works with any agent that supports ACP, which now covers most of the major ones.&lt;/p&gt;

&lt;p&gt;To use Gemini CLI from Telegram or Discord, install it the same way - same interface, same streaming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp agents &lt;span class="nb"&gt;install &lt;/span&gt;gemini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Browse everything available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openacp agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The list includes Claude Code, Gemini CLI, Codex CLI, GitHub Copilot, Cursor, Cline, goose, Qwen Code, JetBrains Junie, and more. OpenACP pulls directly from the &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;ACP registry&lt;/a&gt;, so new agents become available as soon as they register.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydq9o1ysuyrxpct1aeqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydq9o1ysuyrxpct1aeqg.png" alt="Skills system showing a brainstorming skill being launched with detailed exploration output" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform support
&lt;/h2&gt;

&lt;p&gt;Telegram, Discord, and Slack are all stable. Each uses platform-native patterns: forum topics in Telegram, threads in Discord, channels and threads in Slack. You can run all three at once pointing to the same agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it compares to the alternatives
&lt;/h2&gt;

&lt;p&gt;Two tools people usually ask about when they see OpenACP:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;claude-code-telegram&lt;/code&gt; (the original one most people start with) is single-agent, Telegram only, no multi-session support. Fine for the basic use case.&lt;/p&gt;

&lt;p&gt;Claude Code Channels is Anthropic's official remote access feature - cloud-based, tied to Claude Code specifically. Not self-hosted.&lt;/p&gt;

&lt;p&gt;OpenACP is different in that it supports multiple agents and multiple platforms from one install, and everything stays on your machine. The tradeoff is that you have to self-host it. If that's too much friction, Claude Code Channels is the easier path.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few practical things
&lt;/h2&gt;

&lt;p&gt;Daemon mode: &lt;code&gt;openacp start&lt;/code&gt; runs it as a background service. &lt;code&gt;openacp stop&lt;/code&gt;, &lt;code&gt;openacp status&lt;/code&gt;, and &lt;code&gt;openacp logs&lt;/code&gt; handle the rest.&lt;/p&gt;

&lt;p&gt;Tunnels: if an agent needs to expose a local port (say a dev server at 3000), &lt;code&gt;openacp tunnel add 3000&lt;/code&gt; handles it via Cloudflare Tunnel, ngrok, bore, or Tailscale.&lt;/p&gt;

&lt;p&gt;Session handoff: if you're working in the terminal and want to continue on your phone, the &lt;code&gt;/openacp:handoff&lt;/code&gt; integration transfers the session without losing context. Needs to be set up first with &lt;code&gt;openacp integrate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Usage tracking: optional token counting and cost reports per session. You can set a monthly budget limit that pauses the agent when hit.&lt;/p&gt;

&lt;p&gt;Doctor: &lt;code&gt;openacp doctor&lt;/code&gt; checks your daemon, bot token, agent installation, storage, and tunnel config, and tells you exactly what's broken if something isn't working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openacp/cli
openacp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source and issues: &lt;a href="https://github.com/Open-ACP/OpenACP" rel="noopener noreferrer"&gt;https://github.com/Open-ACP/OpenACP&lt;/a&gt;&lt;br&gt;
Docs (platform setup guides): &lt;a href="https://openacp.gitbook.io/docs" rel="noopener noreferrer"&gt;https://openacp.gitbook.io/docs&lt;/a&gt;&lt;br&gt;
ACP registry (browse agents): &lt;a href="https://agentclientprotocol.com/get-started/registry" rel="noopener noreferrer"&gt;https://agentclientprotocol.com/get-started/registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT licensed. I'm a contributor. Happy to answer questions below.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>opensource</category>
      <category>telegram</category>
    </item>
  </channel>
</rss>
