Files
VuongKB/infrastructure/vm-102-matrix-appservice.md
T

154 lines
4.4 KiB
Markdown

---
created: '2026-04-11T16:32:18+00:00'
id: 95ffbaa1-728e-434c-85d9-e82346f77d1e
keywords:
- matrix.pfi.local
- appservice
- as_token
- hs_token
- aipa-bridge
- matrix_bridge.py
- '8009'
- send_notification
- virtual-users
- room-routing
- element
links: []
modified: '2026-04-11T16:32:18+00:00'
summary: AIPA Matrix Application Service bridge setup for VM 102. Covers appservice
registration, agent virtual users, room routing, env vars, operational notes, and
troubleshooting.
tags:
- infrastructure
- pfi
- pfi-ana
- matrix
- docker
- vm-102
- appservice
- bridge
- aipa
- deployment
- integration
title: VM 102 — Matrix Appservice Configuration
---
The AIPA Matrix bridge registers with Synapse as an Application Service. Synapse pushes events to the bridge (no polling). The bridge manages virtual users for each agent.
## Agent Virtual Users
| Agent | Matrix ID | Display Name |
|---|---|---|
| Atlas | @atlas:matrix.pfi.local | Atlas |
| Linus | @linus:matrix.pfi.local | Linus |
| Hermione | @hermione:matrix.pfi.local | Hermione |
These are virtual — managed entirely by the bridge. Do not register them as real Synapse accounts.
## Setup Steps
### 1. Generate tokens
```bash
python3 -c "import secrets; print(secrets.token_hex(32))" # as_token (bridge → Synapse)
python3 -c "import secrets; print(secrets.token_hex(32))" # hs_token (Synapse → bridge)
```
### 2. Create appservice registration
File: /opt/docker/data/synapse/aipa_appservice.yaml
```yaml
id: aipa-bridge
url: http://<BRIDGE_HOST_IP>:8009
as_token: "<AS_TOKEN>"
hs_token: "<HS_TOKEN>"
sender_localpart: aipa-bot
namespaces:
users:
- exclusive: true
regex: "@(atlas|linus|hermione):.*"
rooms: []
aliases: []
rate_limited: false
```
exclusive: true means only the bridge can act as those users. url must be reachable from inside the Synapse container.
Restart Synapse: `cd /opt/docker/compose/synapse && docker compose restart synapse`
### 3. Configure AIPA environment
Add to env.sh:
```bash
export MATRIX_HOMESERVER_URL="http://localhost:8008"
export MATRIX_SERVER_NAME="matrix.pfi.local"
export MATRIX_AS_TOKEN="<as_token>"
export MATRIX_HS_TOKEN="<hs_token>"
# export MATRIX_DEFAULT_ROOM="!roomid:matrix.pfi.local"
```
Uncomment matrix: block in config/providers.yaml:
```yaml
matrix:
homeserver_url: "${MATRIX_HOMESERVER_URL}"
server_name: "${MATRIX_SERVER_NAME}"
as_token: "${MATRIX_AS_TOKEN}"
hs_token: "${MATRIX_HS_TOKEN}"
bridge_host: "0.0.0.0"
bridge_port: 8009
default_notification_room: "${MATRIX_DEFAULT_ROOM}"
agents:
atlas:
display_name: "Atlas"
linus:
display_name: "Linus"
hermione:
display_name: "Hermione"
```
### 4. Start bridge
```bash
source .venv/bin/activate && source env.sh
python -m core.matrix_bridge
```
### 5. First use
1. Open Element at http://10.250.50.70:8080
2. Log in with admin account (server: matrix.pfi.local)
3. DM @atlas:matrix.pfi.local
4. Send a message — bridge routes to Atlas
## Room Routing
1. User invites agent to room → bridge receives m.room.member invite
2. Agent auto-joins
3. Room permanently mapped to that agent in sessions/matrix_rooms.json
4. All subsequent messages routed to mapped agent
5. Multiple agents in same room: first invite wins for session, others get their own session
## Operational Notes
- Session persistence: rooms mapped in sessions/matrix_rooms.json survive restarts. Reset with /reset or delete entry.
- Formatting: markdown→HTML conversion (format: org.matrix.custom.html)
- Typing indicators: bridge sends m.typing while agent processes
- Proactive notifications: agents call send_notification(content, channel="!roomid:matrix.pfi.local")
- Virtual users always show offline — expected, no presence for appservice users
## Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Synapse doesn't push events | Appservice URL wrong | Verify url reachable from Synapse container |
| Agent joins but doesn't respond | hs_token mismatch | Verify token matches MATRIX_HS_TOKEN |
| 401 errors from Synapse | as_token mismatch | Verify token matches MATRIX_AS_TOKEN |
| Messages loop | Bridge not filtering own messages | Check SENDER_LOCALPART filter |
| Agent always offline | Expected | Normal for virtual users |
## Dependencies
- markdown (pip install markdown)
- fastapi, httpx
## Security
- as_token and hs_token are admin-equivalent secrets
- Bridge authenticates Synapse pushes via MATRIX_HS_TOKEN (rejects 403 without it)
- Restrict port 8009 to internal access only