Skip to content

Add get_observations tool to MCP v2 - #2153

Open
keyurva wants to merge 3 commits into
datacommonsorg:masterfrom
keyurva:mcp-v2-get-observations
Open

keyurva wants to merge 3 commits into
datacommonsorg:masterfrom
keyurva:mcp-v2-get-observations

Conversation

@keyurva

@keyurva keyurva commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Added the get_observations tool to MCP v2 (/mcp/preview), consolidating explicit-entity, child-entity, and multi-entity observation lookups into a single tool.

  • Added V2GetObservations to agent.Service and wired get_observations into the MCP v2 server:
    • variable_dcids accepts 1 to 10 statistical variables sharing observation_properties in one SdmxData query (1 to 2 with child_entity_type_dcid, or 1 with source_override).
    • entity_dcids accepts 1 to 20 entities (or 1 parent entity with child_entity_type_dcid). entity_property (default observationAbout) and additional_entities (up to 2 properties, 1 to 20 DCIDs each) constrain multi-entity variables, with omitted counterpart properties left unconstrained.
    • date supports latest (pushed down as TIME_PERIOD="LATEST"), all (explicit entities only), ISO dates (YYYY, YYYY-MM, YYYY-MM-DD), and range (explicit or inferred when date is omitted alongside date_range_start or date_range_end; child-entity ranges require date_range_start).
  • Returned a single top-level entity_metadata table across active entities and per-variable observations in request order:
    • Ranked dataset facets per variable and populated source_metadata (source_id, import_name and provenance_url from provenance ->[name, url] with provenance DCID fallback, unit, scaling_factor, measurement_method, observation_period) and alternative_sources (with entities_found_count when multiple entities or entity tuples have data).
    • Returned factual note messages when a variable has no observations for the requested entities, source_override, or date window.
  • Added get_observations validation and SDMX rejection diagnostics in v2_tool_errors.go and v2_observations.go without leaking internal Spanner or SDMX error strings.
  • Added instructions/v2/tools/get_observations.md and updated instructions/v2/server.md for the resolve_entities -> search_indicators -> get_observations workflow.

@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 implements the get_observations tool for MCP v2, enabling the retrieval of numerical observations and source metadata for statistical variables. It introduces shared SDMX helpers, date parsing, and facet ranking logic, alongside comprehensive unit and integration tests. The review feedback highlights opportunities to simplify the code by removing redundant nil checks on protobuf messages, as Go protobuf getters are nil-safe.


for _, dcid := range dcids {
p := &nodeProperties{}
if nodeResp != nil && nodeResp.GetData() != nil {

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.

medium

In Go, defensive nil checks before calling generated protobuf getters are unnecessary because protobuf getters are nil-safe. Since nodeResp.GetData() is safe to call even if nodeResp is nil, the nodeResp != nil check can be safely omitted.

Suggested change
if nodeResp != nil && nodeResp.GetData() != nil {
if nodeResp.GetData() != nil {
References
  1. In Go, defensive nil checks before calling generated protobuf getters are unnecessary because protobuf getters are nil-safe.

Comment on lines +1085 to +1092
if fullResult != nil {
if shapeSlots := extractShapeDimensionSlots(fullResult.GetShape()); len(shapeSlots) > 0 {
return shapeSlots
}
if slots := extractDimensionSlots(fullResult); len(slots) > 0 {
return slots
}
}

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.

medium

In Go, defensive nil checks before calling generated protobuf getters are unnecessary because protobuf getters are nil-safe. Since fullResult.GetShape() is safe to call even if fullResult is nil, and extractDimensionSlots also handles a nil result safely, the fullResult != nil check can be safely omitted.

	if shapeSlots := extractShapeDimensionSlots(fullResult.GetShape()); len(shapeSlots) > 0 {
		return shapeSlots
	}
	if slots := extractDimensionSlots(fullResult); len(slots) > 0 {
		return slots
	}
References
  1. In Go, defensive nil checks before calling generated protobuf getters are unnecessary because protobuf getters are nil-safe.

@keyurva
keyurva force-pushed the mcp-v2-get-observations branch from 5c75d69 to 4a0aebb Compare October 31, 2026 00:19

This branch has not been deployed

No deployments
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.

1 participant