Table of Contents generated with DocToc
This directory documents the PonyMail tool adapter — the set of capabilities the skills use to read ASF mailing-list archives directly via an MCP server, without going through a personal Gmail subscription.
A project opts into this tool by naming it in its manifest under Tools enabled. The adopting project manifest lives at ../../<project-config>/project.md.
The backing MCP server is rbowen/ponymail-mcp (Python) which wraps the public PonyMail HTTP API at lists.apache.org and layers ASF LDAP OAuth on top so private-list archives (e.g. security@<project>.apache.org, private@<project>.apache.org) are reachable from the MCP client.
| Capability | File | What it covers |
|---|---|---|
| MCP operations | operations.md | The mcp__ponymail__* tool catalogue (auth, search, thread, email, mbox, list overview) + the call-shape contract (list-prefix + domain separation, tid / mid resolution, timespan syntax) |
| Setup and authentication | this file (below) | How to install the MCP server, register it with Claude Code, run the ASF LDAP login, and verify the session cache |
Related, adjacent tools:
| Capability | File | Relationship |
|---|---|---|
| Gmail inbox + drafts | ../gmail/tool.md | Gmail remains the load-bearing write tool — the skills create drafts there; PonyMail MCP is read-only. The two overlap on reads of private security@ threads (both can fetch the same thread); the skills pick whichever the project manifest declares. |
| PonyMail HTTP archive (URL construction only) | ../gmail/ponymail-archive.md | URL templates for the lists.apache.org archive that the skills use for in-tracker cross-links (e.g. the Security mailing list thread body field). Independent of the MCP — a thread URL constructed here is still the pastable form even when PonyMail MCP is the actual read path. |
Gmail is the only inbound-mail path that works for a triager who is not a PMC member on the target list — their personal Gmail subscription is what sees the inbound security@<project>.apache.org threads. PonyMail MCP is the inbound-mail path that works for a PMC member who can authenticate against ASF LDAP; the MCP then sees private-list archives directly, without the triager needing to have subscribed from the specific Gmail account they are running Claude Code against.
The two are not interchangeable today. Specifically:
create_draft equivalent, and the skills' status-update replies to reporters must still go through mcp__claude_ai_Gmail__*.~/.ponymail-mcp/session.json.Primary vs. fallback. When a project declares both tools in its manifest and the user opts into PonyMail MCP in config/user.md, PonyMail MCP is the primary read backend for archive queries (reporter-thread lookups, reviewer-comment searches, advisory-URL scans, [RESULT][VOTE] attribution, prior-rejection precedent searches). Gmail is the fallback — used when the user does not have LDAP archive access to a specific list, when PonyMail returns an error, or when inbox latency matters (just-arrived messages that have not been indexed into the archive yet). Gmail remains the only backend for draft composition regardless of which read backend is active.
Prerequisites:
pmc-<project>), which gates the <security-list> and <private-list> archives.The server is published as rbowen/ponymail-mcp. Install it with uv tool install, pipx install, or via the package-manager of your choice. Confirm the binary resolves on PATH:
uv tool install git+https://github.com/rbowen/ponymail-mcp which ponymail-mcp # /home/<user>/.local/bin/ponymail-mcp
Add the server to Claude Code's MCP configuration. Two common locations, each taking precedence in this order:
.claude/settings.json under the project root. Use this when every team member working in this tree should get the same MCP without extra setup.~/.claude/settings.json for your personal Claude Code configuration. Use this when the MCP is your own preference and not part of the project's declared toolchain.The mcpServers entry looks like:
{ "mcpServers": { "ponymail": { "command": "ponymail-mcp", "args": [], "env": {} } } }
The tool names that Claude Code surfaces after registration are prefixed with mcp__ponymail__ (derived from the key under mcpServers). If you name the server differently, the prefix changes and this directory's docs need to be re-pointed.
Restart Claude Code (or run /mcp → reconnect) so the new server is picked up and its tools appear in the deferred-tool list.
In a Claude Code session, run:
mcp__ponymail__login()
A browser window opens and redirects to the ASF LDAP login at oauth.apache.org. Complete the login. On success, the MCP server caches the session cookie at ~/.ponymail-mcp/session.json; this file is reused for subsequent requests and survives across Claude Code sessions until the cookie expires.
Verify:
mcp__ponymail__auth_status()
It should report an authenticated session with the LDAP username and expiry. If unauthenticated, the tool still works against public lists but returns empty results for private-list queries.
Pull the list overview to confirm the session sees the expected lists:
mcp__ponymail__list_lists()
The result is a { domain → { list → message_count } } map. For a PMC-LDAP-authenticated triager, you should see the project's <security-list-domain> → { security: <count> } — proof that the session has PMC-level LDAP access. If you only see public lists (dev, users, announce), the LDAP group membership is not being recognised; contact ASF Infra.
mcp__ponymail__logout() clears the cached cookie. Use this on a shared workstation, or when rotating credentials. After logout the MCP reverts to anonymous access (public lists only).
The session cookie in ~/.ponymail-mcp/session.json is a credential — it authenticates as you against every ASF list your LDAP account can read. Treat the file like an SSH key: do not commit it, do not sync it across workstations, do not paste it into PRs.
The same rule set from ../../AGENTS.md — Confidentiality of the tracker repository applies to content read through PonyMail MCP. In particular:
security@, private@) that the MCP retrieves for authenticated sessions stays in the tracker's private surfaces only — never copied into public PR descriptions, public issue comments, canned responses, or release-time advisory text.../../AGENTS.md.A project that hosts its mailing lists outside the ASF (any vendor-hosted or self-hosted archive) can swap this directory for a sibling tools/<name>/ documenting the equivalent operations against that backend. The contract the generic skills rely on is:
mid or Message-ID, including full body and headers.Sibling tools that write back (post a draft, reply to a thread) are out of scope for this adapter — drafts remain the Gmail tool's responsibility.