MCP server
@socketly/mcp gives a coding agent five tools and these docs as a resource. The tools matter less than what they add up to: an agent that can publish an event, watch the channel, and see the message arrive can check its own work. One that can only write code publishes blind and reports success, which is how generated realtime code ends up quietly wrong.
Install
claude mcp add socketly \
--env SOCKETLY_SECRET_KEY=sk_app_… \
--env SOCKETLY_PUBLIC_KEY=pk_app_… \
-- npx -y @socketly/mcpBoth keys are minted together when you create an app in the dashboard. The secret is shown exactly once.
Tools
| Tool | Reversible | What it does |
|---|---|---|
socketly_publish | no | Publishes an event to one or more channels, as your server would. Real clients receive it. |
socketly_channel_info | read-only | A channel's kind, and for presence- channels who is currently in it. |
socketly_subscribe | read-only | Opens a connection and starts buffering. Returns a handle. |
socketly_receive | read-only | Drains a handle. Long-polls for the first message if you ask it to. |
socketly_unsubscribe | yes | Closes the subscription and its connection. |
socketly_publish is annotated as not read-only, so a client can gate it behind confirmation. It is the only one that changes anything.
Watching a channel is a buffer, not a stream
MCP cannot push a message into a model's turn. The specification's only server-to-client mechanism carries four notification types, all of them about lists changing, and none of them reaches the model. So the server holds the socket and buffers what arrives; the agent drains it with a tool call.
- A subscription closes after 5 minutes without a receive. An expired handle returns an error telling the agent to resubscribe, rather than an empty result that reads exactly like a quiet channel.
- The buffer holds 256 messages. Past that the oldest are dropped and
receivereports how many — a silently truncated buffer is a lie an agent would reason from. - An open subscription is a connection, and counts against your app's concurrent connection limit.
Only public- channels can be watched. private- and presence- need a signature from your backend, which is the whole point of them.
The docs are a resource
The server exposes socketly://docs, fetched from llms-full.txt — which this site generates from the same constants its own pages render. So an agent scaffolding Socketly reads the checked source rather than whatever it remembers, and when a pattern here improves, every agent's output improves without anyone republishing the package.
Not yet
Creating apps and rolling keys. Those sit behind a session cookie, and exposing them needs a personal access token the API does not have. They are also a dashboard click, and rare.
An agent as a channel member. Replying in presence-support-4821 as a participant needs a credential scoped to one channel and one identity. A secret key grants far too much for that.