MCP Server
Connect AI coding tools like Claude Code and Cursor to QA Note with a single OAuth click — query and manage issues directly
Table of Contents
- What is MCP?
- One-click install
- Auth methods at a glance
- Method A. Remote HTTP + one-click OAuth (recommended)
- Claude Code
- Cursor
- Codex (OpenAI)
- OAuth flow under the hood
- Method B. Local binary (stdio · npx)
- Claude Code
- Cursor / Codex
- Authentication flow
- Method C. API Key (CI · headless · fallback)
- API Key with Remote HTTP
- API Key with stdio binary
- Environment variables (stdio binary)
- Available tools
- Query tools
- Write tools
- Recommended workflows
- Verify setup
- Troubleshooting
- OAuth browser window does not open (Remote HTTP)
- "Unauthorized" error
- MCP server won't connect (stdio binary)
- Reset token/session
- SSH · Docker — no browser available
What is MCP?
MCP (Model Context Protocol) is a standard protocol that lets AI coding tools access external data. By connecting the QA Note MCP server, you can query issue data, change statuses, and leave comments directly from Claude Code, Cursor, Codex, and other tools.
Since QA Note delivers rich technical metadata (console logs, network requests, JS errors, performance metrics, React component trees, user actions, element styles, DOM snapshots) to the AI in a structured form, issue-context-based debugging becomes possible.
One-click install
Pick the MCP client you use and the copy or deep-link action runs immediately. The first connection opens a single browser OAuth consent window.
Pick your MCP client
Each card triggers a copy or deep-link install. The first connection opens a one-time browser OAuth consent.
Claude Code
One CLI line · OAuth one-click
Paste into your terminal — the browser sign-in + consent window opens automatically.
Official install docsCodex
Shared CLI/IDE config.toml · OAuth login
Run it in your terminal to register the server, then complete OAuth in the browser. The IDE extension uses the same config.
Official install docsClaude Desktop
Copy the mcpServers config JSON
Config file: macOS ~/Library/Application Support/Claude/claude_desktop_config.json · Windows %APPDATA%\Claude\claude_desktop_config.json
Official install docsCursor
One-click deep link into Cursor
Not using Cursor? Paste the config JSON into ~/.cursor/mcp.json instead.
Official install docsWindsurf
Copy the mcpServers config JSON (serverUrl key)
Paste into Windsurf → Cascade → MCP Servers → Add Server.
Official install docsChatGPT
Developer Mode connector URL
ChatGPT → Settings → Connectors → enable Developer Mode → Add MCP server.
Official install docsAuth methods at a glance
| Method | When to use | Key required | Recommendation |
|---|---|---|---|
| Remote HTTP + OAuth | Everyday desktop use (Claude Code, Cursor, Codex) | No (one-time browser consent) | ★★★ Default |
| stdio local binary | Corporate proxy blocks HTTP MCP · offline credential cache | No (same OAuth) | ★★ |
| API Key | CI/CD · headless servers · MCP clients without OAuth | Yes, manual qn_... from dashboard | ★ (fallback) |
The default path is one-click OAuth — no need to paste an Authorization header. Claude Code discovers the QA Note authorization server through the standard MCP discovery endpoint (
/.well-known/oauth-protected-resource) and performs Dynamic Client Registration (RFC 7591) → Authorization Code + PKCE S256 → access/refresh token exchange automatically.
Method A. Remote HTTP + one-click OAuth (recommended)
Connect directly to the hosted MCP endpoint at https://qanote.app/api/mcp. No binary install, no API key copy-paste.
Claude Code
One line in your terminal:
claude mcp add --transport http qanote https://qanote.app/api/mcp
After registering, run /mcp in Claude Code — your browser opens automatically, and a single QA Note sign-in + consent completes authentication. The resulting access/refresh tokens are stored safely inside Claude Code and refreshed transparently from then on.
Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"qanote": {
"url": "https://qanote.app/api/mcp"
}
}
}
No headers — Cursor launches the OAuth browser window on first tool call.
Codex (OpenAI)
Same entry under mcpServers in your Codex CLI config:
{
"mcpServers": {
"qanote": {
"url": "https://qanote.app/api/mcp"
}
}
}
OAuth flow under the hood
- The client calls
https://qanote.app/api/mcp→401 UnauthorizedwithWWW-Authenticate: Bearer resource_metadata=... - The client reads
/.well-known/oauth-protected-resource(RFC 9728) →/.well-known/oauth-authorization-server(RFC 8414) to get the authorization server metadata - Dynamic Client Registration (RFC 7591) issues a
client_idautomatically (no user action needed) - Authorization Code + PKCE S256 flow — browser sign-in + MCP consent
/api/oauth/tokenreturns an access token (scopesmcp+offline_access, bound withaud=https://qanote.app/api/mcp— RFC 8707) and a refresh token- Subsequent requests silently refresh via refresh-token rotation
The "MCP Prompt" button on each issue page copies a prompt that embeds the issue permalink so the LLM can pull the full context with a single resolve_by_url call.
Method B. Local binary (stdio · npx)
Use this when your corporate network blocks HTTP MCP, or when you want credentials cached locally for offline/SSH environments. The auth itself is the same OAuth browser flow.
Claude Code
claude mcp add qanote -- npx -y @qanote/mcp-server
Cursor / Codex
{
"mcpServers": {
"qanote": {
"command": "npx",
"args": ["-y", "@qanote/mcp-server"]
}
}
}
Authentication flow
- On first launch, if no stored credential exists, the browser opens automatically
- Log in with your QA Note account (if already signed in, only the consent step remains)
- The resulting token is saved to
~/.qanote/credentials.jsonwithchmod 600(valid 30 days by default) - Subsequent runs reuse the stored token automatically; on expiry the browser opens again
To reset credentials:
rm ~/.qanote/credentials.json
Method C. API Key (CI · headless · fallback)
Use this only in environments where a browser cannot be opened (CI/CD, containers, remote servers) or with MCP clients that do not support OAuth.
- QA Note Dashboard → Organization Settings → API Keys
- "New API Key" → enter a name (e.g.,
Claude Code MCP), pick an expiry → "Create" - Copy the displayed key (
qn_...) immediately to a safe location (shown only once)
API Key with Remote HTTP
claude mcp add --transport http qanote https://qanote.app/api/mcp \
--header "Authorization: Bearer qn_YOUR_KEY"
Cursor / Codex JSON:
{
"mcpServers": {
"qanote": {
"url": "https://qanote.app/api/mcp",
"headers": { "Authorization": "Bearer qn_YOUR_KEY" }
}
}
}
API Key with stdio binary
{
"mcpServers": {
"qanote": {
"command": "npx",
"args": ["-y", "@qanote/mcp-server"],
"env": {
"QANOTE_API_KEY": "qn_YOUR_KEY"
}
}
}
}
Environment variables (stdio binary)
| Variable | Required | Description | Default |
|---|---|---|---|
QANOTE_API_KEY | Optional | API Key (qn_...). Uses OAuth browser login if not set | — |
QANOTE_URL | Optional | QA Note server URL | https://qanote.app |
Remote HTTP does not need environment variables since the client specifies the url directly.
Available tools
Query tools
| Tool | Description |
|---|---|
resolve_by_url | Load an issue + tech context in one call from a permalink (recommended entry point) |
list_projects | List accessible projects |
search_issues | Search and filter issues (status · priority · labels · query) |
get_issue | Issue detail + metadata summary |
get_console_logs | Browser console logs (errors/warnings sorted first) |
get_network_logs | Network request logs (errors only by default, full list available) |
get_user_actions | Pre-issue user actions converted to natural language |
get_tech_context | Combined JS errors · performance · React tree · environment info |
get_element_styles | Computed style · box model · parent/sibling gap |
get_performance_metrics | Web Vitals · Navigation Timing |
get_environment_info | Browser · OS · network · GPU · fonts, etc. |
get_js_errors | Runtime errors + stack trace |
get_react_component_tree | React component tree snapshot |
get_storage | localStorage · sessionStorage · cookies (masked) |
get_dom_snapshot | DOM outerHTML (scripts and input values masked) |
get_screenshots | Screenshot URLs + embedded image content |
Write tools
| Tool | Description |
|---|---|
update_issue | Change issue status/priority |
add_comment | Add a comment to an issue |
Recommended workflows
Just make natural-language requests to your AI coding tool:
# Search issues
"Find critical issues in QA Note"
# Debugging context
"Show me the console errors and network logs for issue #42"
# Reproduce user behavior
"Tell me what the user did in issue #15"
# Update an issue
"Move issue #42 to resolved and leave a comment about the fix"
Optimal debugging sequence:
- Copy a permalink-embedded prompt from the "MCP Prompt" button on any issue page → one
resolve_by_urlcall - Dig deeper with
get_tech_context·get_console_logs·get_network_logs - After resolution, call
update_issueto change status andadd_commentto record cause/fix
Verify setup
After setup, try asking your AI tool:
Show me the project list from QA Note
If the project list appears, setup is complete.
Troubleshooting
OAuth browser window does not open (Remote HTTP)
- In firewall/popup-blocker environments, copy the
authorizeURL printed by Claude Code into a browser manually to finish sign-in + consent. The token is then saved automatically. - If a corporate proxy blocks
.well-known/oauth-*discovery, switch to Method B (stdio binary) or use Method C (API Key).
"Unauthorized" error
- OAuth path: the stored token has expired or was revoked. Restart the MCP server to re-trigger browser login. For the stdio binary, delete
~/.qanote/credentials.json. - API Key path: verify the key starts with
qn_and has not been revoked. To access a different organization's resources, issue a new key in that organization.
MCP server won't connect (stdio binary)
- Run
npx -y @qanote/mcp-serverdirectly in your terminal to confirm it boots - Requires Node.js 20+
- Check that
QANOTE_URL/QANOTE_API_KEYare set correctly in the MCP config'senvblock
Reset token/session
# stdio binary
rm ~/.qanote/credentials.json
# Remote HTTP (Claude Code)
claude mcp remove qanote
claude mcp add --transport http qanote https://qanote.app/api/mcp
SSH · Docker — no browser available
→ Use Method C (API Key). Injecting the key via environment variable or --header is the safest option for CI/CD pipelines.