Docker MCP Gateway COTS Gap Analysis 2026 07 20 - TerrenceMcGuinness-NOAA/global-workflow GitHub Wiki

EIB MCP-RAG Docker Gateway (COTS) Gap Analysis — 2026-07-20 (Monday morning)

Full-sweep health + gap analysis of the on-prem Docker MCP Gateway (systemd mcp-gateway.service on port :18888, DB_BACKEND=cots, ChromaDB + Neo4j Community on Parallel Works bind-mounted persistent storage), performed after the ChromaDB/Neo4j/n8n stack cutover from the legacy chromadb-persistent.service foreground docker run unit + orphaned Docker-managed volumes to the unified docker-compose.devops.yaml stack. All data preserved through the cutover.

Not to be confused with AgentCore. This report targets the on-prem Docker MCP Gateway wrapper of the eib-mcp-rag-python:latest image — not the AWS AgentCore Runtime deployment. For the AgentCore side of the parity picture see Platform-Parity-Check-AWS-vs-COTS-2026-07-15 and Platform-Health-Comparison-AWS-vs-COTS-2026-07-14.

đŸĨ Overall System Health

Status: HEALTHY (4/4 core components operational, 11/11 functional module tests pass)

  • Base Server: Healthy (FastMCP running via mcp-gateway.service on :18888)
  • Utility Tools: Healthy (4 always-on tools registered)
  • Vector Database (ChromaDB): Healthy — 17 indices, chromadb/chroma:latest on /mcp_rag_eib/data/chromadb (3.0 G store, 17 collections)
  • Graph Database (Neo4j): Healthy — 108,280 nodes / 4,229,217 relationships (health-check scope); 344,604 nodes total across all label prefixes; neo4j:5.26.20-community on /mcp_rag_eib/data/neo4j (1.9 G store)

Functional Module Latencies (all 11 pass)

Module Status Latency
semantic_search pass 69 ms
code_analysis pass 73 ms
graph_rag pass 4 ms
ee2_compliance pass 30 ms
operational pass 84 ms
sdd_workflow pass 0 ms
workflow_info pass 0 ms
github_tools pass 126 ms
utility pass 0 ms
code_awareness pass 31 ms
branch_isolation pass 141 ms

🔌 Server Information

MDC MCP/RAG Server v1.0.0 — 53 tools, 9 of 10 active modules, 5 tenants.

  • Active Modules: semantic_search, code_analysis, graph_rag, ee2_compliance, operational, sdd_workflow, workflow_info, github_tools, utility
  • Backend: DB_BACKEND=cots (ChromaDB + Neo4j Community)
  • Deployment Mode: Docker MCP Gateway (Streamable HTTP, port 18888) via mcp-gateway.service systemd unit

đŸĸ Multi-Tenant Workflows (all 5 reachable)

Tenant Branch Lifecycle Workflow Root
gw (default) develop production /app/.pw_workflow_mount/develop
gw_sfs dev/sfs experimental /app/.pw_workflow_mount/dev-sfs
gw_jedi_gfs dev/jedi-gfs experimental /app/.pw_workflow_mount/dev-jedi-gfs
gw_v17 dev/gfs.v17 staging /app/.pw_workflow_mount/dev-v17
gw_gefs_v12 release/gefs_v12 production /app/.pw_workflow_mount/gefs-v12

🧠 Knowledge Base Status (Default Tenant gw / Branch develop)

Vector Database (ChromaDB)

  • Collections (via adapter): 15
  • Total Documents (via adapter): 0 ← âš ī¸ adapter reports 0 despite 17 real collections in ChromaDB
  • Collections (via direct HTTP): 17
    • global-workflow-docs-v8-1-0, code-with-context-v8-0-0, phase48-scratch, jjobs-v8-0-0, mdc-jjobs-mpnet768, global-workflow-docs-v8-2-0, mdc-ee2-standards-mpnet768, community-summaries, global-workflow-docs-v8-0-0, ci-test-cases-v1-0-0, ee2-standards-v5-0-0-enhanced, jjobs-v8-1-0, mdc-code-context-mpnet768, mdc-workflow-docs-mpnet768, mdc-community-summaries-mpnet768, plus gw_v17_mdc-jjobs-titan1024-v9-0-0 and a scratch tenant collection

Graph Database (Neo4j)

  • Files: 17,273
  • Functions: 113,571
  • Classes: 648
  • Total Nodes (tenant gw scope): 225,836
  • Total Relationships: 4,051,374
  • Top Node Labels: Function (89,595), FortranSubroutine (80,745), File (17,273), FortranFunction (16,849), FortranModule (9,014), PythonFunction (7,127), PythonModule (1,480), Module (1,330), FortranProgram (1,186), ShellScript (589)
  • Top Relationship Types: CALLS (3,306,540), USES (679,698), DEPENDS_ON_ENV (28,504), DEFINES (11,687), IMPORTS (9,141), EXPORTS (7,276), DEPENDS_ON (4,032), INVOKES (2,579), SOURCES (1,788), EXECUTES (129)

đŸ›Ąī¸ Knowledge Integrity

Check Status Detail
Path Consistency âš ī¸ SKIP vector adapter does not expose a metadata sampler
Orphaned Graph Nodes ✅ OK 17,273 File nodes in graph, 0/20 sampled lack identity
Stale Embeddings âš ī¸ SKIP vector adapter does not expose a metadata sampler
Coverage Gap âš ī¸ SKIP no Fortran files found in /app/supported_repos/global-workflow (false negative — see Gap 3)

Only 1 of 4 integrity checks executed on the COTS backend. This is a documented adapter gap, not data loss.

📊 Health Trend (last 10 snapshots)

Timestamp Neo4j Nodes Neo4j Rels ChromaDB Docs Collections
2026-06-26 23:23 108,280 4,220,211 220,538 15
2026-07-02 13:37 108,280 4,220,211 220,538 15
2026-07-02 22:03 108,280 4,220,211 220,538 15
2026-07-03 03:18 108,280 4,220,211 220,538 15
2026-07-09 22:07 108,280 4,229,217 223,148 17
2026-07-14 17:43 108,280 4,229,217 223,148 17
2026-07-20 (today) 108,280 4,229,217 (see Gap 1) 17
  • Trend: Neo4j stable (+0 nodes over 10 snapshots); ChromaDB +2,610 docs
  • Anomalies: None detected (all consecutive changes within 10% threshold)

📑 SDD Framework Status

  • Version: 6.0 Phase 31 (Session-Oriented Tracking Model)
  • Available Workflows: 68
  • Total Sessions: 49 (35 completed, 5 abandoned)
  • Active Session: None

Recent sessions of note:

  • ✅ Phase 68 — RAG Data-Plane Gap Closure — 8 steps (completed)
  • âš ī¸ phase63b — Python Container Gateway Parity — 2 steps (abandoned)
  • âš ī¸ phase63 — Python Container Parity + Backend Rename — 3 steps (abandoned)
  • âš ī¸ phase60 — Code Awareness Tool Parity Branch Validation — 1 step (abandoned; superseded by completed 6-step run)

Gap Analysis: Four Systemic Issues

Gap 1 — ChromaDB adapter does not report document counts (COTS observability parity)

Severity: Medium (correctness of observability, not data) Owner: TBD Proposed Phase: phase70_cots_backend_observability_parity.md

Symptom: get_knowledge_base_status reports Total Documents: 0 and marks the vector database [ERROR] Unhealthy for the gw tenant — yet direct HTTP calls to ChromaDB return the correct 17 collections and the health-history snapshot on 2026-07-14 recorded 223,148 documents.

Root cause: The ChromaDB adapter's count_documents() (or equivalent) is a stub; the KB-status tool sums adapter-reported per-collection counts, which are always 0. The same adapter also does not expose a sample_metadata() method, which is why the integrity check skips Path Consistency and Stale Embeddings.

Impact:

  • False Unhealthy verdict in get_knowledge_base_status
  • 3 of 4 integrity sub-checks skipped
  • Cascade into Gap 2 (gap detection reports 0.0% coverage)
  • Health-history JSONL will show null/0 for ChromaDB Docs on all COTS snapshots going forward

Recommendation: Port the OpenSearch-side count() and sample_metadata() logic into the ChromaDB adapter, using ChromaDB's collection.count() and collection.get(limit=N, include=["metadatas"]) APIs.

Gap 2 — list_all_sources --include_gaps reports 0% coverage on every collection (COTS backend)

Severity: Medium (correctness of observability, not data) Owner: TBD Proposed Phase: rolled into phase70

Symptom:

Collection Declared Actual Coverage
code-with-context-v8-0-0 90,098 0 0.0%
global-workflow-docs-v8-0-0 21,248 0 0.0%
community-summaries 2,113 0 0.0%
jjobs-v8-0-0 751 0 0.0%
ee2-standards-v5-0-0-enhanced 34 0 0.0%

Root cause: The gap detector's "actual" side calls the OpenSearch _count API (per tool description). Against a ChromaDB backend it returns 0 or errors silently. Combined with Gap 1's stubbed count_documents(), every declared source appears fully un-ingested.

Impact: Every dashboard driven by include_gaps=true will show 100% gap on the COTS backend, potentially triggering unwarranted re-ingest work.

Recommendation: Route the "actual" count through the active backend adapter (UnifiedDataAccess.get_backend().vector.count(collection)) instead of a hard-wired OpenSearch call.

Gap 3 — Coverage-gap Fortran check uses hard-coded path

Severity: Low (false negative; data is present in the graph) Owner: TBD Proposed Phase: phase72_fortran_coverage_gap_path_fix.md

Symptom: check_knowledge_integrity skips its Coverage-Gap sub-check with no Fortran files found in /app/supported_repos/global-workflow — despite Neo4j holding 80,745 FortranSubroutine nodes, 16,849 FortranFunction nodes, and 9,014 FortranModule nodes for tenant gw.

Root cause: The check hard-codes the pre-multitenant path /app/supported_repos/global-workflow. Under Phase 61 (Configurable Workflow Mount Base), source now lives under /app/.pw_workflow_mount/<subdir> (e.g. /app/.pw_workflow_mount/develop).

Recommendation: Read the path from the tenant catalog (workflow_root field) instead of hard-coding, with a graceful fallback to counting Fortran*-labeled nodes in the graph.

Gap 4 — RAG quality benchmark has never been run (no quality_metrics.jsonl)

Severity: Medium (blind spot on RAG quality regression) Owner: TBD Proposed Phase: phase71_nightly_rag_benchmark_harness.md

Symptom: get_quality_metrics returns:

No benchmark results found. Expected at
/app/mcp_server_python/sdd_framework/execution_state/quality_metrics.jsonl.
Run the benchmark harness to generate results.

Root cause: A benchmark harness exists (mcp_server_node/scripts/benchmark_runner.py, mcp_server_node/scripts/run_benchmark.js, mcp_server_node/scripts/config/benchmark_ground_truth.json, plus Phase 22 and Phase 24g specs), but nothing schedules it. The quality_metrics.jsonl file has never been written.

Impact: No baseline exists to detect RAG regression across ingests, embedding-model swaps, or backend cutovers. get_quality_metrics --compare cannot function.

Recommendation: Add a nightly systemd timer (or cron entry) that runs the benchmark harness against the running gateway, writes quality_metrics.jsonl to the expected path, and rotates old snapshots. Complete the Python-side port so both Node and Python versions are runnable.


â„šī¸ Informational — Not a Gap

Node-count numbers vary across tools (by design, but undocumented)

Three legitimate node counts surface from the same graph:

Reporter Count Scope
Raw cypher-shell MATCH (n) RETURN count(n) 344,604 All labels, all tenant prefixes
get_knowledge_base_status (tenant gw) 225,836 Empty label_prefix (base develop tenant)
mcp_health_check "Graph Database" summary 108,280 Curated subset (stable across 10 snapshots since 2026-06-26)

The 108,280 value is neither a bug nor drift — it has been rock-stable across every health snapshot for 24 days. What's missing is documentation of which labels the health check counts vs the KB-status tool. Proposed phase73_graph_node_count_scope_documentation.md to capture and label these scopes explicitly.

Infrastructure Cutover Completed Today

  • Retired chromadb-persistent.service systemd unit (foreground docker run --rm --name chromadb — colliding with the compose stack)
  • Cleaned up empty leftover Docker-managed volumes: setup_neo4j-{data,logs,plugins,import}, neo4j_data (all 0 B, unreferenced)
  • Migrated to docker-compose.devops.yaml with three edits:
    1. NEO4J_AUTH=neo4j/${NEO4J_PASSWORD:-gfsworkflow2025} — matches the on-disk auth store; verified working against the 344,604-node dataset
    2. image: ${CHROMADB_IMAGE:-chromadb/chroma:latest} and image: ${MCPSERVER_IMAGE:-eib-mcp-rag-python:latest} — local defaults, CI still overrides via CI_REGISTRY
    3. mcp-server service placed behind profiles: [with-mcp-server] — opt-in, avoids competing with mcp-gateway.service
  • All persistent data (ChromaDB 3 G, Neo4j 1.9 G, n8n) preserved on bind mounts under /mcp_rag_eib/data/

📋 Recommended Follow-Up SDD Phases

Four gap-closure phases drafted under sdd_framework/workflows/:

Phase Title Addresses
70 COTS Backend Observability Parity Gaps 1 & 2
71 Nightly RAG Benchmark Harness Gap 4
72 Fortran Coverage-Gap Path Fix Gap 3
73 Graph Node-Count Scope Documentation Informational disagreement

📎 Appendix — Raw Tool Output

mcp_health_check --deep --detailed --functional
Overall Status: HEALTHY (4/4 components healthy)
[OK] Base Server: healthy - FastMCP running
[OK] Utility Tools: healthy - 4 utility tools registered
[OK] Vector Database: healthy - 17 indices
[OK] Graph Database: healthy - 108280 nodes, 4229217 relationships

Functional Validation:
  semantic_search   pass  69ms
  code_analysis     pass  73ms
  graph_rag         pass  4ms
  ee2_compliance    pass  30ms
  operational       pass  84ms
  sdd_workflow      pass  0ms
  workflow_info     pass  0ms
  github_tools      pass  126ms
  utility           pass  0ms
  code_awareness    pass  31ms
  branch_isolation  pass  141ms
Summary: 11/11 passed, 0 failed, 0 skipped
Health snapshot persisted to health_history.jsonl
get_knowledge_base_status (tenant gw)
Vector Database (ChromaDB)
  Collections: 15
  Total Documents: 0
  Status: [ERROR] Unhealthy   <-- adapter gap; see Gap 1

Graph Database (Neo4j)
  Files: 17273, Functions: 113571, Classes: 648
  Total Nodes: 225836, Total Relationships: 4051374
  Status: [OK] Healthy
list_all_sources --include_gaps
Total Sources: 67 (65 enabled)

By Source Type:
  code_parse         3 sources    88,614 declared docs
  community_summary  1 source      2,113 declared docs
  config_parse       2 sources     1,484 declared docs
  jjob_docs          1 source        751 declared docs
  on_disk_submodule  1 source      1,759 declared docs
  standards          1 source         34 declared docs
  url_crawl         58 sources    19,489 declared docs

Gap Detection:
  code-with-context-v8-0-0       90,098 declared / 0 actual  (0.0% - adapter gap)
  global-workflow-docs-v8-0-0    21,248 declared / 0 actual  (0.0% - adapter gap)
  community-summaries             2,113 declared / 0 actual  (0.0% - adapter gap)
  jjobs-v8-0-0                      751 declared / 0 actual  (0.0% - adapter gap)
  ee2-standards-v5-0-0-enhanced      34 declared / 0 actual  (0.0% - adapter gap)
get_quality_metrics
No benchmark results found.
Expected at: /app/mcp_server_python/sdd_framework/execution_state/quality_metrics.jsonl
Run the benchmark harness to generate results.

Report generated 2026-07-20 by running the full MCP tool sweep against the on-host mcp-gateway.service (Docker MCP Gateway, COTS backend). Health snapshot persisted to health_history.jsonl. Companion to EIB-MCP-RAG-Full-State-of-Affairs-Report-2026-07-15 (same Python codebase via the stdio server instead of the gateway wrapper).

âš ī¸ **GitHub.com Fallback** âš ī¸