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/mcp

Or 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.