Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PORTNoListen port. Default: 8080.8080
MCP_HOSTNoBind address. Default: 0.0.0.0.0.0.0.0
MCP_TRANSPORTNoTransport mode: stdio or streamable-http. Default: stdio.stdio
MCP_ALLOWED_HOSTSNoComma-separated Host allow-list. Default: unset.
MCP_ALLOWED_ORIGINSNoComma-separated Origin allow-list. Default: unset.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
search_datasetsA

Find datasets in the Education Data Portal. Returns each one's path template, description and years available; pass a template to describe_dataset for its variables and its summary call. All arguments are optional filters.

NOT COVERED by this portal at all: NAEP scores (see the NAEP Data Explorer), teacher salaries (BLS), private K-12 (limited; CRDC covers some), and curriculum data. Say so rather than searching repeatedly.

Args: level: "schools", "school-districts", or "college-university" source: "ccd", "ipeds", "crdc", "edfacts", "saipe", "scorecard", … topic: "enrollment", "directory", "finance", "discipline", … search: Words matched per-token against dataset paths and descriptions, not as a phrase — so drop specific terms like grade numbers ("8th") if a query returns nothing, since datasets rarely spell those out verbatim.

describe_datasetA

Inspect one dataset: every variable with its definition, data type, coded-value format, and whether it is filterable. Also returns the years covered, the source description, and equivalent R/Stata code.

This is where the [FILTER] marks come from — filtering on anything else returns UNFILTERED data rather than an error.

Args: path: Dataset path, template or filled in — both resolve to the same dataset: "schools/ccd/enrollment/{year}/{grade}/race/" or "schools/ccd/enrollment/2022/grade-99/race/" filterable_only: Show only the variables usable as filters

get_dataA

Fetch raw data records from one dataset path. For totals or averages across groups use get_summary instead — it aggregates server-side.

Results are COMPLETE or refused, never truncated, so counting and averaging over the rows returned is valid. A query matching over 10,000 rows is refused with its true size and how to narrow it. When one is too big, aggregate with get_summary, narrow to a state or district, or hand the user the bulk CSV link from the refusal or the R/Stata snippet from describe_dataset — for whole-country or long multi-year analysis those beat paging through calls.

COST: this hits a live API and a broad query can take 30s+. Filter before fetching rather than issuing many wide calls in parallel.

Args: path: A dataset path from search_datasets with every {placeholder} filled in — "schools/ccd/enrollment/2022/grade-99/race/". One year per call; a leading "/api/v1/" is optional. filters: "fips=11&charter=1". Only fields marked [FILTER] in describe_dataset work; others are rejected here rather than silently returning unfiltered data. Also takes "ordering=" to rank server-side: "ordering=-enrollment" largest first, "ordering=enrollment" smallest. Ranking sorts the whole result before paging, so a ranked query answers where an unranked one is refused as too large. fields: Comma-separated columns — "ncessch,school_name,enrollment". ALWAYS PASS THIS. These tables are 50-96 columns wide; requesting only what you need is typically an 8-17x reduction and is usually the difference between an answer and a refusal. add_labels: Decode coded values to labels (default True). Decoding is per variable, so meanings are FIELD-SPECIFIC — trust the decoded label over any assumption about what a raw code means. preview: Return a small labelled SAMPLE rather than a complete result. The rows are the API's first N by ID, NOT a random sample — never count, rank or average over them.

get_summaryA

Aggregate a dataset server-side: counts, sums, averages by group. Use this rather than get_data whenever the question is about totals ("how many schools per state", "total enrollment by race").

EVERY year comes back in one call — results are grouped by year on top of by, so a trend needs one call, never one per year. Filter years only to narrow a large result. Results are COMPLETE or refused. The API cannot rank aggregates, and refuses groupings that produce too many groups (by=leaid nationally, for instance).

var and by are drawn from two different pools — describe_dataset lists both for any dataset. Guessing costs a slow round trip; reading them does not.

COST: this hits a live API and a broad aggregation can take 30s+.

NO COUNTY AGGREGATION for schools or districts. Several datasets return county_code as a column, but it is neither filterable nor groupable, so county totals cannot be computed here — fetch the rows with get_data and aggregate them yourself, or say the portal does not support it. Do not retry with county in by.

Args: path: The SUMMARY path — no year, no {placeholders}, e.g. "schools/ccd/enrollment". describe_dataset prints the right one for any dataset. Some differ from the data path ("college-university/ipeds/fall-enrollment/race"). var: The measure to aggregate — a numeric, non-filter variable stat: sum, count, avg, min, max, median, stddev, or variance by: Comma-separated groupings — "fips", "fips,race". May also use variables from the source's directory ("school_level", "sector"). filters: "fips=6" — omit year to get every year; "year=2018,2019,2020" to restrict the range

lookup_codesA

Look up the code-to-label mapping for a coded variable — mainly to find a filter value for get_data ("California" -> fips=6).

Args: format_name: The "Format" shown for a variable in describe_dataset — "fips", "race", "sex", "school_level", "charter", … codes: Comma-separated codes to look up — "6,48". Omit for all values.

resolve_entityA

Resolve a school/district/college NAME to the ID used in get_data filters.

Returns CANDIDATES with their city and level, not one authoritative answer — names repeat, so the right row is the one whose city and level fit what the user meant. Type words ("Elementary", "High", "ISD") are ignored when matching, which is what lets natural phrasings reach the directory's abbreviations ("Lakewood Elementary" finds "LAKEWOOD EL").

Schools and districts require fips: without it this asks which state rather than guessing, since "Homestead High" exists in CA, WI, IN and FL.

COST: downloads a whole state's directory, so the first call for a state often takes 10-30s and later ones are cached. Resolve names in the same state together.

Args: name: Name to search for; distinctive words matter most. entity_type: "school", "district", or "college" fips: State FIPS code (6 = California). Required for schools and districts. See lookup_codes(format_name="fips"). max_results: Maximum candidates to return (default 15)

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct role: discover datasets, inspect schema, fetch raw rows, aggregate, decode codes, and resolve names to IDs. The potentially confusing get_data/get_summary pair is explicitly separated and cross-referenced.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun convention: describe_dataset, search_datasets, get_data, get_summary, lookup_codes, resolve_entity. No mixed casing or vague generic verbs appear.

Tool Count5/5

Six tools form a compact, non-redundant set that covers the read-only data-portal workflow well. Each tool earns its place, and the count is well within the ideal range for an agent to navigate comfortably.

Completeness5/5

The tool surface covers the full query lifecycle: find datasets, inspect variables and filter fields, resolve codes and entity names, fetch raw data, and aggregate server-side. Known unsupported operations are explicitly documented with workarounds, leaving no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues