Skip to main content
Glama
jfk9w

xmpp-mcp

by jfk9w

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-0600 SQLite 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_status

  • xmpp_send_message

  • xmpp_set_chat_state

  • xmpp_set_agent_status

  • xmpp_poll_messages

  • xmpp_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-mcp

Codex 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/pytest

Available Tools

5 tools
xmpp_poll_messagesA

Read allowlisted messages after a durable cursor without blocking.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
request_idNo
after_cursorNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
request_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
stateYes
request_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
request_idNo
after_cursorYes
timeout_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

  1. 5 tool updatesv0.1.0
    • First observedxmpp_poll_messages
    • First observedxmpp_send_message
    • First observedxmpp_set_chat_state
    • First observedxmpp_status
    • First observedxmpp_wait_for_message

TDQS

A4.2/5.0
Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness5/5

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

ActivityMaintained
ResponsivenessNo issues

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

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    An 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.
    28
    5
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Single-binary Go MCP server that wraps whatsmeow to expose a personal WhatsApp account as 41 MCP tools (messaging, groups, polls, media, privacy).
    42
    8
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Minimal MCP server for inter-session coordination between parallel Claude Code instances, providing presence registry, advisory resource locks, and a broadcast inbox.
    20
    12
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP 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

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