#Open Claude Code Channels

1 messages · Page 1 of 1 (latest)

main tapir
#

I'm running a local OpenClaw gateway (profile oppusy, port 18790) and bridging a Telegram bot (@Oppusy_bot) into Claude Code via openclaw mcp serve --claude-channel-mode on. The Claude
▎ Code session receives inbound messages correctly via notifications/claude/channel and replies back via the bridge's messages_send tool.

▎ Problem: The gateway also runs an embedded agent (main) on every inbound Telegram message. When that embedded agent fails (auth missing, rate limit, etc.), it sends the error text back
▎ to the Telegram user as a reply — duplicating or conflicting with the Claude Code MCP bridge reply.

▎ Goal: I want this gateway profile to be bridge-only for the Telegram account oppusy — inbound messages should be visible to the MCP bridge session only, and the gateway should NOT
▎�invoke any embedded agent to auto-reply.

▎ I've tried:
▎�- Removing bindings[] entirely — default agent still runs
▎ - Binding to a non-existent agent — still falls through to default main
▎ - Setting agents.defaults.embeddedHarness.fallback: "none" — embedded agent still runs

  • Setting runtime: { type: "acp", acp: { agent: "/usr/bin/true" } } on main
    What is the correct, documented config to disable embedded agent auto-reply on a channel account while keeping the MCP bridge able to read/send through openclaw mcp serve? Is there an
    autoReply: false, a specific runtime type, or a channels.telegram.accounts.<name>.mode: "bridge" setting? Please quote the exact JSON config.
dusky monolithBOT
hearty breachBOT
#

Short answer: no, there is not currently a documented Telegram setting like autoReply: false, channels.telegram.accounts.<name>.mode: "bridge", or a runtime type that makes openclaw mcp serve --claude-channel-mode on truly bridge-only.

What I found:

  • autoReply is surfaced for Matrix rooms, not Telegram.
  • Your fallback behavior is expected:
    • resolveAgentRoute(...) falls back to resolveDefaultAgentId(...)
    • pickFirstExistingAgentId(...) falls back to the default agent if the bound agent does not exist

So removing bindings, using a missing agent, or changing embeddedHarness.fallback will not stop main from being chosen.

The closest supported config, if your goal is “Claude Code bridge replies, OpenClaw does not reply to Telegram”, is session.sendPolicy:

{
  session: {
#
    sendPolicy: {
      default: "allow",
      rules: [
        { action: "deny", match: { channel: "telegram" } }
      ]
    }
  }
}

That suppresses Telegram outbound delivery from the embedded agent, including error replies, while inbound still processes and the MCP bridge can still receive notifications/claude/channel and use messages_send.

Important caveat: this is not true bridge-only. The embedded agent still runs, it just cannot send a user-visible Telegram reply.

If you need it scoped only to Telegram DMs for account oppusy, the closest supported variant is:

#
{
  session: {
    dmScope: "per-account-channel-peer",
    sendPolicy: {
      default: "allow",
      rules: [
        { action: "deny", match: { rawKeyPrefix: "agent:main:telegram:oppusy:direct:" } }
      ]
    }
  }
}

Notes:

  • this only covers DMs
  • it assumes the routed agent is still main
#
  • there is no documented account-specific “bridge-only” switch for all Telegram traffic/groups today

If you only want to stop the error text leak, but not all auto-replies, there is also:

{
  channels: {
    telegram: {
      accounts: {
        oppusy: {
          errorPolicy: "silent"
        }
      }
    }
  }
}
hearty breachBOT
#

I checked the current source for this. The canonical resolution path is:

  1. channels.telegram.accounts.<accountId>.groups["<chatId>"].requireMention
  2. channels.telegram.accounts.<accountId>.groups["*"].requireMention
  3. channels.telegram.groups["<chatId>"].requireMention
  4. channels.telegram.groups["*"].requireMention
  5. fallback default: true

The important gotcha is this part in src/config/group-policy.ts:

  • resolveChannelGroups(...) does accountGroups ?? channelConfig.groups
  • so if channels.telegram.accounts.oppusy.groups exists at all, that account-scoped groups object wins
  • it is not deep-merged with top-level channels.telegram.groups

So for a single named Telegram account, the safest working config is to make the account explicit and keep the setting only there:

#
{
  channels: {
    telegram: {
      defaultAccount: "oppusy",
      accounts: {
        oppusy: {
          groupPolicy: "open",
          groups: {
            "*": { requireMention: false },
            "-5228864433": {
              requireMention: false,
              groupPolicy: "open"
            }
          }
        }
#
      }
    }
  }
}

A few direct answers:

  • No, there is no hidden channels.telegram.defaults.* requireMention layer.
  • No, plugins.entries.telegram.config.* is not the canonical path here.
  • session.groupActivation can override behavior only if that session was changed with /activation ..., otherwise it is not the source of truth.
  • If none of the above resolves, the final fallback is just true.

So if you are still getting:

main tapir
#

That didn't work. Could you help me figure out what exactly is the problem? Currently, I am getting messages in the DM, but nothing in the group.

hearty breachBOT
#

Yeah, I think we can narrow this down.

That log means the bot is receiving the group message. So this is not a Telegram visibility/privacy problem anymore. It is being dropped after inbound, at mention gating.

The important bit is that the Telegram handler hot-loads config on each message, then does roughly:

  • load fresh Telegram account config
  • read groups[chatId] ?? groups["*"]
  • compute requireMention
  • skip with reason:"no-mention" if it still resolves truthy

So if you still get that log, the problem is almost certainly one of these:

  1. the running gateway is using a different config file/profile than the one you edited
  2. the effective Telegram account is not actually oppusy
  3. an account-scoped groups object is shadowing your top-level channels.telegram.groups
  4. less likely, there is a real bug/regression in 2026.4.14
#

For a clean test, I would remove all top-level Telegram group config and use only this minimal account-scoped block:

{
  channels: {
    telegram: {
      defaultAccount: "oppusy",
      accounts: {
        oppusy: {
          groupPolicy: "open",
          groups: {
            "-5228864433": {
              requireMention: false,
              groupPolicy: "open"
            }
          }
#
        }
      }
    }
  }
}

A couple of key notes:

  • do not keep parallel channels.telegram.groups entries during this test
  • if accounts.oppusy.groups exists, that is the config I would trust first
  • you should not need a restart for this specific check, because the Telegram handler re-reads config

What I’d like from you next, because it will make this decisive:

  1. openclaw gateway status
#
  1. openclaw status --all
  2. paste the sanitized channels.telegram block from the exact config path that gateway status reports

If those outputs show the gateway is reading the same file, and that minimal block still logs reason:"no-mention", then I’m pretty convinced it’s a bug in 2026.4.14, not a hidden config key.

main tapir
#

Can you give me the exact JSON for setting this up that you know is proven to work? Also, can you check if plot code channels with openClaw MCP server work with dm and group at the same time?

hearty breachBOT
#

One correction from my earlier reply, session.sendPolicy: "deny" is not the right bridge-only config here, because it also blocks MCP messages_send. I checked the gateway send path.

So, the exact JSON I’d use for a known-supported Telegram DM + group + MCP setup is this:

{
  channels: {
    telegram: {
      defaultAccount: "oppusy",
      accounts: {
        oppusy: {
          enabled: true,
          botToken: "YOUR_TELEGRAM_BOT_TOKEN",

          dmPolicy: "pairing",
#
          groupPolicy: "open",
          errorPolicy: "silent",

          groups: {
            "-5228864433": {
              groupPolicy: "open",
              requireMention: false,
              errorPolicy: "silent"
            }
          }
        }
      }
    }
  }
}
#

What this does:

  • DMs are allowed via pairing
  • that group is allowed
  • group messages in -5228864433 do not require mention
  • embedded-agent error replies are suppressed with errorPolicy: "silent"
  • MCP notifications/claude/channel + messages_send can still work

Important caveat:

  • this is not true bridge-only
  • I do not see a supported exact JSON today for:
    • MCP can read/send
    • embedded agent never sends any successful reply at all

For that exact behavior, I think the honest answer is still: not currently supported as a documented mode