Skip to main content
Federal data from IPEDS & College Scorecard

GradFax MCP server

Cited college data for AI agents.

An AI assistant that supports MCP can use this server to look up U.S. colleges and get back figures from IPEDS and the U.S. Department of Education College Scorecard, and each reply lists its government sources.

Read-only. Seven tools. Every successful answer lists its government sources.

Endpoint

POST https://www.gradfax.com/api/mcp

MCP streamable HTTP, stateless, JSON replies. Authenticated with a GradFax API key.

Get a key

Sign in to GradFax and create a key at /my-gradfax/api-keys. Your key looks like the placeholder gf_live_YOUR_KEY in the examples below. The same key works for this server and for the REST API.

  • 2,000 calls per month, free. The REST API draws on the same count. Limits reset on the 1st of each month, UTC. A key created on the 29th, 30th or 31st may get its first reset a month later than that.
  • What counts. Each tool call counts as 1. The handshake (initialize, ping, tools/list) does not count. Requests refused before they run, for bad arguments, a bad key or a burst limit, do not count either.
  • Burst limits, per key. Tool calls: 10 in 5 seconds and 60 in a minute. Handshake requests are counted separately under the same two limits. Over a limit you get HTTP 429, so wait a moment and retry.
  • Account ceiling: 5,000 calls per month. An account can hold up to 10 keys. Without a ceiling, each free key would bring its own 2,000. All of one account's free keys together are capped at 5,000 calls a month. After that, tool calls on its free keys get 429 until the month resets. The ceiling applies to free keys.
  • Everything is free. There are no paid plans. If you need more than 2,000 calls a month, email josh@gradfax.com.

Connect

Every example uses a placeholder. Replace gf_live_YOUR_KEY with your own key.

Claude Code

One command

claude mcp add --transport http gradfax https://www.gradfax.com/api/mcp \
  --header "X-API-Key: gf_live_YOUR_KEY"

The flags match claude mcp add --help in Claude Code.

Other MCP clients

Any client that supports HTTP servers with custom headers can connect. Send the key in the X-API-Key header. Many clients can only set an Authorization header, and that works too:

Authorization: Bearer gf_live_YOUR_KEY

A common config shape

{
  "mcpServers": {
    "gradfax": {
      "url": "https://www.gradfax.com/api/mcp",
      "headers": {
        "X-API-Key": "gf_live_YOUR_KEY"
      }
    }
  }
}

Field names differ between clients (some also want a transport type). Check your client's documentation.

Claude Desktop, through the mcp-remote bridge

Not tested by GradFax. This format is reported by community docs. Check your client's documentation.
{
  "mcpServers": {
    "gradfax": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://www.gradfax.com/api/mcp",
        "--header",
        "X-API-Key:gf_live_YOUR_KEY"
      ]
    }
  }
}

Cursor

Not tested by GradFax. This format is reported by community docs. Check your client's documentation. Put it in ~/.cursor/mcp.json.
{
  "mcpServers": {
    "gradfax": {
      "url": "https://www.gradfax.com/api/mcp",
      "headers": {
        "X-API-Key": "gf_live_YOUR_KEY"
      }
    }
  }
}

Check your key from a terminal

Listing the tools is part of the handshake, so it does not use any of your monthly calls.

curl -s https://www.gradfax.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "X-API-Key: gf_live_YOUR_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Keep your key private. Never paste it into a chat or commit it to a repository. A command that holds the key is saved in your shell history, so prefer an environment variable or your client's own secret storage. If a key leaks, GradFax can disable it.

The seven tools

All seven only read data. Inputs are strict: an unknown field, a wrong type or an out-of-range value is refused.

search_schools

Filter colleges and get one page of matches, largest enrollment first, with the total that matched.

All optional: state (two-letter code), control (public, private_nonprofit or for_profit), max_tuition_out_of_state (0 to 100,000 dollars), min_acceptance_rate and max_acceptance_rate (percent, 0 to 100), hbcu (true or false), min_enrollment and max_enrollment (0 to 500,000), name_contains (2 to 80 characters), limit (1 to 25, default 10), offset (0 to 5,000).

get_school_profile

One college: location, control, admissions, test scores, cost, net price, graduation and retention, earnings and debt, with links to its IPEDS and College Scorecard pages.

Exactly one of unitid (the 6-digit IPEDS id, 100000 to 999999) or slug (the GradFax school slug, as in gradfax.com/school/the-slug).

compare_schools

Profiles for 2 to 4 colleges, in the order you give them, for side by side comparison. Ids with no record are listed in missing.

Required: unitids (2 to 4 different IPEDS ids).

get_school_programs

The program names a college reports to the College Scorecard (4-digit CIP titles). Names only, no per-program earnings.

Required: unitid. Returns up to 300 names. program_count gives the full number, and truncated is true if names were cut. The program list was generated on 2026-03-17.

get_net_price_by_income

What families at each income level paid on average after grants and scholarships, from IPEDS, plus the overall average net price and the sticker tuition. Only income bands IPEDS reported are returned (under $30k, $30k to $48k, $48k to $75k, $75k to $110k, over $110k).

Required: unitid. A zero or negative IPEDS value is returned as reported, with aid_covers_full_cost set to true.

find_schools_by_description

Turns a short plain description, such as nursing schools in Texas, into filters and runs them. It uses simple built-in rules and no AI service. It applies only state, maximum tuition, public or private nonprofit, size (large is 15,000 or more students, small is 5,000 or fewer) and major. Private means private nonprofit. A described major is matched to program names by text, and one major can stand for several related program names, so it can match more schools than the word alone suggests. Anything else it noticed is listed in not_applied. Questions, comparisons and negations are declined. It often answers abstained with the hint to use search_schools with filters. That is the expected answer for those descriptions, not an error.

Required: description (3 to 300 characters). Optional: limit (1 to 25, default 10). With a major, total_is_lower_bound tells you when the total may undercount.

get_data_sources

Where the data comes from: the datasets and their links, the data years on file, and the source of every field the tools return.

No inputs.

What comes back

Every successful answer has the same four parts. A not-found or unavailable answer is a tool error with no sources, and it still counts as a call.

{ "data": ..., "attribution": "...", "sources": [ ... ], "truncated": false }
  • data: the tool's result.
  • attribution: always this sentence, word for word:Data from IPEDS (NCES) and the U.S. Department of Education College Scorecard, via GradFax (gradfax.com)
  • sources: each dataset used, with its name, link and data_year as stored on the school records. It is one year when every record agrees, a range when they differ, and null when there is none.
  • truncated: true when a cap cut something your request asked for. Paging is not truncation: total tells you how many matched.

Caps: 25 schools per call, 300 program names, and 64 KB per reply. If a list would make an answer too large, the list is shortened and truncated is true. Each successful reply carries the envelope both as structured content and as JSON text, for older clients.

A figure the government source does not have comes back as null. A recorded 0 for acceptance, retention or graduation rate also comes back as null, because those zeros stand in for missing values rather than real rates. Acceptance rate is a percent from 0 to 100.

Left out on purpose, because they have no government source: mascot and primary_color. GradFax's own fit scores are not returned either.

Abridged example: search_schools, limit 1

The call arguments, then the data part of the reply. Text in angle brackets stands for a real value. This example shows the shape only and contains no school's numbers.

{ "name": "search_schools", "arguments": { "state": "TX", "limit": 1 } }
{
  "data": {
    "schools": [
      {
        "unitid": 123456,
        "name": "<institution name>",
        "city": "<city>",
        "state": "<2-letter code>",
        "control": "<public | private_nonprofit | for_profit>",
        "acceptance_rate": "<percent 0 to 100, or null>",
        "enrollment": "<number, or null>",
        "tuition_in_state": "<dollars, or null>",
        "tuition_out_of_state": "<dollars, or null>",
        "avg_net_price_overall": "<dollars, or null>",
        "grad_rate_4yr": "<number, or null>",
        "earnings_10yr": "<dollars, or null>",
        "median_debt": "<dollars, or null>"
      }
    ],
    "total": "<how many schools matched>",
    "limit": 1,
    "offset": 0
  },
  "attribution": "Data from IPEDS (NCES) and the U.S. Department of Education College Scorecard, via GradFax (gradfax.com)",
  "sources": [
    {
      "name": "IPEDS (Integrated Postsecondary Education Data System), NCES",
      "url": "https://nces.ed.gov/ipeds/",
      "data_year": "<year as stored>"
    },
    {
      "name": "College Scorecard, U.S. Department of Education",
      "url": "https://collegescorecard.ed.gov/",
      "data_year": "<year as stored>"
    }
  ],
  "truncated": false
}

Safety and limits

  • Read-only. There are no write tools. The only thing a call changes is your own usage count.
  • No personal data. No tool reads or returns user accounts, profiles, saved schools, payments, anyone's keys or GradFax's request logs. The data is institution-level figures and program names.
  • Strict validation. Arguments are checked against the published schema before anything runs. Error messages are fixed text and never repeat your input back.
  • Small requests only. Requests over 16 KB are refused. One JSON-RPC message per request, batches are not supported.
  • For agents and command-line clients, not websites. Requests that carry a browser Origin header are refused, and no cross-origin (CORS) access is offered. Call it from a server, a terminal or an MCP client, not from a web page.
  • Data, not a quote or advice. The net price tool adds this note:IPEDS averages, not a personal quote. Merit aid and individual circumstances change your real number.

If a request is refused

  • 400 Malformed JSON, a batch array, a request that is not valid JSON-RPC ("Invalid request"), or an unsupported MCP-Protocol-Version header.
  • 401 Key missing, wrong or switched off. A switched-off key reads the same as a wrong one.
  • 403 The request carried a browser Origin header, or was addressed to a host that is not GradFax.
  • 405 Any method other than POST. There is no streaming endpoint.
  • 406 and 415 Accept must list application/json and text/event-stream. Content-Type must be application/json.
  • 404 The server is switched off.
  • 413 Request body over 16 KB.
  • 429 A burst limit, your monthly limit, the account ceiling, or more than 30 rejected keys from one IP address in 10 minutes.
  • 500 Internal error. The message is fixed text with no detail.
  • 503 GradFax could not finish checking the key. Retry shortly. This says nothing about your key.

Arguments that fail validation come back as a JSON-RPC invalid params error (code -32602) with a short fixed message. If a tool cannot read the data it answers with a tool error that says the data is temporarily unavailable.

Terms

This server follows the same stance as the REST API. API access, including this MCP server, does not grant commercial, resale, redistribution or white-label rights. Any such rights require a separate written agreement signed by GradFax that expressly grants them. See the Terms and the licensing notes on /developers.

Data sources

If you show these figures to people, please keep the attribution with them. The server tells connected assistants the same thing: every successful result lists its sources, and they should cite them when they use a number. Call get_data_sources to see the source of every field.

More