Skip to content

feat(mcp): configurable server name and instructions - #512

Merged
arabold merged 5 commits into
arabold:mainfrom
RealFarway:feat/511-configurable-server-info
Oct 11, 2026
Merged

arabold merged 5 commits into
arabold:mainfrom
RealFarway:feat/511-configurable-server-info

Conversation

@RealFarway

Copy link
Copy Markdown
Contributor

Closes #511

Summary

The MCP server identity was hardcoded as docs-mcp-server with a stale 0.1.0 version, and no instructions were sent during initialization. This adds three settings to the server config section, each settable via config file, environment variable, or CLI flag on the default and mcp commands:

Setting Env var CLI flag Default
server.name DOCS_MCP_SERVER_NAME --server-name docs-mcp-server
server.instructions DOCS_MCP_SERVER_INSTRUCTIONS --server-instructions none
server.instructionsFile DOCS_MCP_SERVER_INSTRUCTIONS_FILE --server-instructions-file none
  • instructions is sent as the MCP instructions field on initialize. When unset, the field is omitted as before.
  • instructionsFile is read once per server instance as UTF-8. An unreadable file fails startup with a clear error rather than silently sending nothing. The inline value takes precedence over the file.
  • Blank values (empty env var, --flag "") are treated as absent, matching how publicOrigin behaves.
  • The reported version now comes from the build-time __APP_VERSION__ instead of the hardcoded 0.1.0.

Out of scope

The CLI script name and the envPaths data directory still use the literal docs-mcp-server, so existing installs and databases are unaffected.

Tests

  • src/mcp/mcpServer.test.ts: connects a real client over InMemoryTransport and asserts the name, version, inline instructions, file instructions, inline-over-file precedence, missing-file error, and the no-instructions case.
  • src/utils/config.test.ts: default, env, CLI precedence, and blank-value handling for the three settings.
  • src/cli/commands/{mcp,default}.test.ts: the three flags parse under a strict parser and reach loadConfig.
  • test/mcp-stdio-e2e.test.ts: spawns the server with the env vars set and asserts the initialize result.

npm run lint, npm run typecheck, and npm test pass locally (Node 22).

The MCP server identity was hardcoded as `docs-mcp-server` with a stale
`0.1.0` version, and no `instructions` were sent during initialization.
Users running several instances could not tell them apart, and had no
way to tell the model what a given server indexes or how to use it.

Add three settings to the `server` config section, each settable via
config file, environment variable, or CLI flag:

- `server.name` (`DOCS_MCP_SERVER_NAME`, `--server-name`) — reported in
  `serverInfo`; defaults to `docs-mcp-server`.
- `server.instructions` (`DOCS_MCP_SERVER_INSTRUCTIONS`,
  `--server-instructions`) — sent as the `instructions` field.
- `server.instructionsFile` (`DOCS_MCP_SERVER_INSTRUCTIONS_FILE`,
  `--server-instructions-file`) — read at startup as the instructions
  text; an unreadable file fails startup. Ignored when the inline value
  is set.

Blank values are treated as absent so an empty env var falls back to the
default or the file. The reported version now comes from the build-time
package version instead of the hardcoded string.

The CLI script name and the `envPaths` data directory still use the
literal `docs-mcp-server`, so existing installs are unaffected.

Closes arabold#511

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 22, 2026 22:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@arabold arabold left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this pull request. The feature is useful, and it fits well into the existing server configuration section. The tests are good. I ran them locally with Node 22, and they pass.

Two things must change before we can merge. See the inline comments for details:

  1. The priority between instructions and instructionsFile does not follow our configuration rules.
  2. The instructions file is read on every HTTP request, not once at startup.

One more thing: we describe expected behavior in openspec/specs/. New configuration settings are listed in openspec/specs/configuration/spec.md (see "Server Public Origin Configuration" as an example). The contributor guide does not mention this yet, so this is not a problem with your work. I can add this update myself, or you can add it to this pull request if you want to.

Comment thread src/mcp/mcpServer.ts Outdated
* @throws {Error} If the configured instructions file cannot be read.
*/
export function resolveServerInstructions(config: AppConfig): string | undefined {
if (config.server.instructions !== undefined) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline value always wins over the file. It does not matter where each value comes from. This breaks our priority order:

command line flag > environment variable > configuration file

Example:

  • config.yaml contains server.instructions: "A"
  • The user starts the server with --server-instructions-file b.md
  • Result: the server sends "A". The command line flag is ignored, and the user sees no message.

Suggestion: stop at startup with a clear error when both instructions and instructionsFile are set. This is simple, and it matches how you already handle a file that cannot be read.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the suggestion in the latest commits, now it should follow correctly the priority order and the mutually exclusive suggestion.

Comment thread src/mcp/mcpServer.ts Outdated
tools: {},
resources: {},
},
instructions: resolveServerInstructions(config),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createMcpServerInstance() is called more than once. In HTTP mode, it is called for every new session on /sse and for every request on /mcp (see src/services/mcpService.ts). So the file is read from disk on every request.

Problems:

  • If the file is deleted while the server runs, every request fails with HTTP status 500.
  • If the file is changed, the new text is used right away. The documentation says the file is read once at startup.

Suggestion: read the file once when the server starts (in registerMcpService() and in startStdioServer()). Then pass the text to createMcpServerInstance() as a parameter.

Comment thread src/mcp/mcpServer.ts Outdated
{
name: "docs-mcp-server",
version: "0.1.0",
name: config.server.name,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question, not a blocker: the MCP specification has a separate title field for a display name that people read. name is meant as a technical identifier. Your goal is to tell instances apart in the client, so title may be the better field. The MCP library we use (@modelcontextprotocol/sdk) already supports title.

What do you think about setting title as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's perfectly fine, relevant change to keep together with this PR, I will add title as well!

Comment thread docs/setup/configuration.md Outdated
|:-------|:--------|:------------|
| `name` | `docs-mcp-server` | Server name reported to MCP clients during initialization. Set this to tell instances apart when running more than one. |
| `instructions` | - | Instructions text sent to MCP clients during initialization. Clients inject it into the model's context, so use it to describe what this server indexes and how to use it. |
| `instructionsFile` | - | Path to a file whose contents are used as `instructions`. Read once at startup; a missing or unreadable file fails startup. Ignored when `instructions` is set. |

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two notes:

  • "Read once at startup" is not true in HTTP mode right now. See my comment in src/mcp/mcpServer.ts.
  • A relative path is resolved from the current working directory. When a desktop app starts the server with stdio, this directory is often unknown. Please add a note that the path should be absolute.

Comment thread src/mcp/mcpServer.test.ts Outdated
@@ -2,20 +2,27 @@
* Tests for MCP server read-only mode functionality

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small thing: this file now also tests the server name and the instructions. Please update this comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(mcp): configurable server name and instructions

3 participants