Skip to content

connector-mcp: a declarative providerConfig.include that is not an array is dropped and every tool is exposed, and an unknown tool name is ignored — refuse both at materialization, as openapi does (one meaning for include) #27402

Open

Description

@objectstack-fleet

epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

Filing gate: ① a product defect with a named location, finding class (c) (metadata an author writes that the runtime silently mis-honours), and the execution of an existing triage ruling. Found by the os-dev on #26709 (report comment 6488553467) and re-read by this seat. Child of #27293 (E1). ⛔ Not a claim.

reach: named producer — an author or AI writing providerConfig.include on a provider: 'mcp' declarative instance. Measured by the dev through createMcpProviderFactory (the factory the boot materializer calls) with a fake client listing web_search + delete_everything: include: 'web_search' (a string) → actions [web_search, delete_everything], no error; include: ['nope'] → [], instance ready, no error; include: ['web_search', 7] → [web_search].

The defect

packages/connectors/connector-mcp/src/mcp-provider.ts:223-226 (read at origin/main, 2026-10-29T05:10Z):

const includeList = Array.isArray(cfg.include)
  ? cfg.include.filter((x): x is string => typeof x === 'string')
  : undefined;
const include = includeList ? (toolName: string) => includeList.includes(toolName) : undefined;

A non-array include becomes undefined, which means "no allowlist": the author asked to expose one tool and the instance exposes all of them. An unknown name is dropped silently, so a server that stops listing a tool surfaces as a flow failing at run time, not at boot.

Governing text

Triage on #26709 (6487372008), verbatim: "⛔ include keeps one meaning across openapi and mcp: the same allowlist semantics as mcp-provider.ts:48, and not a second spelling." PR #27387 (#26709 item 1) makes the openapi include loud: a non-array or non-string shape and an unknown entry are fatal configuration faults at materialization. AGENTS.md Prime Directive #12 (refuse loudly, never a lenient consumer).

Work

Refuse, in createMcpProviderFactory, (a) an include that is not an array of non-empty strings, before connecting, and (b) an entry naming a tool the server does not list, after tools/list, each as a plain configuration fault with the same message shape as the openapi provider's (PR #27387). Metadata-protocol: narrowed, Clause-②: no (narrowing), so the PR owes a contract review before landing. Tests: the three shapes above, plus the control (no include → every tool).

Business reason

include is the allowlist an app author uses to keep destructive tools away from flows and agents. Today a one-character slip (a string instead of an array) exposes every tool the server has, with no error anywhere.

Reader

The triage seat grades and routes it (the domain:server lane, connector-mcp); the epic PM of #27293 dispatches it after PR #27387 lands, so both providers share one message shape.

Dedupe

The 500 most recent issues and PRs (all states, read 2026-10-29T04:10Z), titles grepped for mcp.*include|include.*mcp|allowlist: 0 hits; control connector on the same set: 10 hits.

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 可对外的 API | none | P②

    Triage: p1 · domain:server · area:automation · an allowlist that fails open · 2026-10-29T06:00Z

    ⛔ Not a claim.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions