Docs
Jan Agent
MCP

MCP

Model Context Protocol servers extend the agent with tools it doesn't have built in - a private wiki, a database, a browser that holds a login, an internal API.

Jan Agent reads the same mcp_config.json as Jan Desktop, so servers you configured in the app are available in the terminal with nothing further to do. For what MCP is and how to add servers, see Model Context Protocol.

At startup

Active servers connect in the background while the console opens, and announce themselves:


MCP ready: sequential-thinking, serper

A server that fails to come up says so in the transcript, with the reason:


MCP: failed to connect to 'fetch': connection closed: initialize response

The first turn waits for the connecting servers, so the model sees the full toolset rather than a half-connected one. A slow stdio server delays that first turn, not the whole session.

Managing servers

In the console


/mcp

Lists every configured server with its state. Space toggles the highlighted one; turning one on connects it in the background and the tools appear once it lands. Enter opens the server's detail screen (see below).

While the list is open you can also manage it:

  • a opens an add form (name, transport, then the transport-specific fields)
  • e edits the highlighted server, prefilled
  • d removes the highlighted server after writing it out

The list opens even with nothing configured, so a is reachable on a fresh install.

Inside the form, arrow keys (or Tab) move between fields. k and j type as ordinary characters - URLs, paths, and header values contain them - so they no longer steer between fields as they did in earlier releases.

A newly added server defaults to inactive, so it is persisted but not connected until you toggle it on.

The change is written back to mcp_config.json, so it persists - and applies to Jan Desktop too.

The server detail screen

Enter on a row opens that server on its own screen: transport, endpoint or command, the mcp_config.json path it came from, connection state, authentication state, the tool count, and the name and version the server reported when it connected. Everything there is read from local state, so it opens immediately; only the tool listing is a round trip and it fills in when it lands.

The actions below the info block are filtered to what the server can actually do - no sign-in rows for a stdio server, no View tools while it is disconnected, no Reconnect while it is disabled:

  • View tools prints the tool names into the conversation, where they scroll and persist
  • Authenticate / Re-authenticate runs the OAuth flow (see below)
  • Clear authentication forgets the stored tokens and drops the connection, which still holds the old one. The server stays enabled, so signing back in brings it up again
  • Reconnect, Enable / Disable, Edit configuration, Remove server

Esc steps back to the list rather than out of /mcp.

Signing in to a remote server

Remote (http / sse) servers that require OAuth are handled for you: Jan discovers the provider's metadata, registers itself dynamically, and runs the authorization-code flow with PKCE against a loopback redirect. Authenticate prints the consent URL into the conversation before it starts waiting, and opens it in your browser - so a remote or headless session can still finish the sign-in by opening the URL by hand. The wait times out after five minutes.

A server that fails to connect purely for want of a sign-in says so, rather than reporting a transport error: Jan asks the server whether it advertises OAuth instead of guessing from the failure.

Tokens are written to mcp_oauth.json, next to mcp_config.json in the Jan data folder, with 0600 permissions:

  • not in mcp_config.json, which is hand-edited, copied between machines and shared with Jan Desktop; bearer tokens have no business travelling with it
  • Access tokens are refreshed automatically, a minute before they expire, when the provider issued a refresh token
  • Changing a server's url invalidates its stored tokens rather than silently sending credentials issued for a different resource
  • Removing a server clears its tokens too, so a later server reusing the name does not inherit the authorization

If you set an Authorization header by hand, that wins: OAuth is never attempted and never reported as missing, because wrapping it would put two credentials on one request.

From the command line

Add, list, edit, remove, and toggle servers headlessly with jan cli mcp ... - jan cli mcp add files --command npx --arg -y --arg my-mcp, jan cli mcp list, jan cli mcp remove files. See the CLI reference.

Tool policy

MCP tools follow the project's [tools] policy:

defaultEffect on MCP tools
read-onlyAvailable. The default
denyLocked down, except anything in allow
allowAvailable, except anything in deny

[tools]
default = "deny"
allow = ["sequential-thinking"]

That exposes one server's tools and nothing else - useful for a project where you want reasoning help but no outside network access.

Choosing a model

Not every model is good at tool calling, and some can't do it at all. If MCP tools are connected but never used, try a different model before debugging the server - /model switches without leaving the session.