agentcore mcp rag Health Status Report 2026 06 10 - TerrenceMcGuinness-NOAA/global-workflow GitHub Wiki

agentcore-mcp-rag โ€” Health & Status Report

Date: 2026-06-10 Server: agentcore-mcp-rag (AWS Bedrock AgentCore Runtime, ARN arn:aws:bedrock-agentcore:us-east-1:<ACCOUNT_ID>:runtime/<PYTHON_RUNTIME_ID>) Method: Direct agentcore-mcp-rag MCP utility / GraphRAG calls, cross-checked against the deployed source tree at /mnt/mdc-mcp-rag/eib-mcp-rag-server.

Companion to agentcore-mcp-rag Tool Usage Analysis (v17 GEMPAK) โ€” that page rates task-level usefulness of the tools; this page is the operational health of the deployment plus root-cause analysis of issues uncovered.


1. Headline status

Component Status Evidence
Base server (FastMCP) HEALTHY mcp_health_check: 4/4 OK
Utility tools HEALTHY (4 registered) get_server_info: 9/9 modules active, 52/52 tools
Vector DB (OpenSearch) HEALTHY 16 collections, 252,081 docs
Graph DB (Neptune) HEALTHY 148,976 nodes / 4,555,407 relationships
Tenant catalog OK (5 tenants) gw, gw_sfs, gw_jedi_gfs, gw_v17, gw_gefs_v12
Workflow filesystem mount NOT MOUNTED /mnt/workflow absent in microVM
SDD framework Operational, degraded WorkflowExecutor degraded; 0 workflows loaded
Health-trend snapshots EMPTY No persisted history
Quality-metrics benchmarks EMPTY quality_metrics.jsonl not present
check_knowledge_integrity BROKEN tz bug, fails on every tenant
Per-tenant vector indices MISSING for non-gw Gap B โ€” ingestion writing 0 docs
trace_full_execution_chain DEGRADED 30s Neptune statement timeout at depth โ‰ฅ2

Bottom line: the deployment is up and serving graph + vector queries on the gw baseline; non-gw tenants are graph-only, and there are three concrete bugs (timezone, ingestion-writes-zero-docs, traversal timeout) that need fixes.


2. Raw responses

2.1 get_server_info

MDC MCP/RAG Server v1.0.0
Total Tools: 52   Active Modules: 9 of 9   Tenants: 5 (default: gw)

Active Modules:
  semantic_search, code_analysis, graph_rag, ee2_compliance, operational,
  sdd_workflow, workflow_info, github_tools, utility

Capabilities:
  Data Access: connected
  Vector Search: available
  Graph Queries: available
  Utility Tools: always-on (4 tools registered)

2.2 mcp_health_check(detailed=true)

Overall Status: HEALTHY (4/4 components healthy)
[OK] Base Server     : FastMCP running
[OK] Utility Tools   : 4 utility tools registered
[OK] Vector Database : 5 indices
[OK] Graph Database  : 105891 nodes, 4729092 relationships

Tenants (5):
  gw           develop          production    no  /mnt/workflow/develop      (not mounted)
  gw_sfs       dev/sfs          experimental  no  /mnt/workflow/dev-sfs      (not mounted)
  gw_jedi_gfs  dev/jedi-gfs     experimental  no  /mnt/workflow/dev-jedi-gfs (not mounted)
  gw_v17       dev/gfs.v17      staging       no  /mnt/workflow/dev-v17      (not mounted)
  gw_gefs_v12  release/gefs_v12 production    no  /mnt/workflow/gefs-v12     (not mounted)

Default tenant: gw (resolved from catalog.defaults.tenant_id)
Workflow Filesystem mount: /mnt/workflow (NOT mounted)

The base-health node count (105,891 / 4,729,092) and the get_knowledge_base_status count below (148,976 / 4,555,407) disagree โ€” they measure different things (live Neptune count vs cached aggregate) and both are reported as healthy. Worth tracking, not blocking.

2.3 get_knowledge_base_status (default gw)

Vector โ€” 16 OpenSearch collections, 252,081 docs, all healthy:

Collection Docs
code-context-titan1024 90,135
code-context-mpnet768 60,576
content-sha-registry 52,822
workflow-docs-mpnet768 22,498
workflow-docs-titan1024 20,155
community-summaries (titan + mpnet) 2,113 each
jjobs (titan + mpnet) 751 / 700
ee2-standards (titan + mpnet) 34 each
nova1024 collections 0 (5 collections, all empty)

Graph (Neptune) โ€” 148,976 nodes / 4,555,407 relationships:

Edges:  CALLS 3,407,104   USES 997,616   DEFINES 91,652
        DEPENDS_ON_ENV 31,601   IMPORTS 10,443   EXPORTS 7,925
        DEPENDS_ON 4,752   INVOKES 2,690   SOURCES 1,528   EXECUTES 96
Nodes:  Function 87,610   FortranSubroutine 27,941   File 17,273
        FortranFunction 5,744   FortranModule 4,800   PythonFunction 2,642
        PythonModule 719   FortranProgram 671   Module 980   ShellScript 315

2.4 get_knowledge_base_status(tenant_id="gw_v17")

Vector โ€” identical totals to gw (the API returns the global vector store view, not a tenant-scoped view โ€” see ยง3.1).

Graph (gw_v17) โ€” 80,996 nodes / 1,278,330 relationships:

Edges:  CALLS 1,019,436   USES 229,353   DEPENDS_ON_ENV 20,434
        EXPORTS 6,064   INVOKES 1,767   SOURCES 928
        DEFINES 337   EXECUTES 11
Nodes:  FortranSubroutine 36,156   File 30,221   FortranFunction 8,172
        FortranModule 4,558   ShellScript 1,401   FortranProgram 488

Notable absences in the gw_v17 graph:

  • No Python labels (PythonFunction, PythonModule) โ€” Python ingestion has not run on this tenant.
  • DEFINES collapsed from 91,652 โ†’ 337 โ€” the relationship that pairs every Fortran subroutine/function with its containing module. On gw_v17 only ~0.4% of the expected DEFINES exist; subroutines are present as nodes but largely orphaned from their module containers.
  • No IMPORTS / DEPENDS_ON edges โ€” the dependency-graph tools that rely on these will return sparse results on gw_v17.

2.5 get_sdd_framework_status(detailed=true)

Version: 6.0 Phase 31     Status: Operational
Available Workflows: 0    Total Sessions: 0
Active Session: none
[OK] start_sdd_session, record_sdd_step, get_sdd_session,
     complete_sdd_session, get_sdd_execution_history
[..] ISD approval (dormant โ€” reserved for Phase 4C USD)
[..] WorkflowExecutor (filesystem-backed; degraded on AgentCore microVM)
[OK] SpecificationParser, SelfModificationEngine

2.6 get_health_trend & get_quality_metrics

get_health_trend  โ†’ "No health history found."
get_quality_metrics โ†’ "No benchmark results found at
                       /app/sdd_framework/execution_state/quality_metrics.jsonl"

2.7 check_knowledge_integrity(*)

Tested against gw, gw_sfs, gw_v17. All three failed identically:

[ERROR] can't subtract offset-naive and offset-aware datetimes

Server-wide bug, not tenant-specific.

2.8 trace_full_execution_chain(start="JGFS_ATMOS_GEMPAK", tenant_id="gw_v17")

max_depth Outcome Time
5 (default) Neptune 500 โ€” out of memory n/a
2 30s statement timeout, graceful fallback to 1-hop neighbors โ‰ค30 s
1 OK, 12 nodes, 7 bridge crossings 14.9 s

So the tool degrades gracefully (good), but the default depth is unusably high for non-trivial roots, and even depth 1 takes ~15 s.

2.9 Vector-search behavior on gw_v17 (cross-check)

Tool Tenant Result
search_documentation("GEMPAK") gw 3 hits (METplus, EE2 standards, โ€ฆ)
search_documentation("GEMPAK") gw_v17 "No results found"
search_architecture(...) gw_v17 index_not_found_exception: gw_v17_community-summaries
find_similar_code(...) gw_v17 index_not_found_exception: gw_v17_code-with-context-v8-0-0
get_operational_guidance(...) gw_v17 index_not_found_exception: gw_v17_global-workflow-docs-v8-0-0

Same root cause โ€” the gw_v17_* indices don't exist โ€” but the error path is inconsistent (one tool says "no results", three return raw OpenSearch 404s).


3. Investigation: root causes

3.1 Why get_knowledge_base_status looks identical for every tenant

get_knowledge_base_status reports the physical OpenSearch domain (all collections), not a tenant-prefixed view. Per mcp_server_python/src/data/opensearch_adapter.py:

def resolve_tenant_index(self, collection: str, tenant) -> str:
    """Apply tenant.index_prefix to a logical collection name."""
    if not tenant.index_prefix:
        return collection
    return f"{tenant.index_prefix}{collection}"

The prefix is applied at query time by individual search tools, so a tenant that has no prefixed indices yet (gw_v17, gw_sfs, etc.) will hit NotFoundException on real searches even though kb_status shows a "healthy" domain. This is misleading and is the strongest cause of false positives in operational monitoring.

3.2 Why gw_v17 graph is missing Python edges and most DEFINES

The latest ingestion report at mcp_server_python/scripts/ingestion_reports/gw_v17_20260610T232209.json:

{
  "tenant_id": "gw_v17",  "mode": "bridge",
  "elapsed_seconds": 0.4,  "total_files_processed": 61,
  "documents_created": {},
  "embedding_calls": { "bedrock_invocations": 0, "estimated_tokens": 0 },
  "graph": { "nodes_created_by_label": {}, "relationships_created": 16 },
  "drift_flags": [
    "dedupe_efficiency_pct", "documents_created_total", "estimated_tokens"
  ]
}

A second report from earlier the same day in mode: "full" (3-hour run, 6,935 files) shows:

{
  "documents_created": {},   // ZERO documents created
  "embedding_calls": { "bedrock_invocations": 0 },  // Bedrock never invoked
  "graph": {
    "nodes_created_by_label": {
      "GW_V17_FortranModule": 4869, "GW_V17_FortranSubroutine": 31543,
      "GW_V17_FortranFunction": 8200, "GW_V17_FortranProgram": 543
    },
    "relationships_created": 297712
  }
}

The harness itself raises drift flags (dedupe_efficiency_pct, documents_created_total, estimated_tokens) โ€” it knows nothing was written โ€” but the run continues and exits 0. Hence:

  • OpenSearch side: no gw_v17_* indices created โ†’ all per-tenant vector searches return NotFoundException.
  • Neptune side: only the Fortran walker fires (32K subroutines / 8K functions ingested as nodes); the Python and Shell graph walkers either didn't run or didn't write DEFINES edges.

This explains every Gap B symptom we have observed. It is an active ingestion-pipeline bug, not just "porting in progress".

3.3 Why check_knowledge_integrity always errors

In mcp_server_python/src/tools/semantic_search.py:

# now is timezone-aware
now = datetime.now(timezone.utc)

# _parse_iso_ts returns whatever fromisoformat gives us:
def _parse_iso_ts(raw):
    if raw.endswith("Z"):
        raw = raw[:-1] + "+00:00"
    return datetime.fromisoformat(raw)   # NAIVE if input has no offset

# later:
if (now - mod_time).days > STALE_EMBEDDING_DAYS:   # CRASHES

If any sampled document's lastModified/ingestedAt is a bare ISO string (no Z, no +HH:MM), _parse_iso_ts returns a naive datetime; subtracting from now raises exactly the error we see: can't subtract offset-naive and offset-aware datetimes.

Fix (one line):

def _parse_iso_ts(raw):
    if not isinstance(raw, str): return None
    try:
        if raw.endswith("Z"): raw = raw[:-1] + "+00:00"
        dt = datetime.fromisoformat(raw)
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=timezone.utc)   # โ† assume UTC for naive ts
        return dt
    except ValueError:
        return None

3.4 Why trace_full_execution_chain times out

The query expands ALL forward SOURCES, INVOKES, EXECUTES, CALLS, USES, DEFINES edges out to max_depth=5 by default. On the JGFS_ATMOS_GEMPAK root that quickly explodes into thousands of paths via shared utilities like product_functions.sh, jjob_header.sh, etc. Neptune enforces a 30 s statement timeout and (at depth 5) an OOM ceiling.

The tool already has a graceful-fallback path at depth 2 โ€” that path should become the default behaviour at every depth, with a budgeted traversal.

3.5 Why /mnt/workflow is "not mounted"

This is by design for the AgentCore deployment. Runtime containers run in ephemeral Firecracker microVMs and do not bind-mount EFS. Ingestion runs in a separate offline pipeline (scripts/overnight_v17_ingest.sh, overnight_v17_ingest_phase2.sh) using MCP_WORKTREE_ROOT_OVERRIDE=/mnt/efs-staging/supported_repos/global-workflow.

Operational impact:

  • Tools that try to read script content (get_job_details(include_content=true), describe_component(show_content=true)) must always fail at runtime.
  • Tools that walk git history (_git_head_time, _git_file_time used by check_knowledge_integrity) fall back to staleness-by-days because there is no repo to inspect.

The decoupling is correct architecturally, but tools that advertise content/git capabilities should detect the mount absence and either degrade explicitly or hide the parameter on this deployment.

3.6 nova1024 collections are empty

Five collections (*-nova1024, total 0 docs) are provisioned but unused. Either the Nova embedding profile was a planned alternative that didn't ship, or the ingester was never pointed at it. Worth deciding: keep and populate, or drop and reduce surface area.

3.7 SDD framework workflows directory not present

get_sdd_framework_status reports 0 workflows; list_sdd_workflows says "/app/sdd_framework/workflows not bind-mounted on hosted Python runtime." The container image was not packaged with the workflow tree, and (like /mnt/workflow) it isn't mounted. SDD session tools work; SDD discovery tools don't.


4. Severity-ranked recommendations

# Severity Issue Recommended fix
1 HIGH gw_v17 ingestion writes 0 docs / 0 Bedrock calls Investigate why documents_created={} despite 6,935 files processed in full mode. Likely candidate: embedding-client wiring or index-creation step is silently skipped. Fail the run if drift_flags fire instead of warning.
2 HIGH check_knowledge_integrity broken on all tenants Apply the one-line _parse_iso_ts fix in ยง3.3 and add a unit test for naive ISO strings.
3 HIGH kb_status is not tenant-aware Make get_knowledge_base_status(tenant_id=โ€ฆ) show prefixed-index counts and a per-tenant readiness flag (vector_ready: bool, graph_ready: bool).
4 MED trace_full_execution_chain OOMs at default depth Lower default max_depth from 5 โ†’ 2; keep current graceful fallback; document the budget.
5 MED Inconsistent error path for missing indices One tool returns "No results", three return raw 404s. Normalize to [INFO] vector index not built for tenant <x> (Gap B).
6 MED Tool unavailability without explanation Several utility tools were "not available" in an earlier session. Either the proxy or AgentCore was dropping registrations. Add a heartbeat probe to agentcore-kiro-proxy.py that lists tools after startup and logs gaps.
7 LOW get_health_trend empty Wire a cron / startup hook that runs mcp_health_check(deep=true) daily so trends actually accumulate.
8 LOW get_quality_metrics empty Run the benchmark harness; or remove the tool from the published catalog until it has data.
9 LOW nova1024 collections empty Decide and either populate or remove.
10 LOW Mount-aware tool surface get_job_details(include_content) and describe_component(show_content) should silently no-op (with [INFO] content unavailable on this deployment) instead of advertising capabilities the runtime can't deliver.

5. SoC observations (additions to the prior analysis)

The prior tool-usage analysis flagged several SoC issues; this health pass adds three more:

  1. Health vs readiness are conflated. mcp_health_check reports "HEALTHY" while three production tenants cannot serve a vector search. Health (the service is up) and readiness (this tenant can answer this query) are different concerns; the API conflates them.
  2. Ingestion observability is weak. Drift flags exist on the report but aren't surfaced to either MCP consumers (no tool exposes recent ingestion reports) or to operators (no alert fires when documents_created=0). Adding a get_ingestion_status(tenant_id) tool that reads the latest report would close the loop without changing the ingestion architecture.
  3. Backend errors leak across the abstraction. Raw OpenSearch NotFoundError strings reach the agent. The error-translation concern should live in one place (the OpenSearch adapter), normalizing all "missing-index for tenant X" errors into a structured, tenant-aware MCP response.

6. Verification commands

For an operator to reproduce / monitor:

# Health snapshot (run daily; seeds get_health_trend)
mcp_health_check(deep=True)

# Tenant-by-tenant readiness probe
for t in ["gw","gw_sfs","gw_jedi_gfs","gw_v17","gw_gefs_v12"]:
    get_knowledge_base_status(tenant_id=t)
    search_documentation("GEMPAK", tenant_id=t, max_results=1)  # cheap query

# Ingestion report (read directly from EFS until exposed as a tool)
ls -lat /mnt/mdc-mcp-rag/eib-mcp-rag-server/mcp_server_python/scripts/ingestion_reports/

# Integrity check (currently broken โ€” re-run after fix in ยง3.3)
check_knowledge_integrity(tenant_id="gw")

Sources

  • MCP utility / GraphRAG tool responses (above).
  • Server source: mcp_server_python/src/{tools,data,config,tenancy}/ at /mnt/mdc-mcp-rag/eib-mcp-rag-server.
  • Tenant catalog: mcp_server_python/src/config/tenants.yaml.
  • Ingestion reports: mcp_server_python/scripts/ingestion_reports/gw_v17_*.json.
  • Phase-2 ingest scripts: scripts/overnight_v17_ingest{,_phase2}.sh.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ