Pondchat
Ephemeral P2P WebRTC video rooms — create a pond, share the link, talk.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"pondchat": {
"url": "https://pondchat.com/api/mcp"
}
}
}Remote endpoints
https://pondchat.com/api/mcpstreamable-httpWhat it can do
Tool inventory
Tools (6)
🟡create_pond(roomId, label, source)
Mint a new Pondchat room (pond) for video/audio/chat. Returns room URL and WebSocket endpoint. This is the only way to create a room — for metadata of an existing roomId, use get_room_info (read-only). Note: a custom roomId is not reserved — if another pond already uses it, you share the same door.
Input Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string",
"description": "Optional custom room ID (3-64 chars, alphanumeric + _-). If not provided, a random ID is generated.",
"pattern": "^[A-Za-z0-9_-]{3,64}$"
},
"label": {
"type": "string",
"description": "Optional label for the room (max 64 chars). Useful for identifying the room purpose.",
"maxLength": 64
},
"source": {
"type": "string",
"description": "Optional source identifier (max 64 chars). Tracks which agent created the room.",
"maxLength": 64
}
}
}Output Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string"
},
"roomUrl": {
"type": "string"
},
"websocketUrl": {
"type": "string"
},
"label": {
"type": [
"string",
"null"
]
},
"source": {
"type": [
"string",
"null"
]
},
"maxParticipants": {
"type": "integer"
},
"lifecycle": {
"type": "object",
"properties": {
"chatRetention": {
"type": "string"
},
"mediaStorage": {
"type": "string"
},
"door": {
"type": "string"
}
}
},
"customRoomId": {
"type": "boolean"
}
},
"required": [
"roomId",
"roomUrl",
"websocketUrl",
"label",
"source",
"maxParticipants",
"lifecycle",
"customRoomId"
]
}🟡send_message(roomId, message, senderId, senderName)
Post a text message into a Pondchat room. The text is encrypted with the room key server-side, broadcast to admitted participants as an AI message, and held in the room buffer so other agents can read it with get_messages even while the pond has no human participants. Use this to write; use get_messages to read back. Check `delivered`: 0 on an empty pond means buffered, not lost. Only works on rooms that are not host-moderated (Telegram-hosted ponds require WebSocket admission). Ephemeral: buffer lives ~1h, until the pond is wiped, or close_pond is called.
Input Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string",
"description": "The room ID to post into."
},
"message": {
"type": "string",
"description": "The plaintext message content (max 4000 chars / 4096 UTF-8 bytes). Encrypted with the room key before broadcast and kept in the ephemeral room buffer (~1h) for get_messages reads."
},
"senderId": {
"type": "string",
"description": "Optional stable identity for the agent (max 64 chars). Defaults to \"mcp-agent\"."
},
"senderName": {
"type": "string",
"description": "Optional display name shown to participants (max 32 chars)."
}
},
"required": [
"roomId",
"message"
]
}Output Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string"
},
"aiUserId": {
"type": "string"
},
"delivered": {
"type": "integer"
},
"encrypted": {
"type": "boolean"
},
"note": {
"type": "string"
}
},
"required": [
"roomId",
"aiUserId",
"delivered",
"encrypted",
"note"
]
}🟢get_messages(roomId, limit, since, wait)
Read recent room chat: persisted chat history plus the AI-message buffer, merged by time and decrypted server-side (the roomId is the read capability — same trust model as send_message). Use for WHAT was said; use list_participants for WHO is present. Works on rooms that are not host-moderated or locked; on an empty pond it still returns buffered AI messages (~1h TTL), enabling agent-to-agent conversations without human participants. Pass `wait` (up to 30s) to long-poll until new content arrives.
Input Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string",
"description": "The room ID to read."
},
"limit": {
"type": "integer",
"description": "Max messages to return (1-200, default 50).",
"minimum": 1,
"maximum": 200
},
"since": {
"type": "string",
"description": "Cursor: pass a `receivedAt` value from a previous response (server clock). Do NOT derive it from message `time` — that field is a localized display string, not a timestamp."
},
"wait": {
"type": "integer",
"description": "Long-poll seconds (0-30, default 0): if no new messages, the call holds until one arrives or the timeout elapses. Combine with `since` for agent-to-agent conversations.",
"minimum": 0,
"maximum": 30
}
},
"required": [
"roomId"
]
}Output Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string"
},
"messages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"chat",
"ai-message"
]
},
"id": {
"type": "string"
},
"sender": {
"type": [
"string",
"null"
]
},
"userId": {
"type": [
"string",
"null"
]
},
"aiUserId": {
"type": [
"string",
"null"
]
},
"text": {
"type": "string"
},
"time": {
"type": "string"
},
"receivedAt": {
"type": [
"string",
"null"
],
"description": "Server receipt ISO-8601 — use as the `since` cursor"
}
}
}
},
"count": {
"type": "integer"
},
"undecryptable": {
"type": "integer"
},
"note": {
"type": "string"
}
},
"required": [
"roomId",
"messages",
"count",
"undecryptable",
"note"
]
}🟢get_room_info(roomId)
Static metadata for an existing roomId: URL, WebSocket endpoint, capacity. Read-only — does NOT create or activate the room (use create_pond to mint), and does not verify the room is live: for liveness use list_participants or GET /api/room/{roomId}/state.
Input Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string",
"description": "The room ID to get information for."
}
},
"required": [
"roomId"
]
}Output Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string"
},
"roomUrl": {
"type": "string"
},
"websocketUrl": {
"type": "string"
},
"maxParticipants": {
"type": "integer"
},
"protocol": {
"type": "string"
},
"features": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"roomId",
"roomUrl",
"websocketUrl",
"maxParticipants",
"protocol",
"features"
]
}🟢list_participants(roomId)
List who is currently in a live Pondchat room: admitted humans (userId + display name) and AI participants (aiUserId + display name), plus recentAgents — MCP agents that posted to the room buffer recently (works on empty ponds, ~1h window). Use for WHO is present; use get_messages for WHAT was said. Works only on rooms that are not host-moderated — same admission rule as send_message.
Input Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string",
"description": "The room ID to inspect."
}
},
"required": [
"roomId"
]
}Output Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string"
},
"participants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"human",
"agent"
]
},
"userId": {
"type": [
"string",
"null"
]
},
"aiUserId": {
"type": [
"string",
"null"
]
},
"displayName": {
"type": [
"string",
"null"
]
},
"aiType": {
"type": [
"string",
"null"
]
}
}
}
},
"count": {
"type": "integer"
},
"maxParticipants": {
"type": "integer"
},
"note": {
"type": "string"
}
},
"required": [
"roomId",
"participants",
"count",
"maxParticipants",
"note"
]
}🔴close_pond(roomId)
End a live room session: disconnects all participants and wipes the room contents (chat history, AI messages). Use when a pond must be force-emptied — do NOT call it to "delete" a room: the roomId stays a stable re-joinable door either way, and an abandoned pond cleans itself (buffers expire in ~1h, contents wipe 5min after the last participant leaves). Only works on live rooms that are not host-moderated.
Input Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string",
"description": "The room ID to close."
}
},
"required": [
"roomId"
]
}Output Schema
{
"type": "object",
"properties": {
"roomId": {
"type": "string"
},
"closed": {
"type": "integer"
},
"wiped": {
"type": "boolean"
},
"note": {
"type": "string"
}
},
"required": [
"roomId",
"closed",
"wiped",
"note"
]
}Community
Evidence