Harbor stores its configuration at ~/.harbor/config.toml. You can edit this file directly or manage everything through the desktop app and CLI.
File Location
Structure
Harbor Settings
[harbor]
gateway_port = 3100 # HTTP/SSE gateway port
gateway_host = "127.0.0.1" # Bind address (use "0.0.0.0" to expose to network)
gateway_token = "my-secret" # Bearer token for remote access (optional)
| Field | Type | Default | Description |
|---|
gateway_port | int | 3100 | Port the gateway listens on |
gateway_host | string | "127.0.0.1" | IP address to bind to. Use "0.0.0.0" to expose to the network. |
gateway_token | string | — | Bearer token required for non-localhost connections. Supports vault:KEY references. |
publish_relay | string | "relay.harbormcp.ai" | Relay server address for harbor publish |
publish_subdomain | string | — | Persistent subdomain to request when publishing |
publish_token | string | — | Auth token for the relay (supports vault:KEY references) |
publish_tools | string[] | — | Tools exposed remotely — omit to expose all |
publish_auto | bool | false | Auto-publish when the gateway starts |
publish_relay_key | string | — | Relay’s public key (hex) for self-hosted relay verification |
Servers
Each server is defined under [servers.<name>]. A server must have either command (stdio) or url (remote HTTP) — not both.
Stdio server example
[servers.memory]
source = "native:memory"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-memory"]
enabled = true
auto_start = false
Remote HTTP server example
[servers.github]
source = "native:github"
url = "https://api.githubcopilot.com/mcp/"
enabled = true
[servers.github.headers]
Authorization = "Bearer vault:github_personal_access_token"
Server Fields
| Field | Type | Default | Description |
|---|
source | string | — | How the server was sourced (e.g., native:github, registry:@mcp/server, "fleet" for team-managed servers) |
command | string | — | Executable to run (for stdio servers). Mutually exclusive with url. |
args | string[] | [] | Arguments passed to the command |
env | map | {} | Environment variables (supports vault:KEY references) |
url | string | — | URL for remote HTTP MCP servers. Mutually exclusive with command. |
headers | map | — | Custom HTTP headers for remote servers (supports vault:KEY references) |
enabled | bool | true | Whether the server is globally enabled |
auto_start | bool | false | Start this server automatically when Harbor launches |
hosts | map | {} | Per-host enable/disable overrides |
tool_allowlist | string[] | — | Only expose these tools (if set, all others are hidden) |
tool_blocklist | string[] | — | Hide these specific tools (applied after allowlist) |
tool_hosts | map | {} | Per-host tool allowlist overrides |
Either command or url is required — you must set exactly one. Setting both (or neither) is an error.
You can control which tools a server exposes using allowlists, blocklists, and per-host overrides:
[servers.github]
url = "https://api.githubcopilot.com/mcp/"
tool_allowlist = ["get_issues", "create_issue", "search_code"]
tool_blocklist = ["delete_repo"]
[servers.github.tool_hosts]
claude = ["get_issues", "search_code"] # Claude only sees these two tools
Resolution order:
- If a host-specific override exists in
tool_hosts, only those tools are allowed for that host.
- Otherwise, apply global
tool_allowlist (tool must be in it).
- Then apply global
tool_blocklist (tool must NOT be in it).
Hosts
Each host is defined under [hosts.<name>]:
[hosts.claude]
connected = true
[hosts.claude-desktop]
connected = true
[hosts.vscode]
connected = true
scope = "user"
Host Fields
| Field | Type | Default | Description |
|---|
connected | bool | false | Whether Harbor syncs to this host |
scope | string | — | Scope level (e.g., user or project) |
Valid host names: claude, claude-desktop, codex, vscode, cursor
Full Example
[harbor]
gateway_port = 3100
gateway_host = "127.0.0.1"
# Native remote server (GitHub via HTTP)
[servers.github]
source = "native:github"
url = "https://api.githubcopilot.com/mcp/"
enabled = true
[servers.github.headers]
Authorization = "Bearer vault:github_personal_access_token"
# Native stdio server (Filesystem)
[servers.filesystem]
source = "native:filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"]
enabled = true
auto_start = false
# Custom server with tool filtering
[servers.custom-api]
command = "npx"
args = ["-y", "my-mcp-server"]
enabled = true
tool_blocklist = ["dangerous_tool"]
[servers.custom-api.env]
API_KEY = "vault:my_api_key"
[servers.custom-api.hosts]
claude = true
codex = true
vscode = false
[hosts.claude]
connected = true
[hosts.claude-desktop]
connected = true
[hosts.codex]
connected = true
[hosts.vscode]
connected = true
[hosts.cursor]
connected = false
Publish settings example
[harbor]
gateway_port = 3100
gateway_host = "127.0.0.1"
publish_relay = "relay.harbormcp.ai"
publish_subdomain = "myname" # → myname.relay.harbormcp.ai
publish_token = "vault:relay_auth"
publish_auto = true # auto-publish when gateway starts
publish_tools = ["get_issues", "search_code"] # only expose these tools
For self-hosted relays, also set:
publish_relay = "relay.example.com:7800"
publish_relay_key = "a1b2c3..." # hex public key from harbor relay --print-key