Plugin Metadata
The unique plugin identifier
Human-readable plugin name
Invite-based web chat for friends — powered by FRIENDS.md
Plugin type
Current plugin version
User ID prefix for friends (format:
friend:<username>)Setup
1. Enable the Plugin
2. Invite a Friend
3. Share the Invite
Share the invite URL or code with your friend. When they open the link:- The invite code is automatically consumed
- They receive a session cookie for authentication
- They can start chatting immediately
Configuration
Config Keys
Enable/disable the Friends Chat plugin
HTTP server port for the web chat interface
Server hostname (can be overridden via
HOST environment variable)Base URL for generating invite links. Defaults to
http://localhost:{port} if not set.
Set this to your public URL when deploying: https://yourdomain.comDatabase
Friend data is stored in a SQLite database:Stores friend profiles, invite codes, session tokens, and activity timestamps
Pairing Tools
The plugin provides four owner-only tools for managing friend access:friends_chat_invite
Create a new friend and generate an invite link.
Unique username for the friend (2-32 characters, lowercase alphanumeric + underscores).
This is permanent and identifies the friend in FRIENDS.md.
Optional display name for the friend. Defaults to the username.
The friend can change this later.
friends_chat_reinvite
Generate a new invite code for an existing friend. Use this when a friend switches browsers, clears cookies, or loses access.
The username of the existing friend to re-invite
friends_chat_revoke
Revoke a friend’s access to the chat. Their session and invite code are immediately invalidated.
The username of the friend to revoke
friends_chat_list
List all registered friends and their status.
Parameters: None
Returns: Formatted list showing:
- Username and nickname
- Status (active, invite pending, or revoked)
- Last seen timestamp
API Methods
start(context: PluginRuntimeContext)
Initializes the Friends Chat server and starts listening for connections.
Runtime context providing:
enqueue()- Queue messages to the agentagentContext- Agent configurationsecrets- Secrets managerconfigManager- Config manager
- Checks if plugin is enabled
- Initializes InviteStore with SQLite database
- Creates HTTP server with WebSocket support
- Loads embedded chat HTML interface
- Routes all friend messages through
context.enqueue(userId, message) - Logs server URL for access
GET /chat- Web chat interfaceGET /chat?invite=<code>- Invite redemption + authenticationPOST /api/chat- Send message to agentGET /api/stream- Server-Sent Events for real-time updates
sendToUser(userId: string, message: OutboundMessage)
Send a proactive message to a friend (“nudge”).
Friend user ID in format
friend:<username>Message object containing:
content- Text content to sendsource- Source of the message (e.g., “background-agent”)priority- Message priority level
Promise<void>
Behavior:
- Parses username from userId
- Pushes message to user’s active push connections
- Logs warning if user has no active connections
- Throws error if server is not running
stop()
Gracefully shuts down the Friends Chat server.
Returns: Promise<void>
Behavior:
- Stops HTTP server
- Closes all WebSocket connections
- Closes SQLite database
- Logs shutdown
getPairingTools(secrets, configManager)
Returns the four friend management tools for agent integration.
Secrets manager (not currently used by Friends plugin)
Config manager for plugin settings and base URL
Tool[] - Array of friend management tools
Architecture
Authentication Flow
-
Owner invites friend
- Agent calls
friends_chat_invite({ username: "john" }) - Plugin generates random invite code
- Code stored in database with username
- Agent calls
-
Friend clicks invite link
- Opens
http://localhost:3001/chat?invite=abc123 - Server validates invite code
- If valid: generates session token, sets cookie, deletes invite code
- Friend redirected to chat interface
- Opens
-
Friend chats
- All requests include session cookie
- Server validates session token
- Messages routed to agent as
friend:<username>
-
Session lost
- Friend clears cookies or switches browser
- Owner runs
friends_chat_reinvite({ username: "john" }) - New invite code generated, old session invalidated
Message Routing
All friend messages are routed through the agent loop with thefriend: prefix:
Real-time Updates
The plugin supports Server-Sent Events (SSE) for real-time message delivery:User ID Format
Friends are identified with a prefixed format:friend:john_smith
This prefix:
- Isolates friend sessions from other channels
- Maps to the username stored in FRIENDS.md
- Used for authority tier determination (friend vs owner)
Usage Examples
Owner Invites a Friend
Friend Loses Access
Checking Friend Status
Revoking Access
InviteStore
The plugin uses a SQLite-backed InviteStore to manage friend data:createFriend(username, nickname?)- Create new friend with inviteregenerateInvite(username)- Generate new invite, invalidate sessionrevokeFriend(username)- Clear invite and sessionlistFriends()- Get all friends with statusexists(username)- Check if username is taken
Security
- Single-use invites - Each invite code can only be redeemed once
- Session cookies - HTTP-only, secure cookies for authentication
- Username validation - Only alphanumeric + underscores, 2-32 chars
- Owner-only tools - All management tools protected by authority system
- Session invalidation - Old sessions cleared when generating new invite
- Database isolation - Friend data stored in dedicated SQLite file
FRIENDS.md Integration
The Friends Chat plugin is designed to work with FRIENDS.md, a document where the agent stores notes about each friend:- Agent can recall friend preferences and history
- Each friend has persistent identity via username
- Agent treats friends differently than owner (chat only, no system commands)
- Authority tier automatically determined by userId prefix
Error Handling
- Plugin not enabled: Logs info message, no-op
- Database errors: Propagates SQLite errors with context
- Invalid username: Returns descriptive error message
- Duplicate username: Suggests using
friends_chat_reinvite - User not found: Clear error messages for revoke/reinvite
- No active connections: Logs warning when pushing to offline friend
- Server not running: Throws error if sendToUser called before start
Dependencies
@tinyclaw/logger- Logging utilities@tinyclaw/types- Type definitions- Built-in
httpandcryptomodules - SQLite3 (via better-sqlite3 or similar)