feat(connect): dedicated Claude.ai / ChatGPT browser connect picker

- Replace single 'Connect to Claude / ChatGPT' button with a modal picker
  offering Claude.ai web, Claude Desktop, Codex CLI, and ChatGPT/GPT Actions.
- Add /oauth/connect-claude-ai backend route that redirects to Anthropic's
  official https://claude.ai/api/mcp/auth_callback OAuth callback.
- Update MCP callback result page with browser-specific instructions for
  Claude.ai web, Claude Desktop, ChatGPT/GPT Actions, and Codex CLI.
- Deploy new app and hermes images to K8s.
This commit is contained in:
Garfield
2026-06-12 14:55:36 -04:00
parent 51315527c0
commit 6604ab5d2b
6 changed files with 180 additions and 14 deletions

View File

@@ -252,9 +252,71 @@ logoutBtn.addEventListener('click', async () => {
showLogin();
});
// Connect MCP Client — start the browser OAuth flow
// Connect MCP Client — show picker for Claude.ai / ChatGPT / desktop / CLI
document.getElementById('connect-mcp-btn')?.addEventListener('click', () => {
window.open(`${API_BASE}/oauth/connect-mcp`, '_blank', 'width=560,height=600,noopener');
openModal(renderMcpClientPicker());
});
function renderMcpClientPicker() {
return `
<div class="mcp-picker">
<h3>Connect an AI client</h3>
<p class="picker-subtitle">Choose where you want to use SquareMCP tools.</p>
<div class="picker-option">
<div class="picker-meta">
<div class="picker-title">Claude.ai (web)</div>
<div class="picker-desc">Use SquareMCP directly in your browser at claude.ai.</div>
</div>
<a class="btn btn-primary" href="${API_BASE}/oauth/connect-claude-ai" target="_blank" rel="noopener" onclick="window.closeMcpPicker && window.closeMcpPicker()">Connect</a>
</div>
<div class="picker-option">
<div class="picker-meta">
<div class="picker-title">Claude Desktop</div>
<div class="picker-desc">macOS / Windows app with local MCP config.</div>
</div>
<button class="btn btn-primary" data-connect="claude-desktop">Connect</button>
</div>
<div class="picker-option">
<div class="picker-meta">
<div class="picker-title">Codex CLI / OpenCode</div>
<div class="picker-desc">Terminal-based agents (OpenAI, opencode).</div>
</div>
<button class="btn btn-primary" data-connect="codex">Connect</button>
</div>
<div class="picker-option">
<div class="picker-meta">
<div class="picker-title">ChatGPT (web)</div>
<div class="picker-desc">Copy the OpenAPI spec URL for GPT Actions.</div>
</div>
<button class="btn btn-secondary" data-connect="chatgpt">Get URL</button>
</div>
</div>
`;
}
window.closeMcpPicker = closeModal;
modalBody.addEventListener('click', (e) => {
const btn = e.target.closest('[data-connect]');
if (!btn) return;
const type = btn.dataset.connect;
if (type === 'claude-desktop' || type === 'codex') {
window.open(`${API_BASE}/oauth/connect-mcp`, '_blank', 'width=560,height=600,noopener');
} else if (type === 'chatgpt') {
openModal(`
<div class="mcp-picker">
<h3>ChatGPT / GPT Actions</h3>
<p class="picker-subtitle">ChatGPT browser does not yet support native MCP. Use this OpenAPI spec URL in a GPT Action:</p>
<div class="token-box" style="margin:16px 0;">${API_BASE}/openapi.json</div>
<p class="picker-subtitle">Set authentication to <strong>Bearer token</strong> and paste your API key from <em>Settings → API Keys</em>.</p>
<button class="btn btn-primary" onclick="window.open('${API_BASE}/openapi.json','_blank')">Open spec</button>
</div>
`);
}
});
// Password reset request