Skip to content

feat(narratives): report whether the MCP server serves every required tool - #550

Merged
nick-nlb merged 2 commits into
datacommonsorg:mainfrom
nick-nlb:narratives-agent-loop-c1-required-tools
Oct 23, 2026
Merged

nick-nlb merged 2 commits into
datacommonsorg:mainfrom
nick-nlb:narratives-agent-loop-c1-required-tools

Conversation

@nick-nlb

Copy link
Copy Markdown
Collaborator

Overview

On main, /agent/health reports mcp.generation, a version label derived from the presence of get_variable_metadata alone. A server that lacks one of the search or observation tools is still reported as 1.3.x-or-later, and because the agent declares only the tools the server lists, the model is never offered the missing tool and nothing records the gap.

This change defines the six required MCP 1.3.x tools (REQUIRED_TOOLS), adds required_tools_present and missing_tools to Capabilities, reports missing_tools in /agent/health, logs a warning once per turn when required tools are missing, and makes the post-deploy smoke test fail in that case.

It also replaces mcp.generation with mcp.support, which is supported, unsupported, or unknown. The old label named a server version, but the code never reads a version: it only checks which tools are listed. A later server that drops a required tool, or a server of any version that serves all six, would be mislabeled by a version name. A server that provides get_variable_metadata without all six tools, or a 1.2.x server (which only provides two tools), is now reported as unsupported. The agent loop that follows this PR requires all six tools (the server-side fetch functions in the upcoming per-turn table cache PR call the three observation tools directly), and the remaining 1.2.x parsing in mcp/data_utils.py will be removed later in the sequence.

/agent/health and deploy/smoke.sh use the new fields now, the discovery phase uses the same Capabilities properties, and the TOOL_* constants will be used by the server-side fetch functions in the upcoming per-turn table cache PR.

Related Issues

Follows #544 and #547 (independent of #549).

Changes Made

  • mcp/capabilities.py: Defines constants for the six required MCP tools (TOOL_* and REQUIRED_TOOLS), adds required_tools_present and missing_tools to Capabilities, replaces generation with support (typed as a Literal of supported, unsupported, and unknown), reports support and missing_tools in the /agent/health summary, and adds warn_on_missing_tools() to log a warning when required tools are missing.
  • workflows/chat_pipeline.py: Calls warn_on_missing_tools() during the discovery phase after fetching the tool list so missing tools are logged once per turn.
  • deploy/smoke.sh: The capability check now fails, naming the missing tools, when /agent/health reports that a required tool is missing, and it reports mcp.support.
  • docs/deployment.md, docs/architecture.md, AGENTS.md: Documents the new /agent/health fields, the mcp.support values, and what happens when required tools are missing, and notes the required-tool check in the mcp/ layout entry.

Testing Done

  • pnpm test:agent (uv run pytest): 910 passed (907 on main; 3 tests added).
  • pnpm test:ui (vitest run): 26 files, 286 passed.
  • pnpm lint:ui (tsc --noEmit and biome check): passed.
  • pnpm lint:agent (ruff format --check, ruff check, and mypy --strict): passed across all 72 source files.
  • pnpm build:ui: passed.
  • pnpm lint:deploy: terraform fmt -check, pnpm run lint:shell, and pnpm run lint:docker passed (terraform validate fails with a pre-existing GCS backend configuration error on main; no Terraform files were modified).
  • deploy/smoke.sh check 3: the c3 function was extracted (sed -n '/^c3() {/,/^}/p' deploy/smoke.sh) and run with curl_cmd stubbed to return a recorded /agent/health response. The full six-tool response passed (6 tools, support supported); a two-tool response missing get_variable_metadata and search_child_indicators failed and named both; a response from before this change, without support, failed and said the field is absent. shellcheck reports the same findings on smoke.sh as on main.

Checklist:

  • Unit tests passed
  • Integration tests passed (N/A: the agent has no integration suite; live verification is under Manual)
  • Manual verification
  • Any updated goldens or fixtures were reviewed and are intentional (no goldens changed; the expected describe() payloads in mcp/capabilities_test.py and the expected /agent/health payload in server/routes/system_test.py were updated for the new fields, and the default tool list in workflows/chat_pipeline_test.py now contains the six required tools)

Manual

Verified with pnpm dev:agent against public Data Commons (MCP_SERVER_URL=https://api.datacommons.org/mcp):

  • Health on a cold cache: the first GET /agent/health on a fresh server returned support: "unknown", tool_count: 0, and all six tools in missing_tools.
  • Health after the cache fills: that first poll schedules a background tools/list refresh, and a later GET /agent/health returned support: "supported", tool_count: 6, and missing_tools: [].
  • Chat turn: Sent "What is the population of France?" to POST /agent/chat/stream. The turn called search_indicators and get_observations, streamed data, citations, a chart config, and follow-up questions, and completed normally with no missing-tools warning in the server log.

Risk & Rollback

/agent/health gains support and missing_tools, and no longer returns generation. Any monitoring that reads mcp.generation must switch to mcp.support. deploy/smoke.sh now fails against a backend that lacks any required tool, including any 1.2.x backend. In cloudbuild/deploy-stamp.yaml, the smoke step runs after the new revision is serving, so a failure marks the build as failed without rolling back the revision, and turns still run with the tools the server provides. Turn execution, tool declarations, and the SSE stream are unchanged. Rollback is a clean revert of the PR.

Follow-ups

  • The upcoming per-turn table cache PR (server-side fetch functions) will use the TOOL_* constants to call the observation tools.
  • The remaining 1.2.x parsing in mcp/data_utils.py will be removed later in the agent loop sequence.

Checklist

  • I have read AGENTS.md and followed CODING_GUIDELINES.md, plus FRONTEND.md for UI changes.
  • I have run the app's lint, test, and build commands, as documented in that application's guide.
  • I have commented my code, particularly in hard-to-understand areas.
  • My changes generate no new warnings.

Note: Only Maintainers can approve and merge PRs. Expected initial review time: 3 business days.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the version-based MCP server capability checks with a strict required-tools check. It defines a set of six required tools (REQUIRED_TOOLS) that the agent needs to function correctly. The Capabilities class is updated to track missing tools and report a support status (supported, unsupported, or unknown) instead of a version generation string. A new function warn_on_missing_tools is introduced to log warnings when required tools are missing during the discovery phase. Tests, smoke scripts, and documentation are updated accordingly to reflect these changes. No review comments were provided, so there is no feedback to address.

@nick-nlb
nick-nlb marked this pull request as ready for review October 23, 2026 14:24

@juliawu juliawu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This is a nice change!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants