
Wraps the U.S. Department of Education College Scorecard API with nine tools that search institutions, compare outcomes, and pull program-level earnings data. You can filter schools by state, ownership, size, and acceptance rate, then drill into specific programs with median earnings at P25/P50/P75 one year post-graduation. The compare tool normalizes 2-5 schools side by side on costs, admissions, outcomes, or aid with percentile ranks computed in-flight. The value analysis tool runs parallel fetches for cost and earnings, then computes debt-to-earnings ratios and net price brackets the API doesn't expose directly. Includes CIP code lookup from embedded static data so you're not burning rate limits on taxonomy searches. Runs over stdio or streamable HTTP.
Search, compare, and analyze U.S. college data — costs, earnings, programs, and outcomes — via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://college-scorecard.caseyjhand.com/mcp
U.S. college data from the Department of Education College Scorecard API — costs, earnings, programs, and outcomes across roughly 6,500 Title IV institutions. Search and compare schools, look up program-level earnings by field of study, and compute ROI metrics like debt-to-earnings ratio from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| Tool | Description |
|---|---|
scorecard_search_schools | Search institutions by name, location, type, size, acceptance rate, and single-sex flags; sort by supported API fields. Returns core identity and cost metrics. |
scorecard_get_school | Full institutional profiles — costs, admissions, outcomes, aid, demographics, single-sex flags, and completion rates. |
scorecard_compare_schools | Normalized side-by-side comparison of 2–5 schools on a named topic. Returns metric values, ordinal ranks, and a comparison summary. |
scorecard_get_programs | Field-of-study programs at one school: median 1-year earnings, cumulative Stafford/Grad PLUS debt, and IPEDS awards in the two pooled debt-cohort years. |
scorecard_search_programs | Find programs by CIP and credential or keyword, retain degree identity, and rank earnings within each fetched school page. |
scorecard_get_earnings | Earnings of federally aided undergraduate entrants working and not enrolled, regardless of completion: 6/8/10-year medians, 6/10-year P25/P75, and non-male/male 6-year medians. |
scorecard_value_analysis | Workflow tool: parallel-fetches cost, debt, repayment, and earnings data, then computes ROI metrics — debt-to-earnings ratio and net price to earnings ratio. |
scorecard_lookup_cip | Search 186 curated NCES CIP 2020 four-digit groups by code, keyword, or verified descendant alias. Served offline. |
scorecard_list_fields | Search the Scorecard field catalog by keyword. Returns matching field paths, descriptions, data types, and sort support. Use before passing custom fields parameters. |
| Resource | Description |
|---|---|
scorecard://school/{id} | Institutional profile by unit ID — injectable context for school-specific conversations |
scorecard://programs/{id} | Program-level outcomes for a school |
All resource data is also reachable via tools. Use scorecard_search_schools or scorecard_get_school to discover school IDs before constructing resource URIs.
| Prompt | Description |
|---|---|
scorecard_compare_prompt | Structures a multi-school comparison analysis using Scorecard data |
scorecard_search_schools toolper_page is capped at 100 with zero-indexed page. State lists accept WA,CA and case variants. ZIP-only queries use the provider default radius; ZIP+4 and nonnegative decimal radii (bare miles, mi, or km) are supported. Reversed range bounds normalize to ascending order.sort forwards a supported API expression such as latest.cost.avg_net_price.overall:asc (:desc reverses it). men_only and women_only accept true or false; omission includes unknown flags, while false selects only explicit zero values.scorecard_get_school toolmissing_ids identifies processed IDs without records, and unprocessed_ids identifies unchecked excess.fields returns real ID/name plus selected_fields containing requested JSON values, including null, zero, false, and nested arrays. Program leaf projections retain the provider's parent subtree under latest.programs.cip_4_digit, preserving sparse rows and array positions; absent_fields lists requested paths omitted from that response. Unrequested profile metrics are omitted.school.minority_serving.historically_black; HBCU and single-sex flags preserve true/false when known and remain unknown when absent/null.scorecard_compare_schools toolcosts, admissions, outcomes, or aid.availability distinguishes available, unavailable with unknown cause, and confirmed privacy suppression.scorecard_get_programs toolcredential_level, and minimum earnings filters.earnings_availability is available, unavailable, or privacy_suppressed; zero is available, null/absence has unknown cause, and only explicit provider privacy markers set suppressed. suppressed_count and unavailable_count distinguish those populations.median_debt is completers' cumulative Stafford/Grad PLUS borrowing across attended institutions at the same academic level. ipeds_awards_year1 and ipeds_awards_year2 count awards in each year of the pooled debt cohort, not enrollment or unique students.scorecard_search_programs toolcredential_level, state, ownership, net price, earnings, and debt filters; zero-indexed page and per_page (up to 100) paginate schools, so returned program rows may exceed per_page. CIP and credential selectors apply together upstream before pagination; credential codes are 1–8 and 99, and unknown integer selectors may return no matches.credential_level / credential_title, retaining separate credentials and future numeric credential levels; missing identity fields stay absent. Available earnings sort first; availability states and counts have the same meaning as in scorecard_get_programs.min_earnings filters locally; totals and pagination remain upstream school counts before local filtering. Earnings/debt thresholds are inclusive and exclude unknown values. Debt and award fields have the same meanings as in scorecard_get_programs.scorecard_get_earnings toolyears from 1996–2025. These are file vintages, not entry years; valid files without observations succeed. Omit years or pass [] for snapshot only.current_availability and trend[].availability classify each supported metric; aggregate suppressed requires every current metric to carry an explicit privacy marker. Null and omitted values do not prove suppression.current_context and trend[].context give per-metric data_file_year, verified academic entry_cohorts, calendar measurement_years, and inflation dollar_year. Metadata comes from the official cohort maps; unknown parts are omitted. Values retain the provider's dollar basis, so cross-vintage comparisons require checking it. Each requested file adds six- and ten-year medians without extra requests.scorecard_value_analysis toolfamily_income selects the applicable net price bracket ($0–30k, $30k–48k, $48k–75k, $75k–110k, or $110k+).effective_net_price discloses the price used, and net_price_basis is income_bracket, overall, or unavailable. A missing bracket preserves requested family_income / applicable_income_bracket and explains the established overall-price fallback in data_notes. Zero estimates remain valid; ratios require positive annual earnings.scorecard_lookup_cip tool11.07 and undotted 1107 queries are equivalent. Returns exact group titles and family identities from 186 current NCES CIP 2020 four-digit groups; verified six-digit descendant names act as keyword aliases, returning their canonical group. This curated set is a subset of the full taxonomy.scorecard_list_fields toolfields to scorecard_get_school.tip flags results containing unsortable fields.scorecard://school/{id} resourceapplication/json — identity, cost, admissions, outcomes, aid, and completion dataid is the school unit ID (integer as string) from scorecard_search_schoolslist returns a handful of example school URIs; use scorecard_search_schools to discover othersscorecard://programs/{id} resourceapplication/json — CIP code, title, credential level, 1-year earnings, cumulative Stafford/Grad PLUS debt, and ipeds_awards_year1 / ipeds_awards_year2 with the same meanings as the program tools; missing metrics are nullid is the school unit ID from scorecard_search_schoolslist returns a handful of example school URIs; use scorecard_search_schools to discover othersscorecard_compare_prompt promptschool_names (comma-separated list) and focus (costs | outcomes | programs), both requiredscorecard_compare_schools, profiles, and value analysis. Programs sequence school discovery, CIP lookup, and scorecard_get_programs per school; compare matching credentials using returned earnings, cumulative debt, and IPEDS awards in the two pooled debt-cohort years. Missing values and award-year dates remain unknown.Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
College Scorecard-specific:
fields override for custom queriesAgent-friendly output:
PS / PrivacySuppressed provider markers. Confirmed privacy suppression does not identify its particular cause.scorecard_value_analysis — agents can verify arithmetic and branch on computed values, not raw numbersscorecard_compare_schools place each school's metric values within the comparison setscorecard_list_fields before choosing a sort expression. Six-year earnings does not support API sorting. Program earnings ordering applies within each fetched school page.api_error; cancellation remains RequestCancelled.A public instance is available at https://college-scorecard.caseyjhand.com/mcp — no installation required. No API key needed; the instance supplies its own. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"college-scorecard-mcp-server": {
"type": "streamable-http",
"url": "https://college-scorecard.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file. See api.data.gov/signup for a free API key.
{
"mcpServers": {
"college-scorecard-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/college-scorecard-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"SCORECARD_API_KEY": "your-api-key"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"college-scorecard-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/college-scorecard-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"SCORECARD_API_KEY": "your-api-key"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"college-scorecard-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "SCORECARD_API_KEY=your-api-key",
"ghcr.io/cyanheads/college-scorecard-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 SCORECARD_API_KEY=... bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/college-scorecard-mcp-server.git
cd college-scorecard-mcp-server
bun install
cp .env.example .env
# edit .env and set SCORECARD_API_KEY
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
SCORECARD_API_KEY | Required. API key from api.data.gov. 1,000 req/hour rate limit. | — |
MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio |
MCP_HTTP_PORT | HTTP server port | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path where the MCP server is mounted | /mcp |
MCP_PUBLIC_URL | Public origin override for TLS-terminating reverse-proxy deployments | none |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. The server declares stateless in code; an explicit env value overrides it. | stateless |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.) | info |
MCP_GC_PRESSURE_INTERVAL_MS | Opt-in forced-GC pressure loop (ms, Bun only). Try 60000 if heap growth is observed under sustained HTTP load. | 0 (disabled) |
LOGS_DIR | Directory for log files (Node.js only) | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation | false |
See .env.example for the full list of optional overrides.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t college-scorecard-mcp-server .
docker run --rm -e SCORECARD_API_KEY=your-key -p 3010:3010 college-scorecard-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/college-scorecard-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools/resources/prompts and inits services. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools | Tool definitions (*.tool.ts). Nine tools across search, profile, programs, earnings, and analysis. |
src/mcp-server/resources | Resource definitions. School profile and program outcomes resources. |
src/mcp-server/prompts | Prompt definitions. Multi-school comparison prompt. |
src/services | ScorecardService — fetch wrapper with retry, field selection, and pagination against the College Scorecard API. |
tests/ | Unit and integration tests mirroring src/. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagecreateApp() arrays in src/index.tsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
SCORECARD_API_KEY*Required API key for the College Scorecard API. Free registration at https://api.data.gov/signup/. Rate limit: 1,000 requests/hour.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.