Skip to main content

Universal gateway connecting AI agent runtimes to messaging platforms

Project description

HarnessGate (Python)

Connect any AI agent runtime to any messaging platform.

License Python


Why HarnessGate?

Existing chatbot frameworks run their own agent loop — they call LLM APIs, parse tool calls, execute tools locally, and manage context. When you connect them to a managed agent runtime like Claude Managed Agents, they have to bypass their entire infrastructure just to pipe messages through.

HarnessGate takes a different approach: no local agent loop. It's a pure bridge that delegates all intelligence to the provider runtime. The gateway just routes messages between platforms and the agent.

This means:

  • Claude Managed Agents features work out of the box (tool confirmation, custom tools, multi-agent threads, extended thinking)
  • Any future agent runtime plugs in with 4 methods
  • No competing agent loops, no bypassed infrastructure, no wasted abstractions
[Telegram] [Discord] [Slack] [WhatsApp] [Teams] [Web UI]
     |         |        |       |          |       |
     +----+----+----+---+-------+----------+------+
          |         |
     PlatformAdapter ABC (per platform)
          |         |
          +----+----+
               |
          Bridge (orchestrator)
          SessionStore + StreamManager
               |
        Provider ABC
               |
    +----------+----------+
    | Claude   | Custom   |
    | Managed  | (your    |
    | Agents   |  class)  |
    +----------+----------+

Features

  • Provider-agnostic — Claude Managed Agents or bring your own
  • 6 platform adapters — Telegram, Discord, Slack, WhatsApp, Teams, Web UI
  • Multi-app — run multiple bot instances per platform, each mapped to a different agent
  • Session management — automatic session creation, in-memory persistence, multi-turn conversations
  • Buffer-then-send — accumulates agent responses, sends as one message per turn
  • Auto-split — respects per-platform message length limits
  • Fully async — built on asyncio with async/await throughout

Quick Start

pip install harnessgate
import asyncio
from harnessgate import Bridge, BridgeConfig
from harnessgate.providers import ClaudeProvider
from harnessgate.platforms import TelegramAdapter

async def main():
    provider = ClaudeProvider(api_key="sk-ant-...")
    bridge = Bridge(
        provider=provider,
        config=BridgeConfig(platforms={"telegram": {"enabled": True}}),
    )

    # Route users to agents
    async def resolve_user(sender, platform, message):
        return {
            "user_id": sender.id,
            "agent_id": "agent_01XXXX",
            "environment_id": "env_01XXXX",
        }

    bridge.set_user_resolver(resolve_user)
    bridge.add_platform(TelegramAdapter())

    await bridge.connect("telegram", {"bot_token": "123:ABC..."})
    await bridge.start()

asyncio.run(main())

Platform Adapters

Platform Library Max text Markdown Threads Typing Attachments
Telegram aiogram 3.x 4096 Yes Yes Yes Yes
Discord discord.py 2000 Yes Yes Yes Yes
Slack slack-bolt 4000 Yes Yes No Yes
WhatsApp Cloud API (aiohttp) 4096 No No No Yes
Teams Bot Framework SDK 28000 Yes Yes Yes Yes
Web Built-in (aiohttp) 100000 Yes No Yes No

Platform Setup Guides

Detailed setup instructions for each platform, including SaaS multi-tenant distribution:

Provider Setup

Claude Managed Agents

from harnessgate.providers import ClaudeProvider

provider = ClaudeProvider(api_key="sk-ant-...")

Connects to Claude Managed Agents. Full support for streaming, tool confirmation, custom tools, extended thinking, and multi-agent threads.

For Claude, agent_id and environment_id come from your UserResolver, not static provider config:

async def resolve_user(sender, platform, message):
    return {
        "user_id": sender.id,
        "agent_id": "agent_01XXXX",
        "environment_id": "env_01XXXX",
    }

Custom provider

Implement the Provider ABC:

from harnessgate import Provider

class MyProvider(Provider):
    id = "my-provider"
    capabilities = ProviderCapabilities(
        interrupt=False,
        tool_confirmation=False,
        custom_tools=False,
        thinking=False,
    )

    async def create_session(self, opts): ...
    async def send_message(self, session_id, message): ...
    async def stream(self, session_id): ...  # AsyncIterator[ProviderEvent]
    async def destroy_session(self, session_id): ...

Multi-Bot / appId

Every platform adapter supports running multiple app instances simultaneously. Each app connects to the platform and receives a platform-assigned appId.

# Add multiple Telegram bots at runtime
support_id = await bridge.connect("telegram", {"bot_token": SUPPORT_TOKEN})
sales_id = await bridge.connect("telegram", {"bot_token": SALES_TOKEN})

# Route based on which bot received the message
async def resolve_user(sender, platform, message):
    agent_id = await db.get_agent_for_bot(message.app_id)
    environment_id = await db.get_environment_for_bot(message.app_id)
    return {"user_id": sender.id, "agent_id": agent_id, "environment_id": environment_id}

appId per platform

Platform Source Example value
Telegram bot.id "123456789"
Discord client.application_id "1098765432101234567"
Slack auth_test().bot_id "A0123456789"
WhatsApp WABA phone number ID "106540352267890"
Teams activity.recipient.id "28:abc123..."
Web N/A (single instance) --

Session Management

Each conversation context gets its own provider session:

Context Session scope Example key
DM Per user telegram:direct:123:u:user99
Group/Channel Shared (all users) slack:group:ch1
Thread Per thread discord:thread:ch1:t:thread99

Project Structure

harnessgate-py/
├── src/harnessgate/
│   ├── __init__.py             # Public API exports
│   ├── bridge.py               # Orchestrator
│   ├── messages.py             # InboundMessage, OutboundMessage, Sender, Attachment
│   ├── platform.py             # PlatformAdapter ABC
│   ├── provider.py             # Provider ABC + ProviderEvent types
│   ├── session.py              # SessionStore, MemorySessionStore
│   ├── stream.py               # StreamManager
│   ├── platforms/
│   │   ├── telegram.py         # aiogram 3.x
│   │   ├── discord.py          # discord.py
│   │   ├── slack.py            # slack-bolt
│   │   ├── whatsapp.py         # Cloud API (aiohttp)
│   │   ├── teams.py            # Bot Framework SDK
│   │   └── web.py              # Built-in HTTP + SSE
│   └── providers/
│       └── claude.py           # Claude Managed Agents
├── tests/                      # pytest test suite
├── docs/                       # Platform setup guides
├── examples/                   # Starter projects
└── pyproject.toml

Requirements

  • Python >= 3.11
  • uv (recommended) or pip

Development

uv sync
uv run pytest
uv run pyright     # type checking

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

harnessgate-0.1.0.tar.gz (134.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

harnessgate-0.1.0-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file harnessgate-0.1.0.tar.gz.

File metadata

  • Download URL: harnessgate-0.1.0.tar.gz
  • Upload date:
  • Size: 134.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.17

File hashes

Hashes for harnessgate-0.1.0.tar.gz
Algorithm Hash digest
SHA256 38fc0c310609c561e5380e7cdbedb85704824d63dff86ceeb57ad5688da73121
MD5 c2717a7bf00ddb896ab33c6bd0143e84
BLAKE2b-256 a4f796a149338e0951629d7858bdaab33c4a296ae675b1332408d7ad972e8751

See more details on using hashes here.

File details

Details for the file harnessgate-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for harnessgate-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8cda31f738877caf49bf89c44d53d67aaeb756cf51f812e8bd7acb69a211a95c
MD5 8753ab99cad07fa6c1b59d42f5ffa21c
BLAKE2b-256 d4aa85e56cadae424a4ce851a0c3bd828b37a1c4b0089e54c7e7b40215829cef

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page