This is an automated email from the ASF dual-hosted git repository. rbowen pushed a commit to branch rbowen-ponymail-mcp in repository https://gitbox.apache.org/repos/asf/comdev.git
commit f2f1247b438d0600379f184208367fa56ab5b586 Author: Rich Bowen <[email protected]> AuthorDate: Wed Apr 15 15:27:19 2026 -0400 Adds a bookmarklet to help with auth, and updates README to reflect new functionality. But the auth is very cumbersome right now. --- README.md | 35 +++++++++++++++++++++++++++++++++++ auth.js | 29 ++++++++++++++++++++++++----- bookmarklet.html | 31 +++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0524607..8c96363 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ An MCP (Model Context Protocol) server that provides access to the [Apache PonyM | `get_email` | Fetch a specific email by ID with full body and attachments | | `get_thread` | Fetch the root message of a thread by thread ID | | `get_mbox` | Download mbox-formatted archive data for bulk export | +| `login` | Authenticate via ASF OAuth to access private mailing lists | +| `logout` | Clear cached session cookie | +| `auth_status` | Check current authentication status | ## Setup @@ -34,6 +37,38 @@ npm install | Variable | Default | Description | |----------|---------|-------------| | `PONYMAIL_BASE_URL` | `https://lists.apache.org` | Base URL of the PonyMail instance | +| `PONYMAIL_SESSION_COOKIE` | *(none)* | Manual session cookie override (skips OAuth flow) | + +## Authentication (Private Lists) + +Public lists work without authentication. For private/restricted lists, you have two options: + +### Option 1: Automated OAuth (Recommended) + +Use the `login` tool from within Amazon Quick. It will: + +1. Open a local helper page at `http://localhost:39817` +2. The page links to PonyMail's login page — log in with your ASF LDAP credentials +3. After logging in, grab the session cookie (see below) and paste it into the form +4. The server validates the cookie and caches it to `~/.ponymail-mcp/session.json` + +**Finding the HttpOnly cookie:** The `ponymail` cookie is `HttpOnly`, so `document.cookie` and the Application tab won't show it. To find it: +1. On `lists.apache.org` (while logged in), open DevTools (`Cmd+Option+I` / `F12`) +2. Go to the **Network** tab and reload the page +3. Click on any request (e.g., the page itself, or any `api/` call) +4. In **Headers** → **Request Headers** → find the **Cookie:** line +5. Copy the `ponymail=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` part +### Option 2: Manual Cookie + +1. Log into https://lists.apache.org in your browser +2. Open DevTools → Application → Cookies → copy the session cookie +3. Set the environment variable: + ``` + PONYMAIL_SESSION_COOKIE="ponymail=abc123..." + ``` +4. Add it to your MCP server config's environment variables + +Sessions expire after ~20 hours. Use `auth_status` to check, `logout` to clear. ## Usage Examples diff --git a/auth.js b/auth.js index ea1de88..7176cda 100644 --- a/auth.js +++ b/auth.js @@ -95,7 +95,7 @@ function openBrowser(url) { * Perform login by: * 1. Opening PonyMail's login page in the browser * 2. Starting a local HTTP server with a simple form where the user pastes - * their cookie after logging in + * their cookie after logging in, OR uses the bookmarklet to auto-fill * 3. Saving the cookie once received * * @param {string} baseUrl - PonyMail base URL @@ -197,19 +197,30 @@ export function performLogin(baseUrl, timeoutMs = LOGIN_TIMEOUT_MS) { function loginPage(baseUrl) { const oauthUrl = `${baseUrl}/oauth.html`; + const hostname = new URL(baseUrl).hostname; return `<!DOCTYPE html> <html> <head><title>PonyMail MCP Login</title></head> <body style="font-family:system-ui;max-width:640px;margin:40px auto;padding:0 20px"> <h1>🐴 PonyMail MCP Login</h1> - <p><strong>Step 1:</strong> Log into PonyMail in your browser:</p> + + <p><strong>Step 1:</strong> Log into PonyMail (if you haven't already):</p> <p><a href="${oauthUrl}" target="_blank" style="font-size:1.2em;color:#0066cc"> ➜ Open ${oauthUrl} </a></p> - <p><strong>Step 2:</strong> After logging in, open DevTools (<code>Cmd+Option+I</code> or <code>F12</code>) - → <strong>Application</strong> tab → <strong>Cookies</strong> → <code>${new URL(baseUrl).hostname}</code></p> - <p>Copy the <strong>entire cookie string</strong>. It typically looks like:<br> + + <p><strong>Step 2:</strong> After logging in, get the session cookie. The cookie is HttpOnly, so you need to find it via DevTools:</p> + <ol style="line-height:1.8"> + <li>On <code>${hostname}</code>, open DevTools: <code>Cmd+Option+I</code> (or <code>F12</code>)</li> + <li>Go to the <strong>Network</strong> tab</li> + <li>Reload the page (or click any link)</li> + <li>Click on any request to <code>${hostname}</code> (e.g., the document or any <code>api/</code> call)</li> + <li>In <strong>Headers</strong> → <strong>Request Headers</strong> → find the <strong>Cookie:</strong> line</li> + <li>Copy the <code>ponymail=xxxxxxxx-xxxx-...</code> part</li> + </ol> + <p>It typically looks like:<br> <code style="background:#f0f0f0;padding:2px 6px">ponymail=abc123def456...</code></p> + <p><strong>Step 3:</strong> Paste it below:</p> <form method="POST" action="/save"> <input name="cookie" type="text" placeholder="ponymail=..." @@ -220,6 +231,14 @@ function loginPage(baseUrl) { Save Cookie </button> </form> + + <details style="margin-top:30px"> + <summary style="cursor:pointer;color:#0066cc">💡 Quick alternative: Console one-liner</summary> + <p>On <code>${hostname}</code>, open DevTools Console and run:</p> + <pre style="background:#f5f5f5;padding:12px;border-radius:4px;overflow-x:auto;font-size:0.85em">fetch('/api/preferences.lua').then(r=>r.json()).then(j=>console.log(j.login?.credentials ? '✅ Logged in as: '+j.login.credentials.fullname+'\\nNow check Network tab for any api/ request → Request Headers → Cookie' : '❌ Not logged in — log in first'))</pre> + <p>This confirms you're logged in and triggers a network request so the cookie appears in the Network tab.</p> + </details> + <p style="color:#888;margin-top:30px;font-size:0.9em"> The cookie will be saved to <code>~/.ponymail-mcp/session.json</code> and used for API requests. This page will close automatically after saving. Session expires after ~20 hours. diff --git a/bookmarklet.html b/bookmarklet.html new file mode 100644 index 0000000..57b150d --- /dev/null +++ b/bookmarklet.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head><title>PonyMail Cookie Bookmarklet</title></head> +<body style="font-family:system-ui;max-width:700px;margin:40px auto;padding:0 20px"> +<h1>🐴 PonyMail Cookie Extractor</h1> +<p>Drag this bookmarklet to your bookmarks bar:</p> + +<p style="text-align:center;margin:30px 0"> +<a href="javascript:void(fetch('/api/preferences.lua',{credentials:'include'}).then(r=>{const c=document.cookie;return r.json().then(j=>{const m=j.login&&j.login.credentials;if(!m){alert('Not logged in to PonyMail. Log in first, then try again.');return}const x=new XMLHttpRequest();x.open('GET','/api/preferences.lua',false);x.withCredentials=true;x.send();const raw=x.getResponseHeader('X-Request-Cookies')||'';let pc='';document.cookie.split(';').forEach(s=>{if(s.trim().startsWith('ponyma [...] + style="display:inline-block;padding:12px 24px;background:#0066cc;color:white;text-decoration:none;border-radius:6px;font-size:1.1em;cursor:grab"> + 📋 Get PonyMail Cookie +</a> +</p> + +<h2>How to use</h2> +<ol> + <li>Drag the blue button above to your <strong>bookmarks bar</strong></li> + <li>Go to <a href="https://lists.apache.org">lists.apache.org</a> and <strong>log in</strong></li> + <li>Click the bookmarklet</li> + <li>It will confirm you're logged in and prompt for the cookie value</li> + <li>The quickest way to get it: before clicking the bookmarklet, open DevTools (<code>Cmd+Option+I</code>) → <strong>Network</strong> tab, then click the bookmarklet. Look at the <code>preferences.lua</code> request → <strong>Request Headers</strong> → <strong>Cookie</strong> line</li> + <li>Copy just the <code>ponymail=xxxxxxxx-xxxx-...</code> part and paste it in the prompt</li> + <li>The bookmarklet copies the formatted cookie to your clipboard</li> + <li>Paste it into your MCP server's <code>PONYMAIL_SESSION_COOKIE</code> env var</li> +</ol> + +<h2>Even simpler: Console one-liner</h2> +<p>On <code>lists.apache.org</code>, open DevTools Console and run:</p> +<pre style="background:#f5f5f5;padding:12px;border-radius:4px;overflow-x:auto">fetch('/api/preferences.lua').then(r=>r.json()).then(j=>{if(j.login?.credentials){console.log('✅ Logged in as:',j.login.credentials.fullname);console.log('Now check the Network tab for preferences.lua request → Cookie header → copy the ponymail=... value')}else{console.log('❌ Not logged in')}})</pre> +</body> +</html>
