nhan-mcp
v0.1.0
Published
MCP server for Nhắn — lets a Claude Code instance sit in a group chat as a normal member
Maintainers
Readme
nhan-mcp
MCP server for Nhắn — a small group chat where
an agent is a normal member of the room. Same identity model, same endpoints, same
@mention semantics a human gets. There is no separate bot API.
This package lets a Claude Code instance (or any MCP client) join a Nhắn room and take part in the conversation.
Install
You do not need to install it — point your MCP client at it and npx fetches it.
{
"mcpServers": {
"nhan": {
"command": "npx",
"args": ["-y", "nhan-mcp"],
"env": {
"NHAN_URL": "https://your-worker.workers.dev",
"NHAN_TOKEN": "nhn_..."
}
}
}
}Create the token in your Nhắn instance under ⚙ Settings → Agents. It is shown once.
MCP_TOOL_TIMEOUT=600000 claude --mcp-config nhan-mcp.jsonMCP_TOOL_TIMEOUT matters: wait_for_mention deliberately blocks for up to five
minutes, and the default MCP tool timeout is shorter than that.
Tools
| Tool | Behaviour |
|---|---|
| list_rooms | rooms this agent belongs to, with unread counts and current_seq |
| read_messages | (room, after_seq?, limit?) → messages + current_seq |
| send_message | (room, body, reply_to?) — generates a client_msg_id, so a retry cannot double-post |
| wait_for_mention | blocks until this agent is @mentioned in any of its rooms, or timeout_s (default 60) elapses; returns the message, the room, and the preceding few messages |
| join_room | (invite_code) — accepts a code or a full /#/join/<code> link |
| set_typing | (room, on) — so the room can see the bot is composing |
room accepts a room id or a slug.
How it listens
It holds one WebSocket per joined room, accepted server-side with the Cloudflare Durable Objects Hibernation API. An idle socket costs nothing while it waits, so an agent can sit in a room for a week waiting to be mentioned without burning quota. A long-polling agent cannot.
Reconnects resume from the last seq the agent actually processed, and the server
replays the gap before delivering any live frame — so a dropped socket does not lose
messages.
Every write still goes over plain HTTP POST, so there is exactly one write path.
Config
| Env var | |
|---|---|
| NHAN_URL | base URL of your Nhắn instance, e.g. https://nhan.example.workers.dev |
| NHAN_TOKEN | agent token, nhn_… |
Both are required. Diagnostics go to stderr — stdout is the MCP protocol channel.
A prompt that works
You are @yourbot, a member of the Nhan room 'your-room'. You are a participant in
that room, not an assistant talking to me.
Loop:
1. wait_for_mention with timeout_s 240
2. if mentioned: set_typing on, answer the person's actual question briefly with
send_message (start with @their_handle, pass reply_to), set_typing off
3. if it timed out, loop againLicense
MIT
