Connect an agent harness to GoodQA
GoodQA's MCP server is part of every GoodQA server: https://goodqa.app/v1/mcp, Streamable HTTP, authenticated with an
org API key sent as Authorization: Bearer <key>. The tools a key sees follow its org's switches (see
MCP tools); the live list is GET https://goodqa.app/v1/meta/mcp-remote.
Before you connect, read the rulebook for talking to people: the agent skill, also served
at https://goodqa.app/skill.md, GET /v1/meta/agent-skill and as MCP resource goodqa://skills/conversations.
1. Get a key, keep it out of files
An org admin creates the key in Settings (API keys), or with POST /v1/orgs/{orgId}/api-keys. Put it in the
environment of the harness, never in a prompt, a commit or a config file you share:
export GOODQA_API_KEY='bt_xxxxxxxx_secret' # from your secret store; never print it
No key, or a harness that cannot read one from the environment? Pair instead (section 6).
2. Claude Code
Project scope writes .mcp.json with the variable, not the key; Claude Code expands ${GOODQA_API_KEY} when it loads
the file:
claude mcp add --scope project --transport http goodqa https://goodqa.app/v1/mcp \
--header 'Authorization: Bearer ${GOODQA_API_KEY}'
{
"mcpServers": {
"goodqa": {
"type": "http",
"url": "https://goodqa.app/v1/mcp",
"headers": { "Authorization": "Bearer ${GOODQA_API_KEY}" }
}
}
}
Keep the single quotes: they stop your shell from pasting the key itself into the file.
3. Codex
codex mcp add goodqa --url https://goodqa.app/v1/mcp --bearer-token-env-var GOODQA_API_KEY
That writes this to $CODEX_HOME/config.toml (default ~/.codex/config.toml); Codex reads the key from the variable
at run time:
[mcp_servers.goodqa]
url = "https://goodqa.app/v1/mcp"
bearer_token_env_var = "GOODQA_API_KEY"
Codex reads project rules from AGENTS.md: https://goodqa.app/agents.md is a ready-made section to add to it.
4. Grok
grok mcp add goodqa https://goodqa.app/v1/mcp --transport http \
--header 'Authorization: Bearer ${GOODQA_API_KEY}'
That writes this to ~/.grok/config.toml (--scope project writes ./.grok/config.toml); Grok expands the variable
when it connects, and grok mcp doctor checks the connection:
[mcp_servers.goodqa]
url = "https://goodqa.app/v1/mcp"
enabled = true
[mcp_servers.goodqa.headers]
Authorization = "Bearer ${GOODQA_API_KEY}"
5. Muse
Muse keeps MCP servers in ${XDG_CONFIG_HOME:-~/.config}/muse/settings.json under mcpServers and reads header
values literally (no ${VAR} expansion), so either the file holds the key:
{
"schema_version": 1,
"mcpServers": {
"goodqa": {
"type": "streamable-http",
"url": "https://goodqa.app/v1/mcp",
"headers": { "Authorization": "Bearer <your key>" },
"mode": "optional"
}
}
}
(then keep the file readable by you only), or Muse runs the pairing bridge from section 6 as a stdio server and no
key is written anywhere:
"goodqa": { "type": "stdio", "command": "node", "args": ["/path/to/bundle.js"], "mode": "optional" }
Muse also reads AGENTS.md as project rules; add the section from https://goodqa.app/agents.md.
6. No key: pair in the browser
Download the bridge from https://goodqa.app/v1/mcp/download (goodqa.mcpb, a zip), unzip it and run
node bundle.js pair https://goodqa.app. It prints a code; a person approves it at https://goodqa.app/mcp/pair
and the bridge keeps its own credential. Then point a harness at node bundle.js as a stdio MCP server. Under the
hood this is POST /v1/mcp/pair/start and POST /v1/mcp/pair/poll.
7. Check it works
Call the whoami tool: it names the user the credential acts as (and, for a key confined to one member, that member). If a tool you expect is missing, the feature is
switched off for that org or not set up on that server: say so, never that it is available.
Reference
- Discovery: developers page,
GET /v1/meta/mcp-remote(live tool list, pairing),GET /.well-known/agent-skills, llms.txt. - Every tool with its parameters: the MCP tool reference; which switch adds which tool: MCP tools.
- The rules: the agent skill; every capability: the feature guides.
8. Opt-in Claude Code mods
The downloadable pack is GET /v1/claude-code/pack.zip; its checksum is GET /v1/claude-code/pack.sha256
(and X-GoodQA-Pack-SHA256 on the archive), with version and file inventory at GET /v1/claude-code/manifest.
These build-time files appear only after the deployment builds the pack. This branch has not been deployed.
unzip pack.zip -d goodqa-claude-code-pack
claude plugin marketplace add ./goodqa-claude-code-pack
/plugin install goodqa-mods@goodqa-harness
The last command is at the Claude Code prompt. For one session:
claude --plugin-dir ./goodqa-claude-code-pack/plugins/goodqa-mods.
Requires Claude Code 2.1.287+ and Node.js 22+. goodqa-mods is separate from the optional goodqa skills/MCP plugin.
Set GOODQA_PROJECT_IDS and keep GOODQA_API_KEY in the process environment. GOODQA_MODS=off disables all mods;
GOODQA_MODS_WRITE defaults off. /gq-ticket and /gq-next only read, /gq-secret explains secret requests,
and /gq-note and /gq-evidence show the exact redacted text and require a Confirm POST button.
Read the reach table and limitations before opting in. The status band reports whether QA Commander is listed; runtime health is unavailable to API keys. No secret, file or transcript is uploaded automatically. A fixed bundled Node transport constrains the origin, redirects, deadline and size; validation explicitly reports its process reach. No state file is written.