MCP server providing tools for searching and analyzing NYC schools data, including school profiles, similarity analysis, correlation analysis, chart generation, and curated school lists.
The NYC School Explorer MCP server demonstrates solid definition quality with well-structured tool names following verb_noun conventions and comprehensive parameter schemas. All 6 tools have clear, descriptive documentation (100-250 chars) that explains purpose, use cases, and return data. Input schemas are properly defined with JSON Schema types and descriptions. However, there are notable gaps: output schemas are not explicitly documented in the visible code, error handling lacks recovery guidance, and some parameter descriptions could be more constraint-focused (e.g., 'year' accepts free-form strings instead of enum). The server shows strong naming consistency (search_, get_, compare_, find_, get_, analyze_) and parameter annotations, placing it solidly in the B/A- range.
Calculate correlation between metrics. IMPORTANT: Correlation does not imply causation. Always present with caveats.
Compare two or more schools side-by-side on key metrics.
Get educational content about metrics and methodology. Use when users ask "what does X mean?"
Find schools with similar characteristics for contextual comparison. Matches by ENI (±0.05) and enrollment (±20%) by default.
Generate data for visualization (scatter plot, bar chart, histogram, year-over-year change). CRITICAL FILTER REQUIREMENTS: 1. ALWAYS apply ALL filters the user specifies (borough, school type, ENI thresholds, etc.) 2. When charting school categories, ALWAYS filter to report_type="EMS" 3. When user says "exclude schools below economic need threshold" or similar, use min_eni=0.85 4. When user says "elementary schools", "middle schools", OR "elementary and middle schools" → use report_type="EMS" (they are combined in data and cannot be separated) 5. When user says "high schools" → use report_type="HS" 6. When user specifies a borough, ALWAYS include it in the filter object Example: For "Brooklyn elementary schools with ENI above 0.85": filter: { borough: "Brooklyn", report_type: "EMS", min_eni: 0.85 }
Output schemas not documented. While input schemas are detailed, the response structure for each tool is not explicitly documented in the visible code. This forces LLMs to infer output fields and risks misalignment when chaining tools.
'year' parameter in search_schools accepts free-form strings (default '2024-25') without enum constraint. LLMs may hallucinate invalid year formats. Should declare valid years as an enum or add regex pattern constraint.
'report_type' parameter across tools accepts values like 'EMS, HS, HST, D75, EC, or all' but is documented as free-form string in schema. Should be declared as enum for machine parsability and to prevent LLM hallucination of invalid types.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 9 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 48 | 2025-06-18+ | v1 |
Get curated lists of schools by category (high growth, high achievement, etc.). Default scope is Elementary/Middle Schools (EMS) where the methodology was validated.
Get detailed profile for a specific school including metrics across both years, trends, similar schools, location, budget, suspensions, and PTA data. If the exact DBN is not found, returns a "suggestions" array with up to 5 schools that match the search term. Use these suggestions to ask the user which school they meant.
Search NYC schools by various criteria. Returns schools with required context. CRITICAL: Apply ALL filters the user requests: - If user says "Brooklyn" → include borough="Brooklyn" - If user says "elementary schools" → include report_type="EMS" (elementary and middle are combined) - If user says "middle schools" → include report_type="EMS" (elementary and middle are combined) - If user says "elementary and middle schools" → include report_type="EMS" - If user says "high schools" → include report_type="HS" - If user says "high-poverty" or "above economic need threshold" → include min_eni=0.85 - Missing a user-specified filter is a serious error that returns incorrect results SCHOOL NAME SEARCH: Use the "query" parameter when users ask about schools by name. - "Tell me about Brooklyn Tech" → query="Brooklyn Tech" - "Find schools named Washington" → query="Washington" - If multiple matches found, present them to the user to clarify which school they mean. IMPORTANT USAGE GUIDANCE: - Results always include Economic Need (ENI) alongside performance metrics - Impact Score (student growth) is less confounded by poverty than Performance Score - Never present results as a ranking of "best" or "worst" schools - Always note sample size and data limitations when presenting findings
Error handling not visible in tool definitions. No guidance on what errors can occur, how to classify them (retryable, user-fixable, fatal), or recovery actions. This limits LLM ability to handle failures gracefully.
'category' parameter in search_schools is documented as 'Filter by category (high_growth, high_achievement, etc.)' but schema type is string without enum. Categories should be constrained to prevent invalid filters.
compare_schools accepts 'school_dbns' array but does not document acceptable array length (min/max items). Could cause performance issues if LLM passes 100+ schools. Should add minItems and maxItems constraints.
analyze_correlations metric parameters ('metric1', 'metric2') are underdocumented. Description lists 'impact_score, performance_score, eni, etc.' but does not enumerate all valid values. Should provide complete enum or discovery mechanism.