Skip to content

feat: add MCP config adapter for Hermes Agent#106

Open
latekvo wants to merge 3 commits intomainfrom
ignacylatka/add-mcp-config-adapter-for-hermes
Open

feat: add MCP config adapter for Hermes Agent#106
latekvo wants to merge 3 commits intomainfrom
ignacylatka/add-mcp-config-adapter-for-hermes

Conversation

@latekvo
Copy link
Copy Markdown
Member

@latekvo latekvo commented Apr 9, 2026

Summary

  • Add hermesAdapter to packages/mcp/src/cli/mcp-configs.ts supporting Hermes (Nous Research AI coding agent CLI) with YAML-based config format (mcp_servers key)
  • Add readYaml/writeYaml helpers to packages/mcp/src/cli/utils.ts using the yaml package
  • Add full test coverage for write, remove, preserve-other-servers, path resolution, and edge cases
Screen.Recording.2026-04-17.at.17.37.58.mov

Screen.Recording.2026-04-17.at.17.43.02.mov

Before this PR, adapters with only one config path (only local or only global) without were installing regardless of user's scope selection. This PR makes this fact more visible, allowing the user to disable the undesired installation targets.

Would appreciate a UI opinion, i went with A because B was scary in my opinion, but something in between could also work:

A B
image image

Test plan

  • All 69 tests pass in mcp-configs.test.ts (7 new Hermes tests + updated adapter count test)
  • TypeScript compiles with tsc --noEmit

@latekvo latekvo changed the title feat: add MCP config adapter for Hermes feat: add MCP config adapter for Hermes Agent Apr 9, 2026
@latekvo latekvo marked this pull request as draft April 9, 2026 16:15
@latekvo latekvo marked this pull request as draft April 9, 2026 16:15
@latekvo latekvo marked this pull request as ready for review April 9, 2026 16:17
@latekvo latekvo marked this pull request as draft April 9, 2026 16:17
Comment thread packages/mcp/src/cli/init.ts Outdated
@latekvo

This comment was marked as outdated.

@latekvo latekvo force-pushed the ignacylatka/add-mcp-config-adapter-for-hermes branch 2 times, most recently from 8d99376 to f8e8220 Compare April 17, 2026 11:51
Add hermesAdapter to the MCP config registry so `argent init` can write
the mcp_servers.argent entry into ~/.hermes/config.yaml.

- Uses the yaml Document API (parseDocument/setIn/toString) to preserve
  user comments and formatting on round-trip.
- remove() cleans up by deleting the argent key from mcp_servers, or the
  entire mcp_servers block when argent is the only entry.
- readYamlDocument throws on malformed YAML instead of silently
  clobbering; writeYamlDocument uses lineWidth: 0 to avoid re-wrapping
  long user strings.
- Adds symmetric local→global fallback in the init write loop so
  global-only adapters (Hermes, Windsurf) are not silently skipped when
  the user picks scope=local.
@latekvo latekvo force-pushed the ignacylatka/add-mcp-config-adapter-for-hermes branch from f8e8220 to 8a62796 Compare April 17, 2026 12:21
Comment on lines +313 to +322
} else if (scope !== "global" && adapter.globalPath()) {
const fallback = adapter.globalPath()!;
try {
adapter.write(fallback, mcpEntry);
mcpResults.push(
`${pc.green("+")} ${adapter.name} ${pc.dim(`(global fallback: ${fallback})`)}`
);
} catch (err) {
mcpResults.push(`${pc.red("x")} ${adapter.name}: ${pc.dim(String(err))}`);
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This if-else already handled global->local fallback.
This PR only adds the third local->global fallback case handling.

User is notified about this fallback mechanism at the agent selection stage - that's also where they can choose to disable integration with a specific agent.

latekvo added 2 commits April 17, 2026 16:24
readYaml (POJO round-trip) was added to utils.ts but never called — the
hermes adapter uses the Document-returning helpers exclusively. Drop it
and rename readYamlDocument/writeYamlDocument to readYaml/writeYaml so
the naming matches the readJson/readToml pairs; with only one flavor
left, the Document suffix no longer disambiguates anything.
For adapters like Hermes and Windsurf that only expose a global config
path (or conversely, only a project path), the multiselect menu now
shows an italic cyan note next to the adapter name so users understand
up front which scope the entry will land in, instead of discovering it
after selection.
@latekvo latekvo marked this pull request as ready for review April 17, 2026 15:49

This comment was marked as low quality.

Comment on lines +209 to +224
const choices = ALL_ADAPTERS.map((a) => {
const parts: string[] = [];
if (detectedNames.includes(a.name)) parts.push("detected");
const hasProject = a.projectPath(process.cwd()) != null;
const hasGlobal = a.globalPath() != null;
if (!hasProject && hasGlobal) {
parts.push(pc.italic(pc.cyan(`ⓘ will be installed into ${a.name}'s global config`)));
} else if (hasProject && !hasGlobal) {
parts.push(pc.italic(pc.cyan(`ⓘ will be installed into ${a.name}'s project config`)));
}
return {
value: a,
label: a.name,
hint: parts.length > 0 ? parts.join(", ") : undefined,
};
});
Copy link
Copy Markdown
Member Author

@latekvo latekvo Apr 17, 2026

Choose a reason for hiding this comment

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

This fragment adds the blue info text:

Image

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.

2 participants