Skip to content

Commit cdb019c

Browse files
Clarify default MCP servers (#1546)
## Summary - Renamed MCP wrapper defaults from `houseServers` to `defaultServers`. - Kept the Exa HTTPS MCP endpoint in the default set even when the local `index` MCP server is unavailable. - Added an eval assertion for the no-index case. ## Validation - `nix run nixpkgs#nixfmt-rfc-style -- lib/util/mcp.nix packages/agent/mcp.nix packages/agent/codex/default.nix packages/agent/claude-code/default.nix tests/default.nix lib/default.nix` - `nix eval --raw --impure --expr 'let lib = (import <nixpkgs> {}).lib; mcp = import ./lib/util/mcp.nix { inherit lib; }; in (mcp.defaultServers {}).exa.url'` - `nix eval --json --impure --expr 'let lib = (import <nixpkgs> {}).lib; mcp = import ./lib/util/mcp.nix { inherit lib; }; in mcp.toCodexEntries (mcp.defaultServers {})'` - `nix eval --raw --impure --expr 'let flake = builtins.getFlake (toString ./.); tests = import ./tests { nixpkgs = flake.inputs.nixpkgs; ix = flake.lib; paths = flake.lib.paths; }; failures = builtins.filter (a: !a.assertion) tests.groups.mcp; in builtins.toJSON (map (a: a.message) failures)'` Fixes #1545 (sent by an AI agent via Codex) <!-- Macroscope's pull request summary starts here --> <!-- Macroscope will only edit the content between these invisible markers, and the markers themselves will not be visible in the GitHub rendered markdown. --> <!-- If you delete either of the start / end markers from your PR's description, Macroscope will append its summary at the bottom of the description. --> > [!NOTE] > ### Rename `houseServers` to `defaultServers` in MCP server configuration > Renames the `houseServers` attribute and function to `defaultServers` across the MCP configuration layer, including [mcp.nix](https://github.com/indexable-inc/index/pull/1546/files#diff-f70a76d7dd82c8fd07876567087fe2e2412453d6b2d8db0d3ba66c77ed1530b8), [lib/util/mcp.nix](https://github.com/indexable-inc/index/pull/1546/files#diff-30f208a31e39d4388eb8b510d8a6962b9cd1a5d7b074429d38190a855a620744), and the claude-code and codex agent packages. Also adds a test asserting that the Exa MCP server is included even when the index MCP server is unavailable. > > <!-- Macroscope's review summary starts here --> > > <sup><a href="https://app.macroscope.com">Macroscope</a> summarized 00a92f9.</sup> > <!-- Macroscope's review summary ends here --> > <!-- macroscope-ui-refresh --> <!-- Macroscope's pull request summary ends here -->
1 parent 97ba022 commit cdb019c

8 files changed

Lines changed: 27 additions & 16 deletions

File tree

doc/claude-code/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ wrapper injects its defaults file only `unless_present` a caller `--settings`
107107
Rendered from the shared `ix.mcp` registry (`lib/util/mcp.nix`) so `index` is
108108
declared once for both this wrapper and codex. CLI `--mcp-config` layers merge,
109109
so a user's `--mcp-config` and a project `.mcp.json` still load alongside.
110-
Defaults to the house pair, additions only:
110+
Defaults to the default pair, additions only:
111111

112112
- `index`: the ix notebook kernel (`ix-mcp serve`, `packages/mcp`) over stdio, present
113113
only when the `mcp` sibling is in scope (the flake package set, not the

doc/codex/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Defaults bump multi-agent fan-out well above stock:
5050

5151
### Baked MCP servers (`default.nix:62-73`, `80`)
5252

53-
The house MCP servers are added as soft `-c mcp_servers.*` defaults from the same
53+
The default MCP servers are added as soft `-c mcp_servers.*` defaults from the same
5454
`ix.mcp` registry the claude-code wrapper renders, so Codex gets only the
5555
`index` MCP server and the Exa MCP server. The `index` server is present only
5656
when the `mcp` sibling is in scope (the flake package set, not the overlay;

lib/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ let
241241
toml = import ./util/toml.nix { inherit lib; };
242242

243243
/**
244-
Single source of truth for the MCP servers baked into the house wrappers.
244+
Single source of truth for the MCP servers baked into the agent wrappers.
245245
Define a server once in a neutral shape and render it to each tool's native
246246
config with `mcp.toClaudeJson` (Claude Code's `mcpServers` JSON) and
247247
`mcp.toCodexEntries` (dotted `mcp_servers.*` codex `-c` flags), so `index`

lib/util/mcp.nix

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Single source of truth for the MCP servers the house wrappers bake in. Define
1+
# Single source of truth for the MCP servers the agent wrappers bake in. Define
22
# a server ONCE in the neutral shape below and render it to each tool's native
33
# config with `toClaudeJson` / `toCodexEntries`, so `index` (and any future
44
# shared server) is declared in one place instead of copied into the Claude Code
@@ -42,7 +42,7 @@ let
4242
# config-launch turns into `-c <key>=<value>` flags (so a user's own
4343
# `mcp_servers.<name>` in config.toml still wins per the per-leaf presence
4444
# check). Codex keys stdio servers by `command`/`args`/`env` and HTTP servers
45-
# by `url`, mirroring `[mcp_servers.<name>]` tables in config.toml. House MCP
45+
# by `url`, mirroring `[mcp_servers.<name>]` tables in config.toml. Default MCP
4646
# tools are trusted defaults, so approve server tools unless the user config
4747
# sets a stricter `default_tools_approval_mode` or per-tool override.
4848
codexEntriesOne =
@@ -84,7 +84,7 @@ let
8484
in
8585
{
8686
/**
87-
The house MCP server set, defined once for every wrapper that bakes it.
87+
The default MCP server set, defined once for every wrapper that bakes it.
8888
Returns the neutral definitions; each consumer renders them with
8989
`toClaudeJson` / `toCodexEntries`.
9090
@@ -93,7 +93,7 @@ in
9393
sibling is out of scope (e.g. the overlay package set), in which case only
9494
the keyless `exa` server is returned.
9595
*/
96-
houseServers =
96+
defaultServers =
9797
{
9898
indexCommand ? null,
9999
}:

packages/agent/claude-code/default.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
# layers MERGE: a user's own `--mcp-config` and a discovered project
106106
# `.mcp.json` still load alongside this set, so baking the flag here replaces
107107
# the old pattern of consumers symlinkJoin-wrapping this wrapper a second time
108-
# just to add it. Defaults to the house pair, additions only (no stock tool is
108+
# just to add it. Defaults to the default pair, additions only (no stock tool is
109109
# disabled or overridden):
110110
# - `index`: the ix notebook kernel (`ix-mcp serve`, packages/mcp) over
111111
# stdio. Present only when the `mcp` sibling is in scope, i.e. in the
@@ -119,7 +119,7 @@
119119
mcpServers ?
120120
ix.mcp.toClaudeJson
121121
(import (ix.paths.packagesRoot + "/agent/common.nix") { inherit lib ix repoPackages; })
122-
.houseServers,
122+
.defaultServers,
123123

124124
# Text used AS Claude Code's system prompt, REPLACING the stock prompt. The
125125
# string is materialized to a store file and baked into the wrapper as

packages/agent/codex/default.nix

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ let
8888
value = ix.toml.scalar v;
8989
}) flat;
9090

91-
# The house MCP servers, baked as soft `-c mcp_servers.*` defaults from the
92-
# shared house server set (../common.nix `houseServers`, the same source the
91+
# The default MCP servers, baked as soft `-c mcp_servers.*` defaults from the
92+
# shared default server set (../common.nix `defaultServers`, the same source the
9393
# claude-code wrapper renders), so Codex gets only the index MCP server and
9494
# the Exa MCP server. Soft, so a user's own `[mcp_servers.<name>]` in
9595
# config.toml wins per the per-leaf presence check.
96-
mcpServers = common.houseServers;
96+
mcpServers = common.defaultServers;
9797
sharedPermissions = import (ix.paths.packagesRoot + "/agent/policy/permissions.nix") {
9898
inherit lib mcpServers;
9999
};

packages/agent/mcp.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# House MCP server set shared by agent CLI wrappers.
1+
# Default MCP server set shared by agent CLI wrappers.
22
{
33
lib,
44
ix,
@@ -8,7 +8,7 @@
88
# Rendered from the shared `ix.mcp` registry with the kernel pointed at the
99
# `mcp` sibling when it is in scope. Each wrapper adapts this to its own
1010
# config shape (`ix.mcp.toClaudeJson` / `ix.mcp.toCodexEntries`).
11-
houseServers = ix.mcp.houseServers {
11+
defaultServers = ix.mcp.defaultServers {
1212
indexCommand = if repoPackages ? mcp then lib.getExe repoPackages.mcp else null;
1313
};
1414
}

tests/default.nix

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,14 @@ let
153153
baseFirewallTcpPorts = [ 5001 ];
154154
baseFirewallUdpPorts = [ 8443 ];
155155
sampleCodexMcpEntries = ix.mcp.toCodexEntries (
156-
ix.mcp.houseServers {
156+
ix.mcp.defaultServers {
157157
indexCommand = "/bin/ix-mcp";
158158
}
159159
);
160+
sampleCodexMcpEntriesWithoutIndex = ix.mcp.toCodexEntries (ix.mcp.defaultServers { });
160161
sampleCodexMcpEntry = key: lib.findFirst (entry: entry.key == key) null sampleCodexMcpEntries;
162+
sampleCodexMcpEntryWithoutIndex =
163+
key: lib.findFirst (entry: entry.key == key) null sampleCodexMcpEntriesWithoutIndex;
161164
agentCommon = import (paths.packagesRoot + "/agent/common.nix") { inherit lib ix repoPackages; };
162165
sampleClaudeSystemPrompt = agentCommon.systemPromptFor "claude";
163166
sampleCodexSystemPrompt = agentCommon.systemPromptFor "codex";
@@ -2460,7 +2463,7 @@ let
24602463
key = "mcp_servers.index.default_tools_approval_mode";
24612464
value = "\"approve\"";
24622465
};
2463-
message = "Codex MCP entries should approve trusted house server tools by default";
2466+
message = "Codex MCP entries should approve trusted default server tools by default";
24642467
}
24652468
{
24662469
assertion =
@@ -2470,6 +2473,14 @@ let
24702473
};
24712474
message = "Codex MCP entries should include the Exa MCP server";
24722475
}
2476+
{
2477+
assertion =
2478+
sampleCodexMcpEntryWithoutIndex "mcp_servers.exa.url" == {
2479+
key = "mcp_servers.exa.url";
2480+
value = "\"https://mcp.exa.ai/mcp\"";
2481+
};
2482+
message = "Codex MCP entries should include the Exa MCP server even when index MCP is unavailable";
2483+
}
24732484
{
24742485
assertion = lib.all (
24752486
entry: lib.hasPrefix "mcp_servers.index." entry.key || lib.hasPrefix "mcp_servers.exa." entry.key

0 commit comments

Comments
 (0)