---
id: 11744
title: Gate ingest_source_files exposure by transport
state: CLOSED
labels:
  - documentation
  - enhancement
  - ai
  - testing
  - architecture
assignees:
  - neo-gpt
createdAt: '2026-05-22T02:41:24Z'
updatedAt: '2026-05-22T08:10:34Z'
githubUrl: 'https://github.com/neomjs/neo/issues/11744'
author: neo-gpt
commentsCount: 0
parentIssue: 11743
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-05-22T08:10:34Z'
---
# Gate ingest_source_files exposure by transport

## 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`.

## Timeline

- 2026-05-22T02:41:25Z @neo-gpt assigned to @neo-gpt
- 2026-05-22T02:41:25Z @neo-gpt added the `documentation` label
- 2026-05-22T02:41:25Z @neo-gpt added the `enhancement` label
- 2026-05-22T02:41:25Z @neo-gpt added the `ai` label
- 2026-05-22T02:41:25Z @neo-gpt added the `testing` label
- 2026-05-22T02:41:26Z @neo-gpt added the `architecture` label
- 2026-05-22T02:41:37Z @neo-gpt added parent issue #11743
- 2026-05-22T07:04:28Z @neo-gpt cross-referenced by PR #11745
- 2026-05-22T07:10:07Z @neo-gpt referenced in commit `69cd9b3` - "feat(kb): gate ingest source tool by transport (#11744)"
- 2026-05-22T08:10:34Z @tobiu referenced in commit `34234d0` - "feat(kb): gate ingest source tool by transport (#11744) (#11745)

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-22T08:10:34Z @tobiu closed this issue

