xmpp-mcp
Provides tools for interacting with XMPP, allowing an agent to send messages to a fixed allowlisted recipient, set XEP-0085 chat states, poll and wait for messages using cursor-based history, and handle XEP-0333 displayed markers.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@xmpp-mcpSend a notification to my XMPP that the report is ready and wait for my reply."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
xmpp-mcp
A deliberately small XMPP MCP server for human-in-the-loop notifications. It connects as a dedicated bot account and communicates with exactly one allowlisted bare JID.
Security model
The recipient is fixed by
MCP_XMPP_ALLOWED_JID; MCP calls cannot override it.Messages from every other JID are discarded before persistence.
Host, login, and password are supplied through the MCP process environment.
TLS certificate verification is enabled with the system trust store.
XEP-0198 stream management is requested when supported by the server.
Accepted messages are deduplicated and persisted in a mode-
0600SQLite database.No shell, file-transfer, roster-management, MUC, or arbitrary-recipient tools are exposed.
This protects the messaging boundary, but a reply in XMPP is still an agent instruction, not a substitute for a Codex approval required by the client.
Related MCP server: mcp-whatsapp
Tools
xmpp_statusxmpp_send_messagexmpp_set_chat_statexmpp_set_agent_statusxmpp_poll_messagesxmpp_wait_for_message
xmpp_set_chat_state publishes XEP-0085 states (active, composing,
paused, inactive, or gone) to the fixed allowlisted recipient. A typical
agent sends composing before longer work and active after its reply.
Outgoing text messages include an XEP-0172 nickname generated as
<working-directory-name>@<short-hostname>. Set MCP_XMPP_WORKING_DIR when the
MCP process cwd is not the Codex workspace. The recipient client may use this
hint as a display name, but its local roster name remains authoritative.
While xmpp_wait_for_message is waiting, the account publishes a directed
chat presence with the status Ожидаю указания to the allowlisted JID.
Receiving a command changes it to dnd / Работаю; sending the next message
or leaving the wait without a message clears the text and returns to plain
online presence.
For orchestration loops, call xmpp_set_agent_status with waiting, invoke
xmpp_wait_for_message with manage_presence=false for each inner wait, and
publish working when a message arrives. Use clear when leaving the loop
without sending a reply.
Incoming messages that request XEP-0333 Displayed Markers with markable are
automatically marked as displayed. Markers are sent only to the fixed
allowlisted JID and are never generated in response to another marker.
Polling and waiting use durable integer cursors. Save next_cursor and pass it
as after_cursor on the next call. request_id maps to the XMPP thread field;
not every mobile client preserves threads, so cursor order remains the fallback.
Setup
cd ~/Developer/xmpp-mcp
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'Export configuration before launching the MCP server:
export MCP_XMPP_HOST='xmpp.example.org'
export MCP_XMPP_LOGIN='codex-bot@example.org/codex'
export MCP_XMPP_PASSWORD='BOT_ACCOUNT_PASSWORD'
export MCP_XMPP_ALLOWED_JID='you@example.org'Optional variables such as MCP_XMPP_PORT, MCP_XMPP_CONNECT_TIMEOUT, and
MCP_XMPP_STATE_DIR are documented in .env.example.
Run directly:
.venv/bin/xmpp-mcpCodex configuration
Add a stdio MCP server to ~/.codex/config.toml:
[mcp_servers.xmpp]
command = "/home/user/Developer/xmpp-mcp/.venv/bin/xmpp-mcp"
[mcp_servers.xmpp.env]
MCP_XMPP_HOST = "xmpp.example.org"
MCP_XMPP_LOGIN = "codex-bot@example.org/codex"
MCP_XMPP_PASSWORD = "BOT_ACCOUNT_PASSWORD"
MCP_XMPP_ALLOWED_JID = "you@example.org"Restart the Codex session after changing MCP configuration.
Checks
.venv/bin/ruff check .
.venv/bin/pytestAvailable Tools
5 toolsxmpp_poll_messagesA
Read allowlisted messages after a durable cursor without blocking.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| request_id | No | ||
| after_cursor | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for disclosing behavior. It explicitly states 'Read' (non-destructive) and 'without blocking' (non-blocking execution), and hints at cursor persistence ('durable cursor'). This covers the essential safety and execution profile, though deeper details (e.g., whether the cursor auto-advances, error conditions) are not disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence. Every word earns its place: 'Read' (verb), 'allowlisted messages' (object), 'after a durable cursor' (mechanism), and 'without blocking' (behavior). There is zero fluff or redundancy, making it an excellent model of concise writing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return values are not the description's responsibility. However, given the moderate complexity of a cursor-based polling tool, the description misses key context: what 'allowlisted' means, how the cursor should be managed, and what `request_id` is for. These gaps make it minimally viable but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for parameter meaning. It effectively explains `after_cursor` via 'after a durable cursor' but provides no insight into `limit` or `request_id`. `request_id` in particular is cryptic and remains unexplained, leaving two of three parameters semantically underdefined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read'), identifies the resource ('allowlisted messages'), and adds crucial modifiers ('after a durable cursor', 'without blocking') that clearly distinguish it from sibling tools like `xmpp_wait_for_message` (blocking) and `xmpp_send_message` (sending). This precisely conveys the tool's function and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'without blocking' provides clear context that this tool is intended for non-blocking message retrieval, implicitly contrasting with `xmpp_wait_for_message`. It does not explicitly name alternatives or define exclusion criteria, but the context is strong enough that an agent would know when to choose this over a blocking wait.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
xmpp_send_messageA
Send text to the single configured allowlisted JID.
The recipient cannot be overridden. Reuse request_id to correlate a response when the recipient's XMPP client preserves message threads.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| request_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It reveals a key restriction (recipient cannot be overridden) and explains the request_id correlation mechanism, adding context beyond the schema. However, it does not mention side effects, error behavior, or delivery semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary action, and immediately provides a necessary constraint and a valuable usage tip. Every word earns its place without redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple send operation with an output schema, the description covers the core action, the fixed recipient restriction, and request_id usage. It lacks authentication or error-handling context, but the output schema likely documents return values, and sibling tools provide workflow context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates by clarifying the text parameter as the message content through 'Send text' and explaining request_id's purpose for response correlation. It does not specify formatting constraints for text, but the meaning is strongly implied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Send text to the single configured allowlisted JID,' providing a clear verb, object, and target. It distinguishes itself from sibling tools (polling, status, chat state) by focusing on the sending action and highlights the fixed recipient constraint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies the tool is for sending outgoing messages, which is distinct from the sibling polling and waiting tools, but it does not explicitly state when to use it over alternatives. It provides specific guidance for request_id ('Reuse request_id to correlate a response'), though it lacks when-not-to-use exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
xmpp_set_chat_stateA
Publish an XEP-0085 chat state to the single allowlisted JID.
state must be active, composing, paused, inactive, or gone. The recipient cannot be overridden. Pass request_id when the peer preserves XMPP threads.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | ||
| request_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses important constraints (allowlisted JID, fixed recipient, request_id condition) but omits operational details such as error handling, idempotency, or connection requirements. The term 'Publish' implies a side effect, but the description does not elaborate on what the agent should expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences with the purpose front-loaded. Every sentence adds value: purpose, allowed state values, and request_id guidance. There is no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 2-parameter tool with an output schema, the description covers purpose, constraints, and parameter semantics. It lacks a few edge-case details (e.g., error behavior, exact output), but the output schema likely fills that gap. The description is sufficient for an agent to select and invoke the tool correctly in most cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the schema has no enums or descriptions. The description compensates fully by enumerating valid state values ('active, composing, paused, inactive, or gone') and explaining when to pass request_id ('when the peer preserves XMPP threads'). This adds essential meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Publish an XEP-0085 chat state to the single allowlisted JID.' This is a specific verb and resource, and it distinguishes the tool from sibling tools like xmpp_send_message and xmpp_poll_messages by focusing on chat state publication.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: the recipient is allowlisted and cannot be overridden, and request_id should be passed when the peer preserves XMPP threads. However, it does not explicitly state when to use this tool versus alternatives, or provide exclusions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
xmpp_statusA
Check the restricted XMPP connection and current durable message cursor.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose any behavioral details such as authentication requirements, side effects, or what 'restricted' entails. It simply states the action without additional context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no unnecessary words. It is front-loaded and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema is present, so return values are covered elsewhere. The description adequately states the tool's purpose for a zero-parameter status check, though it could elaborate on the meaning of 'restricted' to be fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description does not need to explain parameter semantics. The baseline of 4 applies because the schema is empty and there is nothing to document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'check' and identifies two resources: the restricted XMPP connection and the durable message cursor. This clearly distinguishes from sibling tools that send messages, set state, poll, or wait.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is provided on when to use this tool versus alternatives. The description does not mention sibling tools or suggest usage scenarios, leaving the agent to infer from the name and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
xmpp_wait_for_messageA
Wait for the next allowlisted message after a durable cursor.
timeout_seconds is clamped to 1..1800 seconds. A timeout is a normal result.
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | No | ||
| after_cursor | Yes | ||
| timeout_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It adds meaningful behavioral context by disclosing that timeout_seconds is clamped to 1..1800 seconds and that a timeout is a normal result, which prepares the agent for possible empty or null returns. It does not cover all behaviors (e.g., whether it consumes the message), but it provides substantial useful detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary purpose in the first sentence, followed by a single second sentence that adds a critical behavioral note. It is concise with no redundant words or restatement of schema fields, earning top marks.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity and the presence of an output schema, the description adequately covers the essential behavior (blocking wait, timeout clamping, normal timeout). It leaves some domain context implicit (e.g., what 'allowlisted' means, how to get a cursor), but this is acceptable given sibling tools and schema. Minor gaps prevent a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies 'after_cursor' by referencing 'after a durable cursor' and explains the clamping behavior of 'timeout_seconds'. However, it does not describe 'request_id' at all, and the schema only provides names/types without descriptions. The partial coverage is helpful but not complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Wait for') and a precise resource ('next allowlisted message'), along with a positional constraint ('after a durable cursor'). This clearly distinguishes it from the sibling polling tool 'xmpp_poll_messages' by implying a blocking wait rather than a poll.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for blocking waits (as opposed to polling) and notes that a timeout is a normal outcome, but it does not explicitly compare with alternatives like xmpp_poll_messages or state prerequisites (e.g., how to obtain a durable cursor). Guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
5 tool updates
v0.1.0- First observed
xmpp_poll_messages - First observed
xmpp_send_message - First observed
xmpp_set_chat_state - First observed
xmpp_status - First observed
xmpp_wait_for_message
TDQS
Each tool targets a distinct action: status check, send, set chat state, poll, and wait. Poll and wait are differentiated by blocking behavior, so there is no ambiguity.
All tools share an xmpp_ prefix and mostly follow a verb_noun pattern (send_message, set_chat_state, poll_messages, wait_for_message). The one exception is xmpp_status, which is a noun phrase rather than a verb_noun, a minor deviation.
With 5 tools, the server is well-scoped for its focused purpose of interacting with a single XMPP connection. Each tool earns its place, and the count is within the ideal 3-15 range.
The tool set covers the essential lifecycle for an XMPP connection: check status, send messages, publish chat state, and retrieve messages via poll or wait. No obvious gaps exist for the stated domain of a restricted single-recipient XMPP connection.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Experimental MCP server for current empirical verification of explicit public HTTPS endpoint claims.
FastMCP server for posting formatted content to X (Twitter) — Tollbooth-monetized, DPYC-native
Related MCP Servers
- AlicenseBqualityCmaintenanceAn MCP server that enables interaction with WhatsApp using the Baileys library and Streamable HTTP transport. It supports managing contacts, chats, and messages, while providing a web admin UI for QR code authentication and media handling.285MIT
- AlicenseAqualityBmaintenanceSingle-binary Go MCP server that wraps whatsmeow to expose a personal WhatsApp account as 41 MCP tools (messaging, groups, polls, media, privacy).428MIT
- AlicenseNot gradedqualityBmaintenanceMinimal MCP server for inter-session coordination between parallel Claude Code instances, providing presence registry, advisory resource locks, and a broadcast inbox.2012MIT
- AlicenseNot gradedqualityAmaintenanceMCP server for a local-first messaging workspace that integrates Google Messages, WhatsApp, and Signal. It enables reading, sending, searching messages, and managing conversations through MCP tools.52-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jfk9w/xmpp-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server