Skip to main content
Glama

get_education_data

Retrieve structured education data from the Urban Institute's API for schools, districts, and universities by specifying level, source, and topic parameters.

Instructions

Retrieve education data from the Urban Institute's Education Data API

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
levelYesAPI data level to query (e.g., 'schools', 'school-districts', 'college-university')
sourceYesAPI data source to query (e.g., 'ccd', 'ipeds', 'crdc')
topicYesAPI data topic to query (e.g., 'enrollment', 'directory')
subtopicNoOptional list of grouping parameters (e.g., ['race', 'sex'])
filtersNoOptional query filters (e.g., {year: 2008, grade: [9,10,11,12]})
add_labelsNoAdd variable labels when applicable (default: false)
limitNoLimit the number of results (default: 100)

Implementation Reference

  • The handler for the 'get_education_data' tool. It extracts parameters from the request, validates required fields (level, source, topic), constructs the API URL from https://educationdata.urban.org/api/v1 with subtopics, filters, limits, and labels, makes an axios GET request with mode=R, returns the JSON data as text content, and handles API errors like 404, 400, 413.
    case "get_education_data": { const { level, source, topic, subtopic, filters, add_labels, limit = 100 } = request.params.arguments || {}; if (!level || !source || !topic) { throw new McpError( ErrorCode.InvalidParams, "Missing required parameters: level, source, and topic are required" ); } try { // Construct the API URL let url = `${API_BASE_URL}/${level}/${source}/${topic}`; // Add subtopics if provided if (subtopic && Array.isArray(subtopic) && subtopic.length > 0) { url += `/${subtopic.join("/")}`; } // Add query parameters const queryParams = new URLSearchParams(); queryParams.append("limit", String(limit)); if (add_labels) { queryParams.append("add_labels", "true"); } // Add filters if (filters && typeof filters === "object") { Object.entries(filters).forEach(([key, value]) => { if (Array.isArray(value)) { queryParams.append(key, value.join(",")); } else { queryParams.append(key, String(value)); } }); } // Add mode=R to match the R package behavior queryParams.append("mode", "R"); // Make the API request const response = await axios.get(`${url}?${queryParams.toString()}`); // Return the results return { content: [ { type: "text", text: JSON.stringify(response.data.results || response.data, null, 2) } ] }; } catch (error) { if (axios.isAxiosError(error)) { const statusCode = error.response?.status; const message = error.response?.data?.message || error.message; if (statusCode === 404) { throw new McpError( ErrorCode.InvalidRequest, `Endpoint not found: ${level}/${source}/${topic}` ); } else if (statusCode === 400) { throw new McpError( ErrorCode.InvalidParams, `API error: ${message}` ); } else if (statusCode === 413) { throw new McpError( ErrorCode.InvalidParams, "Your requested query returned too many records. Consider limiting the scope of your query." ); } throw new McpError( ErrorCode.InternalError, `API error (${statusCode}): ${message}` ); } throw new McpError( ErrorCode.InternalError, `Error: ${error instanceof Error ? error.message : String(error)}` ); } }
  • Input schema for the get_education_data tool, defining properties like level, source, topic (required), subtopic, filters, add_labels, limit with types and descriptions.
    inputSchema: { type: "object", properties: { level: { type: "string", description: "API data level to query (e.g., 'schools', 'school-districts', 'college-university')" }, source: { type: "string", description: "API data source to query (e.g., 'ccd', 'ipeds', 'crdc')" }, topic: { type: "string", description: "API data topic to query (e.g., 'enrollment', 'directory')" }, subtopic: { type: "array", items: { type: "string" }, description: "Optional list of grouping parameters (e.g., ['race', 'sex'])" }, filters: { type: "object", description: "Optional query filters (e.g., {year: 2008, grade: [9,10,11,12]})" }, add_labels: { type: "boolean", description: "Add variable labels when applicable (default: false)" }, limit: { type: "number", description: "Limit the number of results (default: 100)" } }, required: ["level", "source", "topic"] }
  • src/index.ts:197-237 (registration)
    Registration of the get_education_data tool in the ListToolsRequestSchema handler, including name, description, and input schema.
    { name: "get_education_data", description: "Retrieve education data from the Urban Institute's Education Data API", inputSchema: { type: "object", properties: { level: { type: "string", description: "API data level to query (e.g., 'schools', 'school-districts', 'college-university')" }, source: { type: "string", description: "API data source to query (e.g., 'ccd', 'ipeds', 'crdc')" }, topic: { type: "string", description: "API data topic to query (e.g., 'enrollment', 'directory')" }, subtopic: { type: "array", items: { type: "string" }, description: "Optional list of grouping parameters (e.g., ['race', 'sex'])" }, filters: { type: "object", description: "Optional query filters (e.g., {year: 2008, grade: [9,10,11,12]})" }, add_labels: { type: "boolean", description: "Add variable labels when applicable (default: false)" }, limit: { type: "number", description: "Limit the number of results (default: 100)" } }, required: ["level", "source", "topic"] } },
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ckz/edu_data_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server