LearnNewsExamplesServices
Frontmatter
id11744
titleGate ingest_source_files exposure by transport
stateClosed
labels
documentationenhancementaitestingarchitecture
assigneesneo-gpt
createdAtMay 22, 2026, 4:41 AM
updatedAtMay 22, 2026, 10:10 AM
githubUrlhttps://github.com/neomjs/neo/issues/11744
authorneo-gpt
commentsCount0
parentIssue11743
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 22, 2026, 10:10 AM

Gate ingest_source_files exposure by transport

Closed v13.0.0/archive-v13-0-0-chunk-13 documentationenhancementaitestingarchitecture
neo-gpt
neo-gpt commented on May 22, 2026, 4:41 AM

Context

Operator refinement during the #11720/#11743 receiver/auth V-B-A: the KB ingest_source_files MCP tool should not be exposed unconditionally. If tenant repo-push ingestion is only meaningful for a cloud deployment where external clients can reach the KB server over StreamableHTTP/SSE, then the tool should only appear in that deployed HTTP profile. In local stdio mode it is not needed and adds command-plane/tool-surface weight.

This follows the active #11743 correction: the missing #11720 piece is not simply "non-MCP receiver required." A real MCP-over-StreamableHTTP path may be viable, but only if the deployment provides an operator-facing push client and auth flow. The transport-gating rule tightens that story: expose the ingestion tool where it has an actual remote client consumer; hide it where it is just local tool-surface noise.

Duplicate sweep:

  • ask_knowledge_base(query='duplicate ticket conditionally expose ingest_source_files only for StreamableHTTP SSE transport hide stdio MCP KB ingestion tool', type='ticket') surfaced archived transport migration tickets such as #9533, but those concern server transport mechanics, not conditional exposure of this ingestion tool.
  • rg "ingest_source_files|StreamableHTTP|stdio|tool exposure|MCP client" resources/content/issues resources/content/discussions learn/agentos ai/mcp/server/knowledge-base ai/mcp/client surfaced Discussion #11690's adjacent ingest_source_files tool-surface governance discussion and no filed implementation ticket for transport-gated exposure.
  • GitHub issue search for ingest_source_files StreamableHTTP stdio surfaced #11743 as the parent receiver/auth decision issue, not this narrower implementation rule.

The Problem

ingest_source_files currently appears as a normal Knowledge Base MCP tool because it is declared in ai/mcp/server/knowledge-base/openapi.yaml and mapped unconditionally in ai/mcp/server/knowledge-base/toolService.mjs.

Current reality:

  • openapi.yaml declares /db/data/ingest with operationId: ingest_source_files.
  • ToolService.initializeToolMapping() turns every OpenAPI operation with an operationId into a listed MCP tool.
  • knowledge-base/toolService.mjs maps ingest_source_files to ingestSourceFilesViaMcp unconditionally.
  • aiConfig.transport defaults to stdio; sse / StreamableHTTP is the cloud/remote deployment transport.

That means local stdio harnesses carry a repo-push ingestion tool even though their normal ingestion paths are local script/service paths (ai:sync-kb, ai:ingest-tenant, direct service calls). The tool's meaningful external consumer is the HTTP-deployed tenant push client from #11743/#11728, not every local agent session.

The Architectural Reality

Verified surfaces:

Surface Current behavior Gap
ai/mcp/server/knowledge-base/openapi.yaml Declares ingest_source_files as a regular MCP operation. No per-transport visibility metadata.
ai/mcp/ToolService.mjs Lists every OpenAPI operation with an operationId; no config/transport filter. No generic way to hide a tool from tools/list by deployment profile.
ai/mcp/server/knowledge-base/toolService.mjs Registers ingest_source_files in serviceMapping unconditionally. Stdio and HTTP deployments expose the same ingestion tool.
ai/mcp/server/knowledge-base/config.mjs transport defaults to stdio; sse is the HTTP/StreamableHTTP deployment mode. Tool visibility does not inspect transport.
#11743 Owns repo-push receiver/auth decision. Needs the MCP path to be concrete and operator-facing if retained.
Discussion #11690 Adjacent tool-surface governance pressure around ingest_source_files. Broader governance/demotion history; this ticket is the narrow transport-gated compromise.

The Fix

Add a transport-aware visibility rule for the Knowledge Base ingest_source_files MCP operation:

  1. Hide ingest_source_files from tools/list when the KB MCP server runs in stdio transport.
  2. Keep it exposed when the KB MCP server runs in sse / StreamableHTTP transport.
  3. Decide whether hidden tools should also reject direct tools/call by name in stdio mode. Preferred posture: fail closed; a hidden stdio tool should not remain callable by clients that know the name.
  4. Keep non-MCP ingestion paths intact: ai:ingest-tenant and direct service use are not affected by this tool-visibility gate.
  5. Document the behavior in the cloud-deployment / tooling docs so #11728 does not teach local stdio users to call a remote-push tool and does not hide the fact that cloud deployments need an HTTP client/auth setup.

Implementation shape is intentionally open. Candidate options:

  • Add an OpenAPI vendor extension such as x-transports: ['sse'] and teach ToolService to filter both listing and dispatch with a server-provided context.
  • Keep the filter local to the KB tool service if a generic ToolService change is over-broad for one tool.
  • Split the ingestion operation into a separate profile-specific spec only if the filtering approach proves too invasive.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
KB tools/list in stdio mode #11743 receiver/auth correction; Discussion #11690 tool-surface pressure; aiConfig.transport ingest_source_files is omitted from the listed KB MCP tools when transport === 'stdio'. If filtering cannot be done generically, implement a KB-local filter and document why. KnowledgeBase.md / cloud-deployment docs. Unit/integration test proves stdio list excludes the tool.
KB tools/list in sse / StreamableHTTP mode #11720 tenant repo-push deployment path; #11743 ingest_source_files remains listed because remote tenant push clients may need it. If #11743 later chooses a non-MCP receiver, this ticket may be superseded by full demotion. HookWiring.md / day-0 tutorial handoff. Test proves HTTP profile includes the tool.
Direct tools/call by hidden name in stdio Fail-closed tool-surface policy Preferred: reject with a clear transport-gated error rather than silently executing. If backward compatibility requires callable-but-hidden, document the exception explicitly. Tooling docs. Test covers the chosen behavior.
Non-MCP ingestion paths #11635 / #11679 / ai:ingest-tenant CLI/service ingestion remains available independent of MCP tool exposure. None; this ticket must not break ai:ingest-tenant. Hook wiring. Existing CLI tests remain green; add targeted regression if touched.

Acceptance Criteria

  • ingest_source_files is not returned by KB tools/list when the KB server is configured for stdio transport.
  • ingest_source_files is returned by KB tools/list when the KB server is configured for sse / StreamableHTTP transport.
  • Direct stdio tools/call behavior for ingest_source_files is explicitly decided and tested; preferred behavior is fail-closed with a clear transport-gated error.
  • ai:ingest-tenant and direct KnowledgeBaseIngestionService.ingestSourceFiles() use remain unaffected.
  • Docs distinguish local stdio ingestion paths from deployed StreamableHTTP tenant push ingestion.
  • #11743 / #11728 can rely on the result when explaining whether the MCP path is an operator-facing remote ingestion path.

Out of Scope

  • Implementing the operator-facing push client or OAuth automation identity flow. That remains #11743 / a child ticket under #11743 if decomposed further.
  • Full tool-surface governance from Discussion #11690 beyond this one acute ingest_source_files transport gate.
  • Server-side ref-only webhook / clone credentials. That remains #11731.
  • Removing ingest_source_files from all deployments unless #11743 or #11690 follow-up explicitly supersedes the MCP path.

Avoided Traps

Trap Why rejected
Full demotion before #11743 decides the receiver path MCP-over-StreamableHTTP may still be the right remote push path if paired with a prescribed client/auth flow.
Leaving the tool unconditionally visible Keeps local stdio agents carrying a code-event ingestion tool with no normal interactive consumer.
Documentation-only fix The tool surface itself remains misleading unless tools/list reflects the deployment profile.
Conflating transport availability with operator readiness The HTTP tool can exist and still need a concrete push client + automation identity model.

Related

Parent / decision context: #11743

Epic context: #11720, #11728

Related substrate: #11634, #11635, #11679, Discussion #11690, #11731

Origin Session ID

2741c4bd-92b2-428b-92d3-ab718d9a7c41

Handoff Retrieval Hints

  • ask_knowledge_base({query: 'ingest_source_files ToolService openapi transport stdio sse', type: 'all'})
  • query_raw_memories({query: '#11743 MCP client automation account ingest_source_files transport gate'})
  • Source anchors: ai/mcp/server/knowledge-base/toolService.mjs, ai/mcp/server/knowledge-base/openapi.yaml, ai/mcp/ToolService.mjs, ai/mcp/server/knowledge-base/config.mjs.
tobiu referenced in commit 34234d0 - "feat(kb): gate ingest source tool by transport (#11744) (#11745) on May 22, 2026, 10:10 AM
tobiu closed this issue on May 22, 2026, 10:10 AM