A starter template for building new interfaces for Project Instar. Use this as a base to connect your bot to any messaging platform, API, or communication channel.
An interface is an always-on service that bridges an external platform (Slack, Discord, a custom API, etc.) to your Instar bot. Every interface follows the same message flow:
External platform message
└─► Your interface (this code)
├─► Gatekeeper /process → strips passphrases, resolves tools
├─► Bot /chat → LLM generates response with tools
├─► Gatekeeper /record-response → logs conversation history
└─► Send response back to platform
The template provides this entire flow as a ready-to-use handle_message() function. You just need to write the platform-specific connection logic.
# Clone the template
git clone https://github.com/thegman54/instar-template-interface.git my-interface
cd my-interface
# Rename references
# Replace "my_interface" with your interface name in:
# - manifest.yaml (name, display_name, container_name)
# - docker-compose.yml (container_name, port)
# - src/api.py (conversation_id prefix, source name, app title)name: my_interface # lowercase, underscores ok
display_name: My Interface # human-readable
description: What this interface connects to
version: "1.0"
type: interface
connection:
pattern: websocket # or: socket_mode, webhook, unix_socket
port: 8085 # your API port
container_name: my_interface-api
credentials:
- MY_API_KEY # list every secret this interface needs
- MY_API_SECRETEdit src/api.py:
In the lifespan() function — connect to your platform:
@asynccontextmanager
async def lifespan(app: FastAPI):
# Connect to your platform here
# e.g., start a WebSocket, authenticate, subscribe to events
yield
# Clean up hereCreate a message handler that calls handle_message():
async def on_platform_message(platform_event):
await handle_message(
conversation_id="unique-thread-id",
user_id="sender-identifier",
message="the message text",
send_response_func=lambda text: send_to_platform(text),
)Add platform-specific endpoints if needed:
@app.post("/webhook")
async def webhook(request: Request):
# For webhook-based platforms (WhatsApp, custom APIs)
...Edit requirements.txt to add platform-specific packages:
# Already included:
fastapi>=0.100.0
uvicorn>=0.22.0
httpx>=0.24.0
structlog>=23.1.0
# Add yours:
slack-bolt>=1.18.0 # for Slack
discord.py>=2.3.0 # for Discord
tweepy>=4.14.0 # for Twitter/X
docker compose up --buildCheck health: curl http://localhost:8085/health
Option A — Admin UI upload:
- Zip the directory
- Upload via Interfaces > Upload Interface in the Admin UI
Option B — Manual:
cp -r my-interface/ /path/to/project-instar/tools/my_interface/The stack manager auto-discovers it via manifest.yaml.
| Pattern | Description | Examples |
|---|---|---|
socket_mode |
Outbound WebSocket, no public URL needed | Slack Socket Mode |
websocket |
Outbound WebSocket to external service | Zoom, RegisterABot |
webhook |
Inbound HTTP, needs public URL (tunnel) | WhatsApp, custom APIs |
unix_socket |
Local Unix socket to sidecar process | Signal (via signald) |
my-interface/
├── manifest.yaml # Required — Instar auto-discovery + BotGlaze metadata
├── Dockerfile # Container build
├── docker-compose.yml # Service definition + networks
├── requirements.txt # Python dependencies
└── src/
├── __init__.py
└── api.py # Your interface code (handle_message already implemented)
The template's handle_message() function does all the heavy lifting:
-
POST
/processto Gatekeeper — sends the raw message with conversation context- Gatekeeper extracts passphrases, looks up grants, returns cleaned message + available tools
- If the message was only a passphrase, responds with "Tools now available: ..."
-
POST
/chatto Bot Service — sends cleaned message + tool list- Bot processes with Claude (or your LLM) using the granted tools
- Returns the response text
-
Send response — calls your
send_response_functo deliver the reply -
POST
/record-responseto Gatekeeper — logs the response for conversation history
You don't need to reimplement this flow. Just call handle_message() with the right parameters from your platform-specific code.
To make your interface discoverable on BotGlaze:
- Push your repo to GitHub
- Add the topic
botglazeto your repo - Ensure
manifest.yamlis at the repo root - Your interface will appear in BotGlaze search automatically
For working examples, see:
- instar-interface-slack — Socket Mode
- instar-interface-zoom — WebSocket + OAuth + Tunnel
- instar-interface-whatsapp — Webhook
- instar-interface-registerabot — WebSocket relay
MIT