Skip to main content

MCP Setup

How to connect hatch3r's MCP servers and manage secrets securely.

:::info Last verified 2026-04-28. Credential acquisition URLs and provider scope models reverified each audit cycle (P3 — Adapter & MCP Currency). :::

Overview

hatch3r ships with 10 MCP servers: 3 enabled by default (no env vars required) and 7 opt-in servers (GitHub, Brave Search, Sentry, Postgres, Linear, Azure DevOps, GitLab). All secrets are centralized in a single .env.mcp file at the project root (gitignored by default). MCP configs use ${env:VAR} placeholders so you never commit secrets.

Supported MCP Servers

hatch3r supports 10 MCP servers. Three are enabled by default (no API keys required) and seven are opt-in (require environment variables).

Default servers (no configuration needed):

ServerDescription
PlaywrightBrowser automation, web testing, and UI interaction
Context7Up-to-date, version-specific library documentation for LLMs
FilesystemFile management and code editing operations

Opt-in servers (require API keys):

ServerDescriptionRequired env vars
GitHubRepository management, code review, issues, PRs, and project boardsGITHUB_PAT
Azure DevOpsWork items, repos, pipelines, and boardsAZURE_DEVOPS_PAT, AZURE_DEVOPS_ORG
GitLabIssues, merge requests, pipelines, and project managementGITLAB_TOKEN
Brave SearchWeb research, fact-checking, and current information retrievalBRAVE_API_KEY
SentryError tracking and performance monitoringSENTRY_AUTH_TOKEN
PostgresPostgreSQL database queries and schema inspectionPOSTGRES_URL
LinearLinear issue tracking and project managementLINEAR_API_KEY

The platform-specific MCP server (GitHub, Azure DevOps, or GitLab) is automatically selected based on your detected platform during init.

Selecting MCP Servers During Init

When you run npx hatch3r init, step 6 asks which MCP servers to enable:

  1. hatch3r detects your platform (GitHub, Azure DevOps, or GitLab) and pre-selects the matching platform MCP server
  2. The three default servers (Playwright, Context7, Filesystem) are pre-checked
  3. You can toggle any server on or off using the interactive checkbox prompt
  4. After selection, hatch3r writes only the chosen servers to .agents/mcp/mcp.json

To change MCP servers after init, run npx hatch3r config. This re-presents the MCP server selection prompt pre-populated with your current choices.

Where MCP Config Lives

All adapters that support MCP emit tool-specific configuration during npx hatch3r init or npx hatch3r sync. The canonical MCP source is .agents/mcp/mcp.json; each adapter transforms it into the format and path the tool expects.

ToolConfig pathFormatNotes
Cursor.cursor/mcp.jsonJSON (direct copy)Also reads mcp.json at project root if using the Cursor plugin
Claude Code.mcp.jsonJSON (direct copy)Also generates .claude/settings.json with opinionated permissions
Copilot / VS Code.vscode/mcp.jsonJSON with env objectEnv vars passed via env object per server
OpenCodeopencode.jsonJSON (inline)MCP servers embedded in the top-level config under mcp key
Windsurf.windsurf/mcp.jsonJSONStandard mcpServers format
Amp.amp/settings.jsonJSONMCP servers under amp.mcpServers key
Codex.codex/config.tomlTOMLMCP servers as [mcp_servers.<name>] sections
Gemini.gemini/settings.jsonJSONMCP servers under mcpServers key alongside context and hooks
Cline / Roo.roo/mcp.jsonJSONStandard mcpServers format; remote servers use streamable-http transport
Kiro.kiro/settings/mcp.jsonJSONStandard mcpServers format

Connecting MCP Servers

Cursor

  1. Run npx hatch3r init and select MCP servers when prompted
  2. Config is written to .cursor/mcp.json and secrets template to .env.mcp
  3. Fill in your API keys in .env.mcp (see Managing Secrets)
  4. Restart Cursor for changes to take effect
  5. In Cursor: Settings -> Tools & MCP -- verify servers show a green dot

If using the Cursor plugin, the plugin provides mcp.json at the project root. Cursor loads project-level config from .cursor/mcp.json (takes precedence over global ~/.cursor/mcp.json).

Claude Code

Config goes to .mcp.json. Claude Code reads it from the project root. Fill in .env.mcp, source it, and restart Claude Code after init.

Other Hosts

See the Adapter Capability Matrix for per-tool output paths.

Managing Secrets

The .env.mcp file

hatch3r init generates a .env.mcp file at the project root containing every environment variable your selected MCP servers need. This file is covered by .gitignore (the .env.* pattern) and must never be committed.

# .env.mcp (generated by hatch3r init)
GITHUB_PAT=ghp_xxxxxxxxxxxx
BRAVE_API_KEY=xxxxxxxx

When you add new MCP servers and run hatch3r init or hatch3r sync, any new variables are appended to .env.mcp without overwriting existing values.

How secrets are loaded per editor

VS Code / Copilot -- Env vars are passed via the env object in .vscode/mcp.json. Source .env.mcp before launching or configure vars in VS Code settings.

Cursor -- Source .env.mcp before launching:

set -a && source .env.mcp && set +a && cursor .

Alternatively, add your tokens to ~/.zshrc / ~/.bashrc for persistent access, or paste them in Cursor: Settings -> Tools & MCP -> pencil icon next to each server.

Claude Code -- Source .env.mcp before launching:

set -a && source .env.mcp && set +a && claude

Other editors -- Same sourcing pattern. See the Adapter Capability Matrix for per-tool details.

Required environment variables

Default servers

ServerEnv varHow to get it
GitHubGITHUB_PATCreate a PAT -- see GitHub PAT scopes
Brave SearchBRAVE_API_KEYapi-dashboard.search.brave.com/register -- see Brave Search pricing notes

Opt-in servers (enable during init)

ServerEnv varHow to get it
SentrySENTRY_AUTH_TOKENSentry Auth Tokens -- see Sentry token types
PostgresPOSTGRES_URLYour PostgreSQL connection string
LinearLINEAR_API_KEYLinear API keys -- OAuth 2.0 also supported, see Linear authentication
Azure DevOpsAZURE_DEVOPS_PAT, AZURE_DEVOPS_ORGCreate a PAT -- see Azure DevOps authentication notes
GitLabGITLAB_TOKENCreate a PAT -- see GitLab token alternatives

GitHub PAT scopes

Classic PAT (Settings -> Developer settings -> Personal access tokens -> Tokens (classic)):

  • repo -- full control of private repositories (read/write code, issues, PRs)
  • read:org -- read org and team membership (needed for org projects)
  • project -- read/write access to GitHub Projects V2 (required for board commands: hatch3r-board-init, hatch3r-board-fill, hatch3r-board-groom, hatch3r-board-pickup, hatch3r-board-refresh)

Fine-grained PAT (recommended):

PermissionAccessRequired for
ContentsRead and writeCode, file operations
IssuesRead and writeIssue creation, labeling, assignment
Pull requestsRead and writePR creation, review, merge
ProjectsRead and writeBoard commands (hatch3r-board-init, etc.)
MetadataReadRepository metadata (auto-granted)
Members (Organization)ReadOrg projects and team membership

Fine-grained tokens have limitations (e.g. user-owned Projects V2 may require classic PATs).

Note: If board commands fail with GraphQL permission errors, the most likely cause is a missing project scope. For classic PATs, add the project scope. For fine-grained PATs, ensure Projects has read and write access. You can also run gh auth refresh -s project if using the GitHub CLI.

User-owned Projects V2 caveat: As of 2026, fine-grained PATs still cannot access Projects V2 owned by a user account (only org-owned projects). For board commands targeting a user-owned project, use a classic PAT with the project scope.

Brave Search pricing notes

Brave retired the free tier of its Search API in 2026 and moved every account onto credit-based billing.

  • New users receive $5 in credits each month (~1,000 web search queries at $5 / 1,000 requests). A credit card is required at sign-up as an anti-fraud measure even for credit-only usage.
  • Legacy users who were on the original 2,000 queries / month free plan are grandfathered to that allowance.
  • Sign up at api-dashboard.search.brave.com/register. The older brave.com/search/api/ URL still works but redirects to the dashboard for key creation.
  • Paid tiers: Basic ($5 / 20k queries), Starter ($20 / 100k), Standard ($40 / 500k), Enterprise (custom).

Sentry token types

Sentry supports two auth-token types:

  • User Auth Tokens (sentry.io/settings/account/api/auth-tokens/) — tied to your personal account. Best for individual MCP use.
  • Organization Auth Tokens (Org Settings → Auth Tokens) — tied to the org rather than a single user. Recommended for shared / CI / production use because they survive personnel changes.

For MCP, set SENTRY_AUTH_TOKEN to whichever token matches your scope. Read scopes (org:read, project:read, event:read) are sufficient for the read-only error / performance views the Sentry MCP server exposes.

Linear authentication

Linear supports two auth methods for the API used by the MCP server:

  • Personal API keys (linear.app/settings/api) — quickest to set up, good for individual / single-user MCP. Set LINEAR_API_KEY to the generated key.
  • OAuth 2.0 — recommended for shared installations, multi-user products, or anything that needs to act on behalf of multiple Linear accounts. Use OAuth actor authorization for integration scenarios.

For the typical single-developer MCP setup, the personal API key is the right call.

Azure DevOps authentication notes

Microsoft now actively recommends Microsoft Entra ID tokens, managed identities, or service principals over PATs (PATs are flagged in the Microsoft Learn docs as "long-lived credentials [that] can be leaked, stolen, or misused"). PATs still work for hatch3r MCP today, but be aware:

  • For Microsoft Entra-backed organizations, you must sign in to Azure DevOps via the full auth flow at least every 90 days for your PAT to remain active.
  • Tokens are 84 characters long and include a fixed AZDO signature at positions 76–80 — useful for secret-scanning rules.
  • Microsoft also publishes an Azure DevOps MCP Server (/azure/devops/mcp-server/mcp-server-overview); hatch3r ships the @tiberriver256/mcp-server-azure-devops STDIO server today, but the official server is an alternative if you prefer Microsoft-maintained tooling.

For least-privilege automation, see Microsoft's guidance on reducing PAT usage.

GitLab token alternatives

Personal access tokens are the simplest path for individual MCP use, but for automation contexts GitLab offers narrower-scope alternatives:

  • Project Access Tokens — bound to a single project, no human user account needed; preferred for project-specific automation.
  • Group Access Tokens — same idea at the group level.
  • CI/CD Job Tokens — fine-grained permissions scoped to a pipeline run; preferred for pipeline-driven workflows.

For self-hosted GitLab, also set GITLAB_HOST=https://gitlab.example.com in .env.mcp.

Verifying connection

  1. Restart your editor after setting secrets
  2. Check MCP status: Cursor shows green dots in Settings -> Tools & MCP
  3. In chat/composer, check "Available Tools" -- you should see tools from each enabled server

Server Details

ServerTypeRequiresNotes
GitHubRemoteGITHUB_PAThttps://api.githubcopilot.com/mcp/ with X-MCP-Toolsets
Context7STDIO--Up-to-date library docs
FilesystemSTDIO--Uses . (project root) as allowed directory
PlaywrightSTDIO--Browser automation
Brave SearchSTDIOBRAVE_API_KEYWeb research and fact-checking
SentrySTDIOSENTRY_AUTH_TOKENError tracking and performance monitoring
PostgresSTDIOPOSTGRES_URLDatabase queries and schema inspection
LinearSTDIOLINEAR_API_KEYIssue tracking and project management
Azure DevOpsSTDIOAZURE_DEVOPS_PAT, AZURE_DEVOPS_ORGBoards, work items, repos
GitLabSTDIOGITLAB_TOKENIssues, merge requests, boards

How MCP Config Is Distributed to Adapters

During hatch3r init or hatch3r sync, the canonical MCP config at .agents/mcp/mcp.json is transformed into tool-specific formats for each selected adapter. The process works as follows:

  1. Canonical source -- .agents/mcp/mcp.json contains the mcpServers object with only the servers you selected during init
  2. Adapter transformation -- each adapter reads the canonical config and writes it to the tool-specific path and format
  3. Secret injection -- environment variable placeholders (${env:VAR}) are preserved in all generated configs. The actual values are read from .env.mcp at runtime

The adapter capability matrix determines which adapters emit MCP config:

AdapterEmits MCPOutput pathFormat notes
CursorYes.cursor/mcp.jsonDirect JSON copy
Claude CodeYes.mcp.jsonDirect JSON copy
Copilot / VS CodeYes.vscode/mcp.jsonEnv vars via env object per server
OpenCodeYesopencode.jsonEmbedded under mcp key
WindsurfYes.windsurf/mcp.jsonStandard mcpServers format
AmpYes.amp/settings.jsonUnder amp.mcpServers key
CodexYes.codex/config.tomlTOML [mcp_servers.<name>] sections
GeminiYes.gemini/settings.jsonUnder mcpServers key
Cline / RooYes.roo/mcp.jsonStandard mcpServers format
KiroYes.kiro/settings/mcp.jsonStandard mcpServers format

When you run hatch3r sync or hatch3r config, all adapter MCP configs are regenerated from the canonical source, ensuring consistency across tools.

Adding Custom MCP Servers

You can add custom MCP servers by editing .agents/mcp/mcp.json directly. Add your server definition to the mcpServers object:

{
"mcpServers": {
"playwright": { "..." : "..." },
"context7": { "..." : "..." },
"my-custom-server": {
"command": "npx",
"args": ["-y", "@my-org/my-mcp-server"],
"env": {
"MY_API_KEY": "${env:MY_API_KEY}"
}
}
}
}

After adding a custom server:

  1. Add any required environment variables to .env.mcp
  2. Run npx hatch3r sync to propagate the config to all adapter output paths
  3. Restart your editor for changes to take effect

Custom servers persist across hatch3r sync and hatch3r update operations. However, hatch3r init regenerates mcp.json from the template -- if you re-run init, your custom servers will need to be re-added.

:::info MCP version-pin check (1.6.0) npx hatch3r validate warns on unpinned npx @scope/pkg invocations and @latest tags in MCP server configs — both are supply-chain risks (per Palo Alto Networks' 2025 npm supply-chain attack report and OWASP ASI 2026). Pin to a specific version or SHA to clear the warning. :::

tip

For remote (HTTP-based) MCP servers, use the url and headers fields instead of command/args:

{
"my-remote-server": {
"url": "https://my-api.example.com/mcp/",
"headers": {
"Authorization": "Bearer ${env:MY_API_TOKEN}"
}
}
}