Skip to content

feat: declare dynamically_loaded_tools for official models and add per-server MCP deferred disclosure - #3667

Merged
sailist merged 6 commits into
MoonshotAI:mainfrom
sailist:feat-176-09-09-official-models-dynamic-tools
Sep 14, 2026
Merged

sailist merged 6 commits into
MoonshotAI:mainfrom
sailist:feat-176-09-09-official-models-dynamic-tools

Conversation

@sailist

@sailist sailist commented Sep 9, 2026 •

Copy link
Copy Markdown
Collaborator

Related Issue

Internal feature work (no linked issue).

Problem

The official models endpoint advertises dynamic tool loading (supports_dynamic_tools), but the CLI never parsed or declared that capability, so the experimental select_tools on-demand loading path could never turn on for official models. Separately, every MCP server's tools always occupied the immutable top-level tools[] list — there was no way to keep a tool-heavy server's schemas out of the prompt unless the model loaded them on demand.

What changed

  • Capability wiring (oauth): parse supports_dynamic_tools from the official models endpoint and map it to the dynamically_loaded_tools model capability, so official models declare dynamic tool loading automatically.
  • Per-server MCP deferred disclosure (agent-core-v2): mcp.json server entries accept deferred (all transports, shared schema across config loading, configStore, management CRUD, and plugin manifests). With the experimental tool-select flag and a model declaring dynamically_loaded_tools, a server marked deferred: true keeps its tools out of the top-level list and the model loads them via select_tools. Servers default to inline disclosure — tools are always exposed unless deferred: true is set explicitly; the synthetic authenticate tool of a needs-auth server follows the same field.
  • Contract (klient): mirror the per-server deferred field in the MCP config contract used by session creation options.
  • Fix: register select_tools regardless of the profile tool allowlist (still vetoable via disallowedTools), aligning with toolPolicyService.isToolActiveForDisclosure.
  • Docs & changesets: MCP page gains a "Loading tools on demand" section (prerequisites, example, default behavior), capabilities gains dynamically_loaded_tools, and KIMI_CODE_EXPERIMENTAL_TOOL_SELECT is documented.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9a6a9e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@9a6a9e3
npx https://pkg.pr.new/@moonshot-ai/kimi-code@9a6a9e3

commit: 9a6a9e3

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 279e72ed39

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// catalogModelToCapability reads it; stripping it here would silently
// disable tool-select for catalog-imported aliases.
"dynamically_loaded_tools",
"dynamic_tools",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the models.dev capability field

The models.dev catalog schema and compatible mirrors expose this as dynamically_loaded_tools; replacing that wire key with the internal dynamic_tools name causes stripModel() to discard the capability from fetched catalogs. Consequently, catalog-imported models that previously advertised support are emitted without the bit and tool selection remains disabled; retain the wire key here and translate it while normalizing the catalog.

Useful? React with 👍 / 👎.

Comment on lines +497 to +499
dynamic_tools:
declared.has('dynamic_tools') ||
detected.dynamic_tools === true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Continue recognizing the existing config capability

For users whose existing config.toml model aliases declare dynamically_loaded_tools, this resolver now silently ignores that declaration, so enabling the tool-select flag no longer activates progressive disclosure after upgrading. Since this is being released as a patch rather than a confirmed major change, accept both spellings during resolution and normalize to dynamic_tools internally.

AGENTS.md reference: AGENTS.md:L64-L64

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e274157fc7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

});
const disposable = this._register(this.registry.register(tool, { source: 'mcp' }));
const disposable = this._register(
this.registry.register(tool, { source: 'mcp', disclosure: 'deferred' }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor deferred:false for MCP authentication tools

When a remote MCP server configured with deferred: false initially enters needs-auth while the tool-select gate is active, this branch still marks its synthetic authentication tool as deferred. AgentToolSelectService consequently hides that tool from the top-level tool list until it is selected dynamically, so the server's explicit inline-disclosure opt-out is not honored during authentication; propagate the server's configured disclosure setting here as the connected-server path does.

Useful? React with 👍 / 👎.

@sailist
sailist force-pushed the feat-176-09-09-official-models-dynamic-tools branch from f791d9a to 154056b Compare September 10, 2026 15:23
@sailist sailist changed the title feat(oauth): add the dynamic_tools capability from the official models endpoint feat: add dynamic tool loading for official models and per-server MCP deferred disclosure Sep 10, 2026
@sailist
sailist force-pushed the feat-176-09-09-official-models-dynamic-tools branch from 154056b to 9a6a9e3 Compare September 14, 2026 11:22
@sailist sailist changed the title feat: add dynamic tool loading for official models and per-server MCP deferred disclosure feat: declare dynamically_loaded_tools for official models and add per-server MCP deferred disclosure Sep 14, 2026
@sailist
sailist merged commit 9296e68 into MoonshotAI:main Sep 14, 2026
16 checks passed
bvisible pushed a commit to bvisible/hermes-agent that referenced this pull request Sep 25, 2026
…eeps a whole server eager

Port from MoonshotAI/kimi-code#3667: kimi-code lets one MCP server opt into
deferred disclosure while its siblings stay inline. Hermes defers every MCP
tool by default, so the useful granularity is the inverse: pin one small,
every-turn server into tools[] while tool-heavy servers keep deferring.

Builds on NousResearch#110714 (tools.tool_search.eager, per tool name): an eager entry may
now also name a toolset (`mcp-<server>`), and `mcp_servers.<name>.defer: false`
folds into that set at config load. Only an explicit boolean False pins.

Before: with tool search on, `mcp_servers.notes.defer: false` had no effect —
tools[] = bridge only. After: notes' tools stay visible next to the bridge;
the sibling server still defers (E2E on a temp HERMES_HOME).

(cherry picked from commit af654fb)
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.

1 participant