MCP client setups
Exact setup for each client, read from its official documentation.
The server is at https://app.harnesslab.co/mcp and speaks Streamable HTTP with plain JSON replies. Every setup below reads the key from the environment variable HARNESSLAB_API_KEY
(except where the client has its own way to hold a secret, and says so). Set the variable first:
macOS and Linux
Add this to ~/.zshrc or ~/.bashrc, then open a new terminal.
export HARNESSLAB_API_KEY="paste-your-key-here"Windows (PowerShell)
Run this once, then open a new terminal.
[Environment]::SetEnvironmentVariable("HARNESSLAB_API_KEY", "paste-your-key-here", "User")
Claude Code
One command, or a .mcp.json file you can commit because it holds no key.
Run this in a terminal. Add --scope user to use the server in every project.
claude mcp add --transport http harnesslab https://app.harnesslab.co/mcp --header "Authorization: Bearer $HARNESSLAB_API_KEY"Or put this in .mcp.json at the root of a project. Claude Code expands the variable when it starts, so the file holds no key.
{
"mcpServers": {
"harnesslab": {
"type": "http",
"url": "https://app.harnesslab.co/mcp",
"headers": {
"Authorization": "Bearer ${HARNESSLAB_API_KEY}"
}
}
}
}- The command saves the value of the variable into your Claude Code configuration. If you share that file, use the .mcp.json form.
- The command does not check the key. Type /mcp in Claude Code to see the server connect.
- The prompts of the server appear as /mcp__harnesslab__build_plan, /mcp__harnesslab__compare_on_topic and /mcp__harnesslab__review_design.
Format read from the client's documentation on 2026-10-28.
Claude Desktop
A custom connector with a request header. There is no configuration file for remote servers.
In Claude Desktop (or claude.ai): Customize, Connectors, Add, Add custom connector. Enter these values.
Name: harnesslab
Remote MCP URL: https://app.harnesslab.co/mcp
Sign in: No sign in
Request header: Authorization = Bearer <your key>- Request headers are the way to give a connector a fixed API key. You type the key into Claude; there is no environment variable.
- Custom connectors need a plan that allows them (the Free plan has one). The connection is made from Anthropic's cloud, which can reach this public server.
- claude_desktop_config.json is for local servers. Anthropic's page does not list remote servers there, so use the connector.
Format read from the client's documentation on 2026-10-28.
Cursor
A url and a headers object in mcp.json. Cursor expands ${env:NAME}.
.cursor/mcp.json in a project, or ~/.cursor/mcp.json for every project.
{
"mcpServers": {
"harnesslab": {
"url": "https://app.harnesslab.co/mcp",
"headers": {
"Authorization": "Bearer ${env:HARNESSLAB_API_KEY}"
}
}
}
}- Start Cursor from a terminal that has the variable, or set it for your whole user account, then restart Cursor.
Format read from the client's documentation on 2026-10-28.
VS Code (GitHub Copilot)
VS Code asks you for the key once and stores it. The file holds no key.
.vscode/mcp.json in a workspace, or open MCP: Open User Configuration for every workspace.
{
"inputs": [
{
"type": "promptString",
"id": "harnesslab-key",
"description": "Harness Lab API key (hek_...)",
"password": true
}
],
"servers": {
"harnesslab": {
"type": "http",
"url": "https://app.harnesslab.co/mcp",
"headers": {
"Authorization": "Bearer ${input:harnesslab-key}"
}
}
}
}- The top-level key is servers (not mcpServers) and the type is http.
- VS Code prompts for the key the first time the server starts. Paste your hek_ key there.
Format read from the client's documentation on 2026-10-28.
Windsurf
A serverUrl and a headers object in mcp_config.json. Windsurf expands ${env:NAME}.
Open Cascade's MCP settings and edit mcp_config.json (the docs give ~/.config/devin/mcp_config.json, and %AppData%\devin\mcp_config.json on Windows). Then press refresh.
{
"mcpServers": {
"harnesslab": {
"serverUrl": "https://app.harnesslab.co/mcp",
"headers": {
"Authorization": "Bearer ${env:HARNESSLAB_API_KEY}"
}
}
}
}- Windsurf's documentation moved to docs.devin.ai and names the path above. Older guides name ~/.codeium/windsurf/mcp_config.json. Check which one your version reads.
- The key must be set before Windsurf starts. An unset variable becomes an empty string and the server answers 401.
Format read from the client's documentation on 2026-10-28.
Codex
A table in config.toml that names the variable holding the token.
Add this to ~/.codex/config.toml (or .codex/config.toml in a trusted project).
[mcp_servers.harnesslab]
url = "https://app.harnesslab.co/mcp"
bearer_token_env_var = "HARNESSLAB_API_KEY"- codex mcp add harnesslab --url https://app.harnesslab.co/mcp writes the first line of this table. Add the bearer_token_env_var line yourself.
- Codex sends the variable's value as the Authorization: Bearer header.
Format read from the client's documentation on 2026-10-28.
Gemini CLI
httpUrl (not url, which is SSE) and headers in settings.json.
Run this in a terminal. Add -s user to save it for every project.
gemini mcp add --transport http --header "Authorization: Bearer $HARNESSLAB_API_KEY" harnesslab https://app.harnesslab.co/mcpOr edit ~/.gemini/settings.json (or .gemini/settings.json in a project).
{
"mcpServers": {
"harnesslab": {
"httpUrl": "https://app.harnesslab.co/mcp",
"headers": {
"Authorization": "Bearer $HARNESSLAB_API_KEY"
}
}
}
}- Gemini CLI documents $VAR expansion for the env block. It does not say headers are expanded, so the command is the safe route: your shell expands the variable once and the file then holds the key. Keep that file out of git.
- If the server answers 401 with the settings.json form, use the command.
Format read from the client's documentation on 2026-10-28.
curl
Plain JSON-RPC over one POST. Good for scripts and for seeing what the server says.
1. Discover the server: its name, protocol versions and capabilities.
curl -sS https://app.harnesslab.co/mcp \
-H "Authorization: Bearer $HARNESSLAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'2. List the tools your key can call.
curl -sS https://app.harnesslab.co/mcp \
-H "Authorization: Bearer $HARNESSLAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'3. Call a tool.
curl -sS https://app.harnesslab.co/mcp \
-H "Authorization: Bearer $HARNESSLAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_catalog","arguments":{"kind":"harnesses"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'- Every request is a new POST. The server keeps no session. Clients on the 2025 protocol versions send initialize first; the server answers that too.
- Add | jq . to read the reply.
Format read from the client's documentation on 2026-10-28.
Another client
Any client that supports remote MCP servers over Streamable HTTP with a custom header will work: the URL is https://app.harnesslab.co/mcp and the header is Authorization: Bearer <your key>.
Clients that only offer OAuth sign-in cannot use this server yet; see the changelog.