| name | harness-mcp |
| description | Create and manage MCP server config entities in the agent-harness workspace. |
/harness-mcp
Use this skill to create, edit, and manage mcp entities in the agent-harness workspace. An mcp entity defines one or more MCP (Model Context Protocol) servers in a single JSON config file. When harness apply runs, all mcp config files are merged and rendered into each enabled provider's native format.
What is an mcp entity?
An mcp entity is a JSON file under .harness/src/mcp/<config-id>.json. It contains a map of server definitions keyed by server ID. Multiple mcp config files are supported — harness merges them at apply time. If the same server ID appears in more than one file, harness rejects the plan with a collision error.
Source path: .harness/src/mcp/<config-id>.json
The file is a flat JSON object where each top-level key is a server ID and its value is the server definition. Any key-shape that does not use a reserved wrapper key (servers or mcpServers) is treated as a direct server map; files that happen to use those wrapper keys are unwrapped automatically before merging.
Provider output mapping
| Field | Claude Code | OpenAI Codex CLI | GitHub Copilot | Cursor |
|---|
| Output file | .mcp.json | .codex/config.toml | .vscode/mcp.json | .cursor/mcp.json |
| Root key | mcpServers | [mcp_servers.<id>] | servers | mcpServers |
| Format | JSON | TOML | JSON | JSON |
Claude Code — .mcp.json
Root key: mcpServers. Each server entry supports:
| Field | Type | Description |
|---|
command | string | Executable to run (stdio transport) |
args | string[] | Arguments passed to the command |
env | object | Environment variables forwarded to the server process |
type | string | Transport: stdio (default), sse, or http |
url | string | Endpoint URL (for sse / http transport) |
Project-scoped MCP servers live in .mcp.json at the repo root. This is the file harness writes.
Official docs: https://code.claude.com/docs/en/mcp
OpenAI Codex CLI — .codex/config.toml
Section: [mcp_servers.<id>]. Fields rendered by harness are command, args, and env. The full field set supported by Codex config includes:
| Field | Type | Description |
|---|
command | string | Launcher command for a stdio MCP server |
args | string[] | Arguments passed to the command |
cwd | string | Working directory for the server process |
env | map | Environment variables forwarded to the server |
env_vars | string[] | Additional env vars to whitelist |
url | string | Endpoint for an HTTP/streamable MCP server |
bearer_token_env_var | string | Env var name supplying the bearer token (HTTP) |
enabled | boolean | Disable without removing (default: true) |
enabled_tools | string[] | Allowlist of tool names exposed by this server |
disabled_tools | string[] | Denylist applied after enabled_tools |
required | boolean | Fail startup if server cannot initialize |
startup_timeout_sec | number | Override default 10 s startup timeout |
tool_timeout_sec | number | Override default 60 s per-tool timeout |
Official docs: https://developers.openai.com/codex/config-reference
GitHub Copilot — .vscode/mcp.json
Root key: servers. Each server entry supports:
| Field | Type | Description |
|---|
type | string | Transport: stdio (default), sse, or http |
command | string | Executable to run (stdio) |
args | string[] | Arguments passed to the command |
env | object | Environment variables |
url | string | Remote server endpoint (sse / http) |
inputs | object | Input variable definitions for sensitive data |
Official docs: https://code.visualstudio.com/docs/copilot/chat/mcp-servers
Cursor — .cursor/mcp.json
Root key: mcpServers. Each server entry supports:
| Field | Type | Description |
|---|
command | string | Executable to run (stdio transport) |
args | string[] | Arguments passed to the command |
env | object | Environment variables forwarded to the server process |
envFile | string | Path to an .env file (stdio only) |
type | string | Transport: stdio (default) |
url | string | Endpoint URL (for sse / Streamable HTTP transport) |
headers | object | HTTP headers (for remote servers) |
auth | object | Static OAuth credentials (CLIENT_ID, CLIENT_SECRET, scopes) |
Cursor supports three transport methods: stdio (local), SSE (local/remote), and Streamable HTTP (local/remote). Protocol capabilities include tools, prompts, resources, roots, elicitation, and MCP apps (interactive UI extension).
Configuration locations: project (.cursor/mcp.json) or global (~/.cursor/mcp.json).
Config interpolation supported in command, args, env, url, and headers:
${env:NAME} — environment variables
${userHome} — home directory
${workspaceFolder} — project root
${workspaceFolderBasename} — project root name
${pathSeparator} / ${/} — OS path separator
Official docs: https://docs.cursor.com/context/mcp
Canonical source format
The harness source file is a plain JSON object. Use one server-ID key per server you want to register:
{
"<server-id>": {
"command": "...",
"args": ["..."],
"env": {
"VAR_NAME": "value"
}
}
}
You may define as many servers as needed in one file, or split them across multiple mcp entity files. Harness merges all files before rendering — server IDs must be unique across all files.
Remote server URLs
For sse / http transport servers, write the endpoint under url — every supported provider (Claude Code,
OpenAI Codex CLI, GitHub Copilot, Cursor) reads a remote server's endpoint from a field named url, never
serverUrl. As a compatibility alias, harness accepts serverUrl in the source file and rewrites it to url in
every rendered artifact, but new configs should use url directly:
{
"figma": {
"url": "https://mcp.figma.com/mcp"
}
}
Harness CLI commands
npx harness add mcp <config-id>
npx harness apply
npx harness plan
npx harness remove mcp <config-id>
npx harness remove mcp <config-id> --no-delete-source
Copy-paste example
.harness/src/mcp/servers.json — a filesystem server and a Postgres server:
{
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
"env": {}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "${POSTGRES_CONNECTION_STRING}"
}
}
}
After running npx harness apply, harness writes:
.mcp.json (Claude Code):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "actual-value-from-env"
}
}
}
}
.codex/config.toml (Codex CLI):
[mcp_servers.filesystem]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
[mcp_servers.postgres]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-postgres"]
[mcp_servers.postgres.env]
POSTGRES_CONNECTION_STRING = "actual-value-from-env"
.vscode/mcp.json (GitHub Copilot):
{
"servers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "actual-value-from-env"
}
}
}
}
Environment variable substitution
Use ${ENV_VAR_NAME} placeholders anywhere in the JSON values. Harness substitutes them at apply time using the process environment. This keeps secrets out of source-controlled files.
{
"my-api-server": {
"command": "npx",
"args": ["-y", "my-mcp-server"],
"env": {
"API_KEY": "${MY_API_KEY}",
"BASE_URL": "${MY_API_BASE_URL}"
}
}
}
If a referenced variable is not set in the environment, harness will error during apply.
Typical workflow
npx harness provider enable claude
npx harness provider enable codex
npx harness provider enable copilot
npx harness add mcp servers
npx harness plan
npx harness apply
Official documentation