LearnNewsExamplesServices
Frontmatter
id12033
titleExtract ingest_source_files facade from KB tool mapping
stateClosed
labels
enhancementairefactoringarchitecture
assigneesneo-gpt
createdAtMay 26, 2026, 8:40 PM
updatedAtMay 26, 2026, 9:33 PM
githubUrlhttps://github.com/neomjs/neo/issues/12033
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 26, 2026, 9:33 PM

Extract ingest_source_files facade from KB tool mapping

Closed v13.0.0/archive-v13-0-0-chunk-14 enhancementairefactoringarchitecture
neo-gpt
neo-gpt commented on May 26, 2026, 8:40 PM

Context

Operator technical-debt review on 2026-05-26 flagged that ai/mcp/server/knowledge-base/toolService.mjs currently contains the ingestSourceFilesViaMcp() method body inline above the serviceMapping dispatch table.

The live substrate now intentionally keeps the remote StreamableHTTP/SSE ingest_source_files path after #11743 and #11744, while hiding and fail-closing it for local stdio. This ticket is therefore not a demotion ticket. It is a narrow refactor to keep the retained MCP facade but remove implementation logic from the mapping module.

Duplicate sweep:

  • rg "ingest_source_files|ingestSourceFilesViaMcp|IngestSourceFilesTool|toolService.*mapping" resources/content/issues resources/content/discussions surfaced #11690, #11743, and #11744.
  • #11690 resolved an earlier demotion pressure, but #11743 and #11744 later established the transport-gated compromise: remote MCP path retained, local stdio hidden and fail-closed.
  • #11744 implemented transport gating, not this extraction.
  • No existing ticket was found for moving the MCP facade implementation out of toolService.mjs while retaining the remote tool.

The Problem

toolService.mjs has two roles mixed together:

  1. server-local tool listing / dispatch composition; and
  2. the concrete ingest_source_files facade implementation, including MCP volume counting, KB_INGEST_VOLUME_EXCEEDED, and service dispatch.

The mapping object should read as a declarative OpenAPI operationId to handler table. Keeping a full method definition inline makes the file harder to scan and encourages future tool-specific implementations to accrete directly into the mapping surface.

The Architectural Reality

Verified surfaces:

Surface Current behavior Relevance
ai/mcp/server/knowledge-base/toolService.mjs Defines ingestSourceFilesViaMcp() inline and maps ingest_source_files to it. Refactor target.
ai/mcp/ToolService.mjs Generic OpenAPI operationId to handler dispatcher. Should remain generic and not learn KB-specific transport policy.
KnowledgeBaseIngestionService.ingestSourceFiles() Domain ingestion service consumed by MCP, CLI, and server-side pull paths. Should not receive MCP facade naming or transport exposure logic.
test/playwright/unit/ai/mcp/server/knowledge-base/IngestSourceFilesTool.spec.mjs Already names this surface as an MCP facade and tests the exported handler directly. Test naming supports extracting a dedicated facade module.
#11744 Retains ingest_source_files for StreamableHTTP/SSE and hides/fail-closes stdio. This ticket must preserve that behavior.

Structural pre-flight:

Pre-Flight (structural full): considered ai/mcp/server/knowledge-base/, ai/services/knowledge-base/helpers/, and a new ai/mcp/server/knowledge-base/tools/ subdirectory; consulted learn/benefits/ArchitectureOverview.md Structural Inventory, learn/agentos/v13-path.md M6 service/MCP boundary, ADR list, and sibling files. Chosen destination is an existing KB MCP-server-local sibling module, recommended ai/mcp/server/knowledge-base/ingestSourceFilesTool.mjs, because this is transport/tool-boundary policy over a retained remote facade, not reusable ingestion-domain logic. Map-maintenance: not needed; this decomposes an existing server-local file and introduces no new subsystem row.

The Fix

Extract the ingest_source_files facade implementation out of toolService.mjs into a KB MCP-server-local module.

Recommended shape:

  • Add ai/mcp/server/knowledge-base/ingestSourceFilesTool.mjs.
  • Move ingestSourceFilesViaMcp() there.
  • Move any tightly coupled batch-volume helper with it.
  • Consider moving the ingest_source_files transport visibility and fail-closed policy with it if that improves locality without obscuring listTools() flow.
  • Keep toolService.mjs as the composition root that imports the handler and maps ingest_source_files: ingestSourceFilesViaMcp.
  • Keep KnowledgeBaseIngestionService free of MCP facade naming and transport policy.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
ingest_source_files MCP behavior #11634, #11743, #11744, current IngestSourceFilesTool.spec.mjs Behavior unchanged: remote SSE listed/callable, stdio hidden/fail-closed, over-threshold payload returns KB_INGEST_VOLUME_EXCEEDED. If extraction exposes ambiguity, keep transport visibility in toolService.mjs and move only the handler body. Existing cloud deployment docs; no user-facing doc change expected. Existing IngestSourceFilesTool.spec.mjs should remain green or be updated to import the new module.
toolService.mjs service mapping Generic ToolService dispatch pattern and local server composition Mapping stays declarative and imports handlers rather than defining full tool bodies inline. None. JSDoc comment on extracted module. Unit coverage proves mapping still dispatches.
KnowledgeBaseIngestionService.ingestSourceFiles() Service-layer ingestion boundary No MCP-specific method names or transport visibility policy move into the service. A pure reusable batch-volume helper may live under ai/services/knowledge-base/helpers/ only if multiple non-MCP consumers appear. Existing JSDoc remains authoritative. No service behavior change.

Acceptance Criteria

  • ingestSourceFilesViaMcp() is no longer defined inline in ai/mcp/server/knowledge-base/toolService.mjs.
  • toolService.mjs imports the facade handler and keeps serviceMapping readable as operationId to handler wiring.
  • ingest_source_files behavior remains unchanged for both sse and stdio transports.
  • Oversized MCP payloads still return KB_INGEST_VOLUME_EXCEEDED without dispatching to KnowledgeBaseIngestionService.
  • test/playwright/unit/ai/mcp/server/knowledge-base/IngestSourceFilesTool.spec.mjs is updated only as needed for the new import location and passes.
  • No domain ingestion logic is forked away from KnowledgeBaseIngestionService.

Out of Scope

  • Removing ingest_source_files from StreamableHTTP/SSE deployments.
  • Changing the OpenAPI operation or schema.
  • Changing ai:ingest-tenant, ai:kb-push-client, or server-side TenantRepoSyncService ingestion behavior.
  • Introducing a generic cross-server tool plugin registry.

Related

Origin Session ID: 1578fb3e-7f5a-4b43-a6d0-ba00e66a9885

Handoff Retrieval Hints:

  • ask_knowledge_base({query: "ingest_source_files facade toolService transport gate", type: "all"})
  • rg "ingestSourceFilesViaMcp|ingest_source_files|listTransportVisibleTools" ai/mcp/server/knowledge-base test/playwright/unit/ai/mcp/server/knowledge-base -S
tobiu referenced in commit 2790607 - "refactor(kb): extract ingest source MCP facade (#12033) (#12035) on May 26, 2026, 9:33 PM
tobiu closed this issue on May 26, 2026, 9:33 PM