Skip to content
ƒtsforgev0.57.1
38

MCP servers

5 min read

tsforge can connect to external MCP (Model Context Protocol) servers and offer their tools to the agent during an interactive session. The classic use is Context7 for up-to-date library documentation, but any MCP server works, spawned locally over stdio or reached over HTTP.

MCP is opt-in: with no mcpServers block in your config, nothing connects and nothing changes.

Add an mcpServers block to tsforge.config.json at your repo root. An entry is either a stdio server tsforge spawns, or ("type": "http") a server it reaches at a URL. ${VAR} references are read from the environment at startup.

{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": { "CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}" }
}
}
}
FieldRequiredNotes
commandyes (stdio)Executable to spawn
argsnoArguments for command
envnoExtra env vars (merged over the parent env); ${VAR} interpolated
typenostdio (default) or http
urlyes (http)The server’s MCP endpoint, e.g. https://crm.example.com/mcp
headersno (http)Headers sent on every request, e.g. { "Authorization": "Bearer …" }; ${VAR} interpolated
timeoutMsnoPer-call timeout (default 30000)

An mcpServers block also works in the global model registry, ~/.tsforge/models.json — same shape, same fields. Servers defined there are available in every project, so a server you use everywhere (Linear, Sentry, Context7) only needs to be configured once. A project’s own tsforge.config.json mcpServers entry with the same name overrides the global one entirely; entries unique to either side apply together.

~/.tsforge/models.json
{
"active": "...",
"models": { "...": {} },
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.linear.app/sse"]
},
"sentry": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.sentry.dev/sse"]
}
}
}

On startup tsforge connects each server, lists its tools, and advertises them to the model under a namespaced name: mcp__<server>__<tool> (for example mcp__context7__get-library-docs). When the model calls one, tsforge routes it to that server and feeds the text result back into the conversation.

Built-in integrations (Linear, Notion, Sentry, Twenty)

Section titled “Built-in integrations (Linear, Notion, Sentry, Twenty)”

Some MCP servers get a curated treatment instead of raw passthrough. When you configure a server keyed linear, notion, sentry or twenty, tsforge offers a small set of purpose-built verbs (e.g. linear_read, notion_read, sentry_read) instead of that server’s dozens of raw tools — so the model’s tool list stays focused — and hides the raw mcp__<server>__* tools by default (re-expose them with the matching TSFORGE_<NAME>_RAW=1). These follow a capability = consent model: the server being connected is your consent, reads work in every mode, and writes are held back while planning or running unattended.

GitHub is first-class too, but via the git/gh binaries rather than MCP.

Chatwoot works the same way but over its REST API, since it has no MCP server.

Full guides: Git & GitHub · Linear · Notion · Sentry · Twenty CRM · Chatwoot.

A server that speaks Streamable HTTP and takes a token in a header connects directly with "type": "http". Self-hosted apps such as Twenty work this way:

{
"mcpServers": {
"twenty": {
"type": "http",
"url": "https://crm.example.com/mcp",
"headers": { "Authorization": "Bearer <your Twenty API key>" }
}
}
}

tsforge sends your headers on every request, keeps the session the server issues (and starts a fresh one if the server forgets it), accepts JSON or streamed replies, and reports a rejected key as HTTP 401 (unauthorized …) at startup.

Hosted servers that sign you in through a browser (OAuth), like Linear’s, Notion’s or Sentry’s, still go through mcp-remote, which handles the sign-in:

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

MCP fits tsforge’s deterministic, local-first design as an opt-in context source:

  • MCP tools never touch your editable scope and cannot satisfy or bypass the acceptance gate. They add context, they don’t certify “done”.
  • Because they don’t write the workspace, they remain available in plan mode (e.g. look up docs while planning).
  • A stdio server’s own logging (its stderr, e.g. mcp-remote’s [Local→Remote] tools/call lines) never reaches your terminal. It goes to the debug trace (TSFORGE_TRACE), and if the server dies, its last lines appear in the error message.
  • A server that fails to connect, crashes, or times out is reported and skipped. It can never block a session from starting or wedge the loop. A failed tool call comes back as an error string the model can react to.
  • The http transport takes a token in a header. It does not run a browser sign-in (OAuth); use mcp-remote for servers that need one.
  • MCP tools are offered in the interactive CLI; the headless eval path does not load them.
  • Connected servers are child processes; they exit with the tsforge process.

→ Interactive CLI · tsforge.config.json