Skip to main content
Glama
WillHsiaoNYC

NYC Open Data Capital Projects MCP Server

by WillHsiaoNYC

get_project_schedule

Read-onlyIdempotent

Retrieve capital project schedule by PID, including phase, lifecycle, variance, linked budgets, and forecast_past_due status.

Instructions

Schedule (PID): phase, lifecycle, signed variance, reason; lists linked budgets; forecast_past_due flags a forecast already past as of the PID's own latest report (never true for completed/cancelled).

Interpretation rules:

  • [relationships] "Project" is ambiguous: PID identifies a SCHEDULE; FMS ID identifies a BUDGET. They are MANY-TO-MANY: a budget can fund several PIDs and a PID can have several budgets. LIST ALL linked counterparts; never silently select one. One linked counterpart does not establish a 1:1 relationship in the reverse direction. A budget without a PID is normal before Design and for lines that do not require schedules; absence alone does not establish missing data. Source-only schedules can also lack dashboard funding links.

  • [population] Listings/rankings default to population_scope='latest_known' (each entity's own latest observation). Use population_scope='current' for the selected complete snapshot. State the population_scope and observation period; respect present_in_current_snapshot. Detail tools use latest-known state and each anchor's latest available link period; these links are not proof of presence in the current complete snapshot.

  • [lifecycle] Lifecycle: Pre-Design -> Design -> Construction Procurement -> Construction -> Close-out. Schedule progression is reported from Design through Construction. Forecasts and most actual milestones can be suppressed outside those phases; actual_construction_end is the exception and means substantial completion. NULL milestones need not mean missing data. Budget spend%=100 does not prove completion. forecast_past_due is evaluated as of the observation period, not today's date.

  • [funding_totals] attributed_budget counts a funding line fully on every PID it funds; it is not an allocated share or an independent project cost. Summing it across PIDs can double-count shared funding. For the portfolio's distinct funding total use summary.line_budget_total, which counts each (managing_agency, fms_id) once. State which budget basis is reported.

  • [signed_values] Report neutral, SIGNED changes: "moved 45 days later" or "budget decreased $2M". Do not echo loaded terms in the answer. "slippage" means positive schedule change and "overrun" means positive budget growth; neither includes the decreasing side. Preserve the returned direction and metric basis.

  • [schedule_coverage] Schedule totals and cumulative variance use dashboard-aligned schedule_history. source_schedule_history retains native observations absent from that population; schedule_source_coverage reconciles them. State the schedule universe and cumulative basis. Parenthesized phases are no-schedule reasons. Respect excluded variance artifacts and missing/invalid-duration counts; forward duration statistics exclude reversed dates.

  • [location] Location belongs to the BUDGET LINE, represented by fms_location. A PID inherits its funding-line boroughs: one specific borough takes precedence over Citywide, multiple specific boroughs yield 'Multiple', and only Citywide lines yield 'Citywide'. Preserve the boroughs list when several boroughs apply.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pidYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
answerYes
provenanceYes
linked_budgetsYes
interpretation_rulesYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv0.1.1
    • addedInput schema / properties / pid / minLength
      Added value: +1
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$defs": {
      +    "InterpretationRule": {
      +      "properties": {
      +        "id": {
      +          "description": "Stable identifier of the domain rule.",
      +          "title": "Id",
      +          "type": "string"
      +        },
      +        "text": {
      +          "description": "Guidance for interpreting and reporting this tool's result.",
      +          "title": "Text",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "id",
      +        "text"
      +      ],
      +      "title": "InterpretationRule",
      +      "type": "object"
      +    }
      +  },
      +  "additionalProperties": true,
      +  "properties": {
      +    "answer": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": true,
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Answer"
      +    },
      +    "interpretation_rules": {
      +      "items": {
      +        "$ref": "#/$defs/InterpretationRule"
      +      },
      +      "title": "Interpretation Rules",
      +      "type": "array"
      +    },
      +    "linked_budgets": {
      +      "items": {
      +        "additionalProperties": true,
      +        "type": "object"
      +      },
      +      "title": "Linked Budgets",
      +      "type": "array"
      +    },
      +    "provenance": {
      +      "additionalProperties": true,
      +      "title": "Provenance",
      +      "type": "object"
      +    }
      +  },
      +  "required": [
      +    "provenance",
      +    "interpretation_rules",
      +    "answer",
      +    "linked_budgets"
      +  ],
      +  "title": "ScheduleResult",
      +  "type": "object"
      +}
  2. First observedv0.1.0

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/closed-world safety, so the bar is low, yet the description adds substantive behavior: forecast_past_due is evaluated as of the observation period (never for completed/cancelled), attributed_budget double-counts shared funding, and schedule totals use dashboard-aligned schedule_history. This is meaningful context beyond the annotations, though nothing on rate limits or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with purpose and organized under bracketed headers ([relationships], [population], [lifecycle]), which aids scanning. However for a single-parameter read tool the volume is heavy and much of it reads as cross-cutting boilerplate likely shared across many sibling tools rather than tool-specific value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be re-explained, and the description instead supplies the interpretive domain context (lifecycle phases, funding basis, location inheritance) an agent needs to read the results correctly. It is close to complete for this tool's complexity, with the pid format being the main omission.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one input (pid) at 0% schema coverage, so the description must compensate. It does clarify PID identity in [relationships] ('PID identifies a SCHEDULE; FMS ID identifies a BUDGET'), which partly compensates, but it never states the pid format or expected value, and the population_scope referenced in the text is not actually in this schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opener 'Schedule (PID): phase, lifecycle, signed variance, reason; lists linked budgets' states the resource and the main returned fields, so an agent knows this retrieves schedule state for a PID. It does not, however, explicitly distinguish itself from close siblings like schedule_breakdown, schedule_changes, or get_project_budget, so an agent still has to infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The interpretation rules convey how to use the output (state population_scope, report signed changes, don't trust attributed_budget as a project cost), which is real usage guidance. But there is no explicit when-to-use-this-vs-siblings statement, so tool selection among schedule_breakdown/schedule_changes/get_project_budget is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.