← Portfolio/free-code

free-code

MCP — connect external tools, with credentials kept out of your config.

What is MCP?

The Model Context Protocol lets free-code talk to external tool servers — databases, APIs, CI systems, design tools.

An MCP server exposes a set of tools over a standard protocol. Once a server is configured and enabled, its tools appear in your next free-code session automatically — alongside the built-in read, bash, and code graph tools — and the agent can call them like any other tool.

free-code supports two kinds of server:

  • stdio — a local process free-code launches (defined with command + args). Most servers, including Docker- and npx-based ones.
  • HTTP — a remote endpoint free-code connects to (defined with url).
Newly added servers start disabled
Adding a server to mcp.json does not auto-start it. You opt in explicitly with /mcp enable <name> — so importing a config never silently runs code. See Enabling servers.

Where the configuration lives

Server definitions and secrets are plain files under .free-code/.

FilePurpose
~/.free-code/agent/mcp.json Global server definitions — available in every project.
<project>/.free-code/mcp.json Project-local server definitions. Merged over the global file; on a name clash the project copy wins.
~/.free-code/agent/.env Global secrets (tokens, API keys) as KEY=VALUE.
<project>/.free-code/.env Project-local secrets. Override the global .env for that project.
~/.free-code/agent/mcp-status.json Which servers are enabled/disabled. Managed by the /mcp command — you normally don't edit it by hand.
Server definitions and activation are separate on purpose
You can edit mcp.json freely without changing which servers start — that state lives in mcp-status.json.

Adding a server

Edit mcp.json — global or project-local — under the mcpServers key.

stdio server (a local command)

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {}
    }
  }
}

Paths in command and args may use ~, $HOME, or ${HOME} — they are expanded without needing a shell.

HTTP server (a remote endpoint)

{
  "mcpServers": {
    "my-remote": {
      "type": "http",
      "url": "https://mcp.example.com/endpoint"
    }
  }
}

After editing, run /mcp enable <name> and then /reload (or start a new session) for the tools to appear.

Tokens & API keys

Keep credentials in .env, out of mcp.json.

For stdio servers, free-code injects environment variables into the server process from, in increasing priority:

  1. the global ~/.free-code/agent/.env
  2. the project-local <project>/.free-code/.env
  3. any env block written directly in the server's mcp.json entry (wins on conflict)

Recommended: put the secret in .env

Add the credential as a KEY=VALUE line:

# ~/.free-code/agent/.env
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxxxxxxxxxxxxxxx
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx

The server process inherits these in its environment, so a server that reads GITHUB_PERSONAL_ACCESS_TOKEN just works. For Docker-based servers, forward the variable with -e:

{
  "mcpServers": {
    "github": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"]
    }
  }
}
Prefer .env over inline env
Writing secrets inside mcp.json works, but that file is the one you copy, import, and share. Keeping tokens in .env avoids leaking them. Add .free-code/.env to your .gitignore.

OAuth servers (browser login)

Some remote servers authenticate via OAuth instead of a static token. Run them through the mcp-remote bridge as a stdio server:

{
  "mcpServers": {
    "linear": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.linear.app/sse"]
    }
  }
}

On first connect, free-code detects the authorization URL the server prints and surfaces it in the UI — open it in your browser to complete the login. No token to copy by hand.

Enabling servers & the /mcp commands

Control which servers start, and import configs from other tools.

CommandWhat it does
/mcp list List every configured server with its state — [on] (enabled) or [off] (disabled).
/mcp enable <name> Mark a server to start automatically. Takes effect after /reload or a new session.
/mcp disable <name> Stop a server from starting automatically.
/mcp-import Import MCP server definitions from another tool (see below).
/mcp list                 # see what's configured and what's on
/mcp enable github        # opt a server in
/reload                   # apply — github's tools appear next turn

/mcp-import — bring in existing servers

If you already use MCP in another tool, import its servers instead of writing mcp.json by hand. /mcp-import reads from:

  • Claude (Claude Code / Desktop)
  • Cursor
  • VS Code
  • IntelliJ (GitHub Copilot)

It merges the chosen servers into ~/.free-code/agent/mcp.json and extracts any env values it finds into ~/.free-code/agent/.env. Imported servers arrive disabled — enable the ones you want, then /reload.

Typical workflow

From zero to a working MCP server.

# 1. Add the server definition to ~/.free-code/agent/mcp.json
#    (or run /mcp-import to bring one in)

# 2. Put any token/API key in ~/.free-code/agent/.env
echo 'GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx' >> ~/.free-code/agent/.env

# 3. Enable it and reload
/mcp enable github
/reload

# 4. Confirm it's on
/mcp list