MCP servers

Connect Model Context Protocol servers over stdio or HTTP to give the agent new tools and resources.

The Model Context Protocol (MCP) is an open standard for connecting agents to tools and data: issue trackers, databases, browsers, design tools, internal APIs. Nib is an MCP client. Any server that works with another MCP client works with Nib.

Configuration files

ScopeFileUse it for
Project.nib/mcp.json, or .mcp.json at the repository rootServers the whole team uses. Commit the file
User~/.nib/mcp.json, or mcpServers in ~/.claude.jsonServers you want in every project
Localprojects["<path>"].mcpServers in the user file above (where nib mcp add writes), then in ~/.claude.jsonPersonal servers for one project
SettingsmcpServers in your user settings, managed settings or --settingsServers defined alongside other settings. A project's own settings files can't define servers: put them in .mcp.json, where each asks for approval
Managedmanaged-mcp.json in the managed settings directoryOrganization policy. When present, it has exclusive control

All files share one format:

.nib/mcp.json
{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
    },
    "postgres": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "${DATABASE_URL}"]
    }
  }
}

When two scopes define a server with the same name, the higher scope's whole entry wins; fields are not merged. From highest to lowest: managed, command line, local, project, user, settings, servers declared by subagents and plugins, then servers imported from another coding agent (each waits for your approval). Within a scope, .nib/ files win over .mcp.json and ~/.claude.json.

Transports

stdio

Nib starts the server as a child process and talks to it over stdin and stdout.

FieldMeaning
type"stdio" (the default when command is set)
commandThe executable
argsArguments
envExtra environment variables
cwdWorking directory
timeoutTool call timeout in milliseconds (default 10 minutes, restarted by progress). Starting the server has its own 30-second limit
restart"on-failure" restarts the server after it exits unexpectedly. After 5 crashes within a minute Nib stops restarting it and shows the error. Default "never"

HTTP

Nib connects to a remote server using the streamable HTTP transport, and falls back to the older SSE transport for servers that only support that.

FieldMeaning
type"http" (or "sse" for SSE-only servers)
urlThe server endpoint
headersRequest headers, for example an Authorization header
headersHelperA command whose output supplies headers, for tokens that expire
timeoutTool call timeout in milliseconds (default 10 minutes, restarted by progress). Connecting has its own 30-second limit
oauthSign-in settings: clientId and clientSecret for a client registered with the server in advance, scopes (a list or a space-separated string) to request instead of the server's own, and callbackPort for a fixed local callback port. See Signing in

Common fields

FieldMeaning
alwaysLoadLoad this server's tools up front instead of deferring them
samplingtrue lets the server ask Nib for a model answer. See Requests from servers

Variables

${VAR} in any string is replaced with the environment variable VAR when the server starts. ${VAR:-default} uses default when VAR is unset or empty. A variable that is unset and has no default stays as written, and Nib reports it. ${NIB_PROJECT_DIR} and ${CLAUDE_PROJECT_DIR} are set to the project root. Keep secrets in your environment, not in committed files.

In a remote server's url, headers and oauth credentials, credential variables never expand: model provider keys, ANTHROPIC_AUTH_TOKEN, AWS credentials, NPM_TOKEN, HTTP_PROXY and HTTPS_PROXY, and Nib's own API key become empty, and their defaults are ignored. A server's own token, such as ${GITHUB_TOKEN} in its headers, expands as usual.

Expanded values, including any secrets, are never shown to the model.

Approving project servers

A project's .mcp.json comes from whoever wrote the repository. Before Nib connects to a server defined there, you approve it. The approval is tied to a hash of the exact entry, so if someone changes the command or URL later, Nib asks again.

You can pre-approve in settings:

SettingEffect
enabledMcpjsonServers: ["github"]Approve these project servers
disabledMcpjsonServers: ["postgres"]Reject these
enableAllProjectMcpServers: trueApprove every server in the project's file

These count only in your user or managed settings: a project's own settings can't approve its servers, trusted or not.

Signing in

Remote servers that use OAuth need you to sign in once. When a server says it needs sign-in, Nib shows it as waiting for sign-in instead of failing quietly. Sign in with:

  • Sign in next to the server in Customize, in the app;
  • /mcp login <server> in a CLI session;
  • nib mcp login <server> in a terminal. It opens the sign-in page in your browser; with --no-browser it prints the link instead.

Unless you set oauth.clientId, Nib identifies itself to the server. Where the server accepts client ID metadata documents, Nib uses the one it publishes. Otherwise it registers with the server as a client. The sign-in is kept on this computer, and every session uses it. nib mcp logout <server> forgets it.

Tools and resources

Each server tool becomes a Nib tool named mcp__<server>__<tool>. The input schema is the server's own JSON Schema.

MCP tools are deferred by default: the model sees their names and loads the definitions with ToolSearch when it needs one. This keeps a server with fifty tools from filling the context on every turn. Set alwaysLoad: true on a server whose tools the agent needs constantly.

Two built-in tools give access to server resources: ListMcpResourcesTool and ReadMcpResourceTool.

Requests from servers

A server can ask the client for things during a call:

  • Sampling, a model answer, only for servers with sampling: true. The session's small model answers, with text only or one structured answer.
  • Elicitation, a short form for you to fill in. Nib shows you the form, and the server gets your answer, or nothing if you decline. Requests to open a link are declined.

Permissions

MCP tools go through the permission engine like any other tool.

{
  "permissions": {
    "allow": ["mcp__github__get_issue", "mcp__github__list_pull_requests"],
    "ask": ["mcp__github__create_issue", "mcp__github__merge_pull_request"],
    "deny": ["mcp__postgres__execute"]
  }
}

An ask rule is decided before an allow rule, so "ask": ["mcp__github__*"] would make the allow rules above never apply. Ask for the specific tools you want to confirm instead.

RuleMatches
mcp__githubEvery tool on the github server
mcp__github__*The same, written as a wildcard
mcp__github__create_issueOne tool

Per-agent servers

A subagent can list servers in its frontmatter, either by name or as an inline definition. Inline servers are available only to that agent. See Agents.

Troubleshooting

  • The server doesn't appear. Check that it's approved (project servers) and that the command runs on its own in a terminal.
  • Tools are missing. They're deferred. Ask the agent to use the tool by name, or set alwaysLoad.
  • Variables come through empty. ${VAR} reads from the daemon's environment. An app started from the Dock or Start menu may not see variables exported in your shell profile. Check with the CLI started from a terminal, which does.

On this page