BharatCode

Integrations

MCP Integration

BharatCode is a Model Context Protocol (MCP) client. Point it at one or more MCP servers and their tools are bridged into the agent alongside the built-ins — over a local stdio process or a remote http / sse endpoint. Each server is just another entry in your config.

What is MCP?

The Model Context Protocol (MCP) is an open standard for connecting AI agents to external tools and data sources. A program that exposes capabilities — reading files, searching a database, calling an API — implements an MCP server. An agent that consumes those capabilities is an MCP client.

BharatCode is an MCP client. Once a server is configured, the tools it advertises become available to the model in the same way as the built-in tools — the agent can call them, you approve them through the same permission system, and their results flow back into the conversation. You write no glue code: any compliant MCP server works out of the box.

Transports

BharatCode supports three MCP transports. Which one you use depends on whether the server runs locally as a child process or remotely behind a URL:

  • stdio — BharatCode launches the server as a local child process and communicates over its standard input and output. This is the most common setup for tools that run on your own machine.
  • http — BharatCode connects to a remote server over HTTP at a given url. No process is spawned; the server is hosted elsewhere.
  • sse — a remote transport using Server-Sent Events, also addressed by a url. Use this when the server you are connecting to exposes an SSE endpoint.

Configuring MCP servers

MCP servers live under an mcp block in your config, inside a servers map. The map key is the name you choose for the server — keep it short and lowercase, because it becomes the prefix on every bridged tool (see below). Like the rest of BharatCode, this can sit in your global ~/.config/bharatcode/config.json or a per-project ./.bharatcode.json; see Configuration for how the two files merge.

Local (stdio) servers

A stdio server is described by the executable to run. The fields are command (the program), args (its arguments), and an optional env map of environment variables passed to the child process:

./.bharatcode.jsonjson
{  "mcp": {    "servers": {      "filesystem": {        "type": "stdio",        "command": "npx",        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]      }    }  }}

Here BharatCode runs the official MCP filesystem server with npx, scoping it to a single directory passed as the last argument. The server starts when BharatCode starts and is shut down when your session ends.

Remote (HTTP / SSE) servers

A remote server is described by its type (http or sse) and a url. No command or args are needed because BharatCode does not launch the process — it simply connects:

~/.config/bharatcode/config.jsonjson
{  "mcp": {    "servers": {      "docs": {        "type": "http",        "url": "https://mcp.example.com/mcp"      },      "events": {        "type": "sse",        "url": "https://mcp.example.com/sse"      }    }  }}

All server fields

Putting it together, here is an annotated entry showing every field. As with the rest of BharatCode's config, strict JSON has no comments — strip the // notes before saving:

~/.config/bharatcode/config.json (annotated)jsonc
{  "mcp": {    "servers": {      // A local (stdio) server: BharatCode launches the process and      // talks to it over stdin/stdout. Use for tools that run on your box.      "filesystem": {        "type": "stdio",                 // stdio | http | sse        "command": "npx",                // the executable to launch        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"],        "env": {                         // extra env vars for the child process          "LOG_LEVEL": "info"        },        "permission": "ask"              // ask | allow | deny — applies to this server's tools      },       // A remote server reached over HTTP. No process is spawned;      // BharatCode connects to the URL. Use "sse" for Server-Sent Events.      "company-tools": {        "type": "http",        "url": "https://mcp.example.com/mcp"      }    }  }}
  • type — the transport: stdio, http, or sse.
  • command — for stdio servers, the executable BharatCode launches.
  • args — for stdio servers, the list of arguments passed to command.
  • env — for stdio servers, additional environment variables to set on the child process. The child also inherits BharatCode's own environment, so secrets like API tokens are best exported in your shell rather than written here.
  • url — for http and sse servers, the endpoint to connect to.
  • permission — an optional per-server permission verb (ask, allow, or deny) applied to every tool the server bridges. See per-server permission below.

Keep secrets in the environment

For tokens and keys, prefer your shell environment over hardcoded values. A stdio server is a child process that BharatCode launches, so it inherits BharatCode's environment — export the variable the server expects (for example a GITHUB_PERSONAL_ACCESS_TOKEN for the GitHub server) and it is picked up automatically. The optional env map is for setting additional, non-secret variables on the child. This mirrors how providers read keys from api_key_env, so you can commit a config file without leaking credentials.

How bridged tools appear to the agent

When a server connects, BharatCode reads the list of tools it advertises and bridges each one into the agent's toolset. To avoid collisions between servers — and with the built-ins — bridged tool names are server-prefixed: the server's name from your servers map is prepended to each tool.

So a github server that advertises a create_issue tool surfaces to the model as github_create_issue; a filesystem server's read_file becomes filesystem_read_file. The prefix is the same name you chose as the map key, which is why a short, lowercase server name reads best. These bridged tools sit alongside built-ins like view, edit, and bash — the model picks whichever fits the task.

Names are illustrative

The exact tool names depend on what each MCP server advertises; the examples above show the shape of a bridged name (<server>_<tool>), not a fixed list. Run a session and the model will see whatever tools your configured servers expose, each carrying its server prefix.

Per-server permission

Bridged tools are not exempt from BharatCode's safety model. Because each one has a server-prefixed name, it flows through the same permission system as everything else: the active mode (read-only, auto, or full) and per-action verbs (ask, allow, deny) all apply. When BharatCode asks, you can remember the answer for a scope — once, session, project, or forever.

To set a default for an entire server, add a permission verb to its entry. This applies to every tool the server bridges, which is handy when a server is trustworthy enough to auto-allow, or sensitive enough to always confirm:

per-server permissionjson
{  "mcp": {    "servers": {      "filesystem": {        "type": "stdio",        "command": "npx",        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"],        "permission": "allow"      },      "github": {        "type": "stdio",        "command": "npx",        "args": ["-y", "@modelcontextprotocol/server-github"],        "permission": "ask"      }    }  }}

Here the read-mostly filesystem server is auto-allowed, while the GitHub server — which can open issues and push changes — always asks first.

Worked example: the GitHub MCP server

Let's wire up the official GitHub MCP server end to end. First, export your token in the shell — using the exact variable name the server reads — so the secret never lands in a config file. Because BharatCode launches the server as a child process, it inherits this variable automatically:

export a GitHub tokenbash
export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_your_personal_access_token"

Then add the server to your config. It runs over stdio via npx; no token appears here, because the server reads it from the inherited environment:

~/.config/bharatcode/config.jsonjson
{  "mcp": {    "servers": {      "github": {        "type": "stdio",        "command": "npx",        "args": ["-y", "@modelcontextprotocol/server-github"],        "permission": "ask"      }    }  }}

Start BharatCode as usual. On launch it spawns the GitHub server, reads the tools it advertises, and bridges them under the github_ prefix. Now you can ask the agent to use them in plain language:

use a bridged toolbash
bharatcode run "Open a GitHub issue titled 'Flaky CI on main' summarizing the last three failed runs"

Because the server entry carries "permission": "ask", BharatCode pauses for your approval before any github_* tool runs — so the model can propose the action, but nothing is created on your account until you say yes.

Next up

MCP brings external tools in; the next integration brings your editor's language intelligence in. See LSP for in-context diagnostics, or Hooks to run your own shell commands around tool calls.