Docker MCP Gateway COTS Gap Analysis 2026 07 20 - TerrenceMcGuinness-NOAA/global-workflow GitHub Wiki
Full-sweep health + gap analysis of the on-prem Docker MCP Gateway (systemd
mcp-gateway.serviceon 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 legacychromadb-persistent.serviceforegrounddocker rununit + orphaned Docker-managed volumes to the unifieddocker-compose.devops.yamlstack. 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:latestimage â 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.
Status: HEALTHY (4/4 core components operational, 11/11 functional module tests pass)
-
Base Server: Healthy (FastMCP running via
mcp-gateway.serviceon :18888) - Utility Tools: Healthy (4 always-on tools registered)
-
Vector Database (ChromaDB): Healthy â 17 indices,
chromadb/chroma:lateston/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-communityon/mcp_rag_eib/data/neo4j(1.9 G store)
| 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 |
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.servicesystemd unit
| 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 |
- 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, plusgw_v17_mdc-jjobs-titan1024-v9-0-0and a scratch tenant collection
-
- Files: 17,273
- Functions: 113,571
- Classes: 648
-
Total Nodes (tenant
gwscope): 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)
| Check | Status | Detail |
|---|---|---|
| Path Consistency | 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 | vector adapter does not expose a metadata sampler | |
| Coverage Gap | 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.
| 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)
- 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)
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
Unhealthyverdict inget_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/0forChromaDB Docson 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.
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.
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.
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.
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.
- Retired
chromadb-persistent.servicesystemd unit (foregrounddocker 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.yamlwith three edits:-
NEO4J_AUTH=neo4j/${NEO4J_PASSWORD:-gfsworkflow2025}â matches the on-disk auth store; verified working against the 344,604-node dataset -
image: ${CHROMADB_IMAGE:-chromadb/chroma:latest}andimage: ${MCPSERVER_IMAGE:-eib-mcp-rag-python:latest}â local defaults, CI still overrides viaCI_REGISTRY -
mcp-serverservice placed behindprofiles: [with-mcp-server]â opt-in, avoids competing withmcp-gateway.service
-
- All persistent data (ChromaDB 3 G, Neo4j 1.9 G, n8n) preserved on bind mounts under
/mcp_rag_eib/data/
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 |
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).