@cyanheads/college-scorecard-mcp-server 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +14 -6
- package/CLAUDE.md +14 -6
- package/README.md +29 -24
- package/changelog/0.6.x/0.6.0.md +34 -0
- package/changelog/template.md +10 -3
- package/dist/data/field-catalog.d.ts.map +1 -1
- package/dist/data/field-catalog.js +60 -23
- package/dist/data/field-catalog.js.map +1 -1
- package/dist/data/repayment-context.d.ts +74 -0
- package/dist/data/repayment-context.d.ts.map +1 -0
- package/dist/data/repayment-context.js +69 -0
- package/dist/data/repayment-context.js.map +1 -0
- package/dist/mcp-server/institution-context.d.ts +14 -1
- package/dist/mcp-server/institution-context.d.ts.map +1 -1
- package/dist/mcp-server/institution-context.js +24 -1
- package/dist/mcp-server/institution-context.js.map +1 -1
- package/dist/mcp-server/program-format.d.ts +25 -0
- package/dist/mcp-server/program-format.d.ts.map +1 -0
- package/dist/mcp-server/program-format.js +71 -0
- package/dist/mcp-server/program-format.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/compare.prompt.js +4 -4
- package/dist/mcp-server/prompts/definitions/compare.prompt.js.map +1 -1
- package/dist/mcp-server/repayment.d.ts +107 -0
- package/dist/mcp-server/repayment.d.ts.map +1 -0
- package/dist/mcp-server/repayment.js +146 -0
- package/dist/mcp-server/repayment.js.map +1 -0
- package/dist/mcp-server/resources/definitions/programs-page.resource.d.ts +3 -3
- package/dist/mcp-server/resources/definitions/programs-page.resource.js +3 -3
- package/dist/mcp-server/resources/definitions/programs-page.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/programs.resource.d.ts +3 -3
- package/dist/mcp-server/resources/definitions/programs.resource.js +3 -3
- package/dist/mcp-server/resources/definitions/programs.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/school.resource.d.ts +3 -3
- package/dist/mcp-server/resources/definitions/school.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/school.resource.js +6 -5
- package/dist/mcp-server/resources/definitions/school.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-schools.tool.d.ts +4 -3
- package/dist/mcp-server/tools/definitions/compare-schools.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-schools.tool.js +70 -40
- package/dist/mcp-server/tools/definitions/compare-schools.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-earnings.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/get-earnings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-earnings.tool.js +9 -8
- package/dist/mcp-server/tools/definitions/get-earnings.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-programs.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/get-programs.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-programs.tool.js +15 -21
- package/dist/mcp-server/tools/definitions/get-programs.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-school.tool.d.ts +47 -3
- package/dist/mcp-server/tools/definitions/get-school.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-school.tool.js +37 -7
- package/dist/mcp-server/tools/definitions/get-school.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/list-fields.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/list-fields.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-cip.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-cip.tool.js +25 -11
- package/dist/mcp-server/tools/definitions/lookup-cip.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-programs.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/search-programs.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-programs.tool.js +26 -21
- package/dist/mcp-server/tools/definitions/search-programs.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-schools.tool.d.ts +14 -3
- package/dist/mcp-server/tools/definitions/search-schools.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-schools.tool.js +51 -9
- package/dist/mcp-server/tools/definitions/search-schools.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/value-analysis.tool.d.ts +50 -4
- package/dist/mcp-server/tools/definitions/value-analysis.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/value-analysis.tool.js +53 -18
- package/dist/mcp-server/tools/definitions/value-analysis.tool.js.map +1 -1
- package/dist/services/scorecard/input-normalization.d.ts.map +1 -1
- package/dist/services/scorecard/input-normalization.js +2 -1
- package/dist/services/scorecard/input-normalization.js.map +1 -1
- package/dist/services/scorecard/scorecard-service.d.ts +1 -1
- package/dist/services/scorecard/scorecard-service.d.ts.map +1 -1
- package/dist/services/scorecard/scorecard-service.js +19 -2
- package/dist/services/scorecard/scorecard-service.js.map +1 -1
- package/dist/services/scorecard/types.d.ts +16 -0
- package/dist/services/scorecard/types.d.ts.map +1 -1
- package/dist/services/scorecard/types.js +7 -1
- package/dist/services/scorecard/types.js.map +1 -1
- package/package.json +5 -5
- package/server.json +3 -3
- package/skills/college-scorecard-guide/SKILL.md +4 -4
package/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** college-scorecard-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
6
|
-
**Engines:** Bun ≥1.4.
|
|
4
|
+
**Version:** 0.6.0
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.22`
|
|
6
|
+
**Engines:** Bun ≥1.4.4, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.4.0
|
|
8
8
|
**Zod:** ^4.6.7
|
|
9
9
|
|
|
@@ -185,6 +185,12 @@ Institution earnings cover federally aided undergraduate entrants working and no
|
|
|
185
185
|
|
|
186
186
|
`readMetric` distinguishes numbers (including zero), unknown-cause null/absence, and explicit `PS` / `PrivacySuppressed` markers. Suppression flags/counts require the latter; unexpected values are provider contract failures. CIP lookup covers all current NCES CIP 2020 four-digit groups, with exact group/family titles and verified descendant aliases. Program search applies CIP × credential together upstream before school pagination; totals remain school-level.
|
|
187
187
|
|
|
188
|
+
`src/data/repayment-context.ts` holds dictionary provenance for discontinued declining-balance rates and the separate two- and four-year undergraduate federal Direct Loan borrower statuses. The three-year declining-balance rate uses the 2016–17 file. Profiles and value analysis retain each borrower-status horizon's OPEID6 scope, denominator when available, and reported decimal or bin. Only point estimates carry numeric values. Unsupported status rates yield an unavailable value and a notice. Comparison ranks use the historical three-year rate.
|
|
189
|
+
|
|
190
|
+
`school.operating` is current operating certification. Actual closure requires separate evidence. School search applies certification, HBCU, locale, price, and completion filters upstream before pagination. Use observed provider support for catalog sort flags, including unsortable pooled full-time retention projections.
|
|
191
|
+
|
|
192
|
+
Program tool text leads with completion earnings and renders legacy highest-credential values separately. School comparison leaves descriptive metrics, singleton results, shared OPEID6 outcomes, and mixed price periods unranked. Negative dollar selectors normalize to zero with a notice. Earnings vintages deduplicate in caller order. Six-digit CIP lookup resolves to the four-digit group used by program selectors.
|
|
193
|
+
|
|
188
194
|
---
|
|
189
195
|
|
|
190
196
|
## Context
|
|
@@ -356,7 +362,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
356
362
|
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
357
363
|
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
358
364
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
359
|
-
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
365
|
+
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity, `.mcpbignore` coverage, plugin manifests, the published `skills/` tree (run by devcheck) |
|
|
360
366
|
| `bun run list-skills` | Print the skill registry |
|
|
361
367
|
| `bun run tree` | Generate directory structure doc |
|
|
362
368
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
@@ -376,7 +382,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
376
382
|
|
|
377
383
|
## Bundling
|
|
378
384
|
|
|
379
|
-
`npm run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips four classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs
|
|
385
|
+
`npm run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips four classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs — `framework-skills/`, `skills/`, `.claude/`, `.agents/`, `AGENTS.md`, and `CLAUDE.md` at a package's root, and `SKILL.md` anywhere (a `skills/` deeper in a package is runtime code and stays); platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on; node-gyp build output beside a `binding.gyp` (`config.gypi`, Makefiles, `obj.target/`, `.deps/`, object files and debug symbols), which records the packing machine's paths — compiled `*.node` addons stay; and build-only package files — the framework's `changelog/`, `scripts/`, `templates/`, and config bases (`biome.json`, `vitest.config.base.mjs`, `config/tsconfig.base.json`), and `better-sqlite3`'s `deps/` and `src/` C sources. A server using DataCanvas therefore ships a portable bundle without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so canvas tools report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
380
386
|
|
|
381
387
|
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
382
388
|
|
|
@@ -447,4 +453,6 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
447
453
|
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
448
454
|
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
449
455
|
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
450
|
-
- [ ] `
|
|
456
|
+
- [ ] Any new root dev path has a root-anchored line in `.mcpbignore` and passes `bun run bundle` and `lint:packaging`
|
|
457
|
+
- [ ] Field-test verified every gate and identifier claim in the published `skills/college-scorecard-guide` against live tool behavior
|
|
458
|
+
- [ ] `bun run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** college-scorecard-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
6
|
-
**Engines:** Bun ≥1.4.
|
|
4
|
+
**Version:** 0.6.0
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.22`
|
|
6
|
+
**Engines:** Bun ≥1.4.4, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.4.0
|
|
8
8
|
**Zod:** ^4.6.7
|
|
9
9
|
|
|
@@ -185,6 +185,12 @@ Institution earnings cover federally aided undergraduate entrants working and no
|
|
|
185
185
|
|
|
186
186
|
`readMetric` distinguishes numbers (including zero), unknown-cause null/absence, and explicit `PS` / `PrivacySuppressed` markers. Suppression flags/counts require the latter; unexpected values are provider contract failures. CIP lookup covers all current NCES CIP 2020 four-digit groups, with exact group/family titles and verified descendant aliases. Program search applies CIP × credential together upstream before school pagination; totals remain school-level.
|
|
187
187
|
|
|
188
|
+
`src/data/repayment-context.ts` holds dictionary provenance for discontinued declining-balance rates and the separate two- and four-year undergraduate federal Direct Loan borrower statuses. The three-year declining-balance rate uses the 2016–17 file. Profiles and value analysis retain each borrower-status horizon's OPEID6 scope, denominator when available, and reported decimal or bin. Only point estimates carry numeric values. Unsupported status rates yield an unavailable value and a notice. Comparison ranks use the historical three-year rate.
|
|
189
|
+
|
|
190
|
+
`school.operating` is current operating certification. Actual closure requires separate evidence. School search applies certification, HBCU, locale, price, and completion filters upstream before pagination. Use observed provider support for catalog sort flags, including unsortable pooled full-time retention projections.
|
|
191
|
+
|
|
192
|
+
Program tool text leads with completion earnings and renders legacy highest-credential values separately. School comparison leaves descriptive metrics, singleton results, shared OPEID6 outcomes, and mixed price periods unranked. Negative dollar selectors normalize to zero with a notice. Earnings vintages deduplicate in caller order. Six-digit CIP lookup resolves to the four-digit group used by program selectors.
|
|
193
|
+
|
|
188
194
|
---
|
|
189
195
|
|
|
190
196
|
## Context
|
|
@@ -356,7 +362,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
356
362
|
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
357
363
|
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
358
364
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
359
|
-
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
365
|
+
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity, `.mcpbignore` coverage, plugin manifests, the published `skills/` tree (run by devcheck) |
|
|
360
366
|
| `bun run list-skills` | Print the skill registry |
|
|
361
367
|
| `bun run tree` | Generate directory structure doc |
|
|
362
368
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
@@ -376,7 +382,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
376
382
|
|
|
377
383
|
## Bundling
|
|
378
384
|
|
|
379
|
-
`npm run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips four classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs
|
|
385
|
+
`npm run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips four classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs — `framework-skills/`, `skills/`, `.claude/`, `.agents/`, `AGENTS.md`, and `CLAUDE.md` at a package's root, and `SKILL.md` anywhere (a `skills/` deeper in a package is runtime code and stays); platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on; node-gyp build output beside a `binding.gyp` (`config.gypi`, Makefiles, `obj.target/`, `.deps/`, object files and debug symbols), which records the packing machine's paths — compiled `*.node` addons stay; and build-only package files — the framework's `changelog/`, `scripts/`, `templates/`, and config bases (`biome.json`, `vitest.config.base.mjs`, `config/tsconfig.base.json`), and `better-sqlite3`'s `deps/` and `src/` C sources. A server using DataCanvas therefore ships a portable bundle without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so canvas tools report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
380
386
|
|
|
381
387
|
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
382
388
|
|
|
@@ -447,4 +453,6 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
447
453
|
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
448
454
|
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
449
455
|
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
450
|
-
- [ ] `
|
|
456
|
+
- [ ] Any new root dev path has a root-anchored line in `.mcpbignore` and passes `bun run bundle` and `lint:packaging`
|
|
457
|
+
- [ ] Field-test verified every gate and identifier claim in the published `skills/college-scorecard-guide` against live tool behavior
|
|
458
|
+
- [ ] `bun run devcheck` passes
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/college-scorecard-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/college-scorecard-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -35,13 +35,13 @@ US college data from the Department of Education College Scorecard: costs, earni
|
|
|
35
35
|
|
|
36
36
|
| Tool | Description |
|
|
37
37
|
|:---|:---|
|
|
38
|
-
| `scorecard_search_schools` | Search institutions by
|
|
39
|
-
| `scorecard_get_school` |
|
|
40
|
-
| `scorecard_compare_schools` |
|
|
38
|
+
| `scorecard_search_schools` | Search institutions by location, price, completion, operating certification, and other school characteristics. Sort by fields with API sort support. |
|
|
39
|
+
| `scorecard_get_school` | Institutional profiles with costs, admissions, aid, demographics, completion, and borrower repayment outcomes. |
|
|
40
|
+
| `scorecard_compare_schools` | Side-by-side comparison of up to five schools. Includes ranks and leaders for eligible metrics. |
|
|
41
41
|
| `scorecard_get_programs` | Paged field-of-study outcomes: completion-based 1/4-year earnings, legacy highest-credential earnings, debt, and campus awards with separate provenance. |
|
|
42
42
|
| `scorecard_search_programs` | Find programs by CIP and credential or keyword, retain degree identity, and rank earnings within each fetched school page. |
|
|
43
43
|
| `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. |
|
|
44
|
-
| `scorecard_value_analysis` |
|
|
44
|
+
| `scorecard_value_analysis` | Combines cost, debt, repayment, and earnings data with debt-to-earnings and net-price-to-earnings ratios. |
|
|
45
45
|
| `scorecard_lookup_cip` | Search all 464 current NCES CIP 2020 four-digit groups by code, keyword, or related program name. Served offline. |
|
|
46
46
|
| `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. |
|
|
47
47
|
|
|
@@ -67,9 +67,10 @@ The [college-scorecard-guide](./skills/college-scorecard-guide/SKILL.md) covers
|
|
|
67
67
|
|
|
68
68
|
### `scorecard_search_schools` <sub>tool</sub>
|
|
69
69
|
|
|
70
|
-
- Search by name, state, ownership, degree level, size, acceptance rate, CIP code, or ZIP and distance (miles or `km`).
|
|
71
|
-
-
|
|
72
|
-
- `
|
|
70
|
+
- Search by name, state, ownership, degree level, size, acceptance rate, CIP code, or ZIP and distance (miles or `km`). State lists accept `WA,CA`.
|
|
71
|
+
- Apply `max_net_price` (inclusive dollars), `min_completion_rate` (inclusive 0–1), and `locale` (`city`, `suburb`, `town`, or `rural`) before paging. These filters require reported values. Negative price ceilings normalize to $0 with a notice.
|
|
72
|
+
- `operating`, `hbcu`, `men_only`, and `women_only` match explicit true or false values. Omit a flag to include unknown values. `operating: false` means the school lacks current operating certification. Verify actual closure separately.
|
|
73
|
+
- Use `scorecard_list_fields` to choose a supported sort such as `latest.cost.avg_net_price.overall:asc`. Omit sort to preserve API order. `page` starts at zero and `per_page` is capped at 100.
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
@@ -78,22 +79,23 @@ The [college-scorecard-guide](./skills/college-scorecard-guide/SKILL.md) covers
|
|
|
78
79
|
- Accepts a school ID or an array of up to 1,000. The first 100 distinct IDs are fetched; `missing_ids` lists fetched IDs with no record and `unprocessed_ids` lists the excess.
|
|
79
80
|
- Default profiles cover costs, admissions, outcomes, financial aid, demographics, and completion rates. Custom `fields` returns `selected_fields` with the requested values, and `absent_fields` lists requested paths missing from the response.
|
|
80
81
|
- Projected program arrays use `program_limit` (default 20, capped at 100) and `program_offset`; follow each school's `program_pages` continuation. Raw values and provider positions stay aligned.
|
|
81
|
-
- HBCU and single-sex flags
|
|
82
|
+
- Profiles include operating certification, HBCU, and single-sex flags as booleans when known, omitting unknown flags. The discontinued three-year declining-balance rate carries its 2016–17 file, repayment-entry cohorts, and measurement period.
|
|
83
|
+
- `borrower_repayment` reports making progress, default, and paid in full at two and four years for OPEID6-pooled undergraduate federal Direct Loan borrowers. Each horizon has its own provenance and cohort count when available. Published bins are preserved verbatim, and only decimal point estimates have numeric values.
|
|
82
84
|
|
|
83
85
|
---
|
|
84
86
|
|
|
85
87
|
### `scorecard_compare_schools` <sub>tool</sub>
|
|
86
88
|
|
|
87
89
|
- Accepts 2–1,000 raw unit IDs and compares the first five distinct normalized IDs on `costs`, `admissions`, `outcomes`, or `aid`. `missing_ids` were queried; `unprocessed_ids` were not.
|
|
88
|
-
- Equal
|
|
89
|
-
- Each cell's `availability` distinguishes available, unavailable, and privacy-suppressed values.
|
|
90
|
+
- Equal eligible values share a rank (1, 1, 3). Admissions metrics, aid participation rates, shared OPEID6 outcome rows, and mixed academic/program-year price rows are unranked. A single found school yields values without ranks or leaders.
|
|
91
|
+
- Each cell's `availability` distinguishes available, unavailable, and privacy-suppressed values. Repayment rows rank the historical three-year declining-balance measure and identify its vintage.
|
|
90
92
|
|
|
91
93
|
---
|
|
92
94
|
|
|
93
95
|
### `scorecard_get_programs` <sub>tool</sub>
|
|
94
96
|
|
|
95
97
|
- Accepts one school ID, with optional CIP code (dotted or undotted), `credential_level`, and minimum earnings filters. A school with no matching programs returns an empty collection; a nonexistent school is a lookup error.
|
|
96
|
-
-
|
|
98
|
+
- Text results lead with completion-based one- and four-year medians, counts, and availability. Legacy `earnings_1yr_median` and `earnings_count` appear separately with their highest-credential provenance.
|
|
97
99
|
- `min_earnings` and ordering use completion-based one-year earnings, with no legacy fallback. Page with `limit` (default 20, capped at 100) and `offset`; `total` counts matches before paging, and `nextOffset` is null at the end.
|
|
98
100
|
- `median_debt` is completers' cumulative Stafford/Grad PLUS borrowing. `ipeds_awards_year1` and `ipeds_awards_year2` count awards in each year of the pooled debt cohort, not students.
|
|
99
101
|
|
|
@@ -103,14 +105,14 @@ The [college-scorecard-guide](./skills/college-scorecard-guide/SKILL.md) covers
|
|
|
103
105
|
|
|
104
106
|
- Search by CIP code or program name, with optional integer `credential_level` (1–8 and 99), state, ownership, net price, earnings, and debt filters. `page`/`per_page` paginate schools; `offset`/`limit` page matching program rows within that school page.
|
|
105
107
|
- Returns school IDs and names with program metrics, `credential_level`, and `credential_title`. Available earnings sort first; availability, debt, and award fields match `scorecard_get_programs`.
|
|
106
|
-
- `min_earnings` filters locally, so totals and pagination are upstream school counts before filtering. Earnings and debt thresholds are inclusive and exclude unknown values.
|
|
108
|
+
- `min_earnings` filters locally, so totals and pagination are upstream school counts before filtering. Earnings and debt thresholds are inclusive and exclude unknown values. Negative `max_net_price` and `max_debt` normalize to $0 with a notice.
|
|
107
109
|
- Follow `next` until null: it drains program rows on the current school page before advancing. `shown` counts returned programs; `schools_shown` counts fetched schools. Rankings use current completion-based one-year earnings within the fetched page only.
|
|
108
110
|
|
|
109
111
|
---
|
|
110
112
|
|
|
111
113
|
### `scorecard_get_earnings` <sub>tool</sub>
|
|
112
114
|
|
|
113
|
-
- Accepts one school ID and optional data-file start `years` from 1996–2025 (file vintages, not entry years). Omit `years` or pass `[]` for the snapshot only.
|
|
115
|
+
- Accepts one school ID and optional data-file start `years` from 1996–2025 (file vintages, not entry years). Duplicate years collapse in caller order. Omit `years` or pass `[]` for the snapshot only.
|
|
114
116
|
- Covers federally aided undergraduate entrants working and not enrolled, regardless of completion: medians at 6/8/10 years after entry, 6/10-year P25/P75, and non-male/male 6-year medians.
|
|
115
117
|
- `current_availability` and `trend[].availability` classify each metric. `current_context` and `trend[].context` give `data_file_year`, `entry_cohorts`, `measurement_years`, and `dollar_year`; values keep the provider's dollar basis, so check it before comparing across vintages.
|
|
116
118
|
|
|
@@ -118,24 +120,25 @@ The [college-scorecard-guide](./skills/college-scorecard-guide/SKILL.md) covers
|
|
|
118
120
|
|
|
119
121
|
### `scorecard_value_analysis` <sub>tool</sub>
|
|
120
122
|
|
|
121
|
-
- Accepts one school ID
|
|
123
|
+
- Accepts one school ID. Optional `family_income` selects the applicable net price bracket ($0–30k, $30k–48k, $48k–75k, $75k–110k, or $110k+). Negative income normalizes to $0 with a notice.
|
|
122
124
|
- Returns ratios alongside their source figures. `effective_net_price` is the price used, and `net_price_basis` is `income_bracket`, `overall`, or `unavailable`.
|
|
123
125
|
- If the bracket is missing, the overall price is used and `data_notes` says so. Ratios require positive annual earnings.
|
|
124
126
|
- Tuition and attendance independently prefer academic-year prices, otherwise reported program-year prices; each has its own basis. Program tuition never substitutes for net price. OPEID6-pooled outcomes are identified alongside campus prices.
|
|
127
|
+
- Returns the same two- and four-year borrower statuses and historical three-year declining-balance context as the default school profile.
|
|
125
128
|
|
|
126
129
|
---
|
|
127
130
|
|
|
128
131
|
### `scorecard_lookup_cip` <sub>tool</sub>
|
|
129
132
|
|
|
130
133
|
- Search by nonblank keyword or partial name (default limit 20, capped at 50). Dotted `11.07` and undotted `1107` are equivalent; continue with `offset` and returned `nextOffset` while more results remain.
|
|
131
|
-
- Returns exact group titles and family identities from all 464 current NCES CIP 2020 four-digit groups.
|
|
134
|
+
- Returns exact group titles and family identities from all 464 current NCES CIP 2020 four-digit groups. Six-digit queries such as `11.0701` and `110701` resolve to their four-digit group with a notice. Program tools take the four-digit group. No matches return an empty collection with guidance.
|
|
132
135
|
|
|
133
136
|
---
|
|
134
137
|
|
|
135
138
|
### `scorecard_list_fields` <sub>tool</sub>
|
|
136
139
|
|
|
137
|
-
- Search
|
|
138
|
-
- Returns field paths, descriptions, data types, categories, and API sorting support
|
|
140
|
+
- Search 94 curated offline field entries by nonblank query (default limit 30, capped at 100). Use before passing custom `fields` to `scorecard_get_school`, including pooled full-time retention for four-year and less-than-four-year institutions.
|
|
141
|
+
- Returns field paths, descriptions, data types, categories, and observed API sorting support. `tip` flags results containing unsortable fields.
|
|
139
142
|
|
|
140
143
|
---
|
|
141
144
|
|
|
@@ -159,7 +162,7 @@ The [college-scorecard-guide](./skills/college-scorecard-guide/SKILL.md) covers
|
|
|
159
162
|
### `scorecard_compare_prompt` <sub>prompt</sub>
|
|
160
163
|
|
|
161
164
|
- Arguments: `school_names` (comma-separated list) and `focus` (`costs` | `outcomes` | `programs`), both required
|
|
162
|
-
- `costs` and `outcomes` run school discovery, `scorecard_compare_schools`, profiles, and value analysis. `programs` runs school discovery, CIP lookup, and `scorecard_get_programs` per school, then compares earnings, debt, and IPEDS awards for matching credentials.
|
|
165
|
+
- `costs` and `outcomes` run school discovery, `scorecard_compare_schools`, profiles, and value analysis. `programs` runs school discovery, CIP lookup, and `scorecard_get_programs` per school, then compares completion earnings, debt, and IPEDS awards for matching credentials.
|
|
163
166
|
|
|
164
167
|
## Features
|
|
165
168
|
|
|
@@ -170,14 +173,14 @@ College Scorecard-specific:
|
|
|
170
173
|
- Full College Scorecard API coverage: ~6,500 Title IV institutions, ~2,800 data fields spanning costs, outcomes, demographics, financial aid, and field-of-study earnings
|
|
171
174
|
- Program completion earnings at one and four years, alongside legacy highest-credential outcomes; each series carries its population and vintage
|
|
172
175
|
- Field pre-selection per tool — curated field sets appropriate to each tool's purpose; optional `fields` override for custom queries
|
|
173
|
-
- Embedded CIP taxonomy (464 groups) and field catalog (
|
|
176
|
+
- Embedded CIP taxonomy (464 groups) and field catalog (94 fields) served offline
|
|
174
177
|
- Geographic filtering via U.S. zip code + distance radius
|
|
175
178
|
|
|
176
179
|
Agent-friendly output:
|
|
177
180
|
|
|
178
181
|
- Availability distinguishes numbers (including zero), missing values, and explicit `PS` / `PrivacySuppressed` provider markers
|
|
179
182
|
- Derived metrics sit alongside source figures in `scorecard_value_analysis`, and `scorecard_compare_schools` adds ordinal ranks
|
|
180
|
-
- School sorting uses
|
|
183
|
+
- School sorting uses fields with observed API sort support. Six-year earnings and pooled full-time retention can be projected but cannot be used as sort fields.
|
|
181
184
|
- Provider failures report distinct validation, authentication, throttling, timeout, and availability reasons; availability uses `api_error` and cancellation remains `RequestCancelled`
|
|
182
185
|
|
|
183
186
|
## Getting started
|
|
@@ -265,7 +268,7 @@ MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 SCORECARD_API_KEY=... bun run start:h
|
|
|
265
268
|
|
|
266
269
|
### Prerequisites
|
|
267
270
|
|
|
268
|
-
- [Bun v1.4.
|
|
271
|
+
- [Bun v1.4.4](https://bun.sh/) or higher (or Node.js v24+).
|
|
269
272
|
- A College Scorecard API key — free registration at [api.data.gov/signup](https://api.data.gov/signup/). Rate limit: 1,000 requests/hour per key.
|
|
270
273
|
|
|
271
274
|
### Installation
|
|
@@ -305,12 +308,14 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
|
|
|
305
308
|
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http` | `stdio` |
|
|
306
309
|
| `MCP_HTTP_PORT` | HTTP server port | `3010` |
|
|
307
310
|
| `MCP_HTTP_ENDPOINT_PATH` | HTTP endpoint path where the MCP server is mounted | `/mcp` |
|
|
308
|
-
| `MCP_PUBLIC_URL` | Public
|
|
311
|
+
| `MCP_PUBLIC_URL` | Public HTTP or HTTPS base URL for TLS-terminating reverse-proxy deployments. Omit credentials, query parameters, and fragments. | none |
|
|
309
312
|
| `MCP_SESSION_MODE` | HTTP session mode: `stateless`, `stateful`, or `auto` | `stateless` |
|
|
310
313
|
| `MCP_AUTH_MODE` | Authentication: `none`, `jwt`, or `oauth` | `none` |
|
|
314
|
+
| `MCP_JWT_EXPECTED_AUDIENCE` | Required `aud` claim in JWT mode. An unset audience logs a startup warning. | none |
|
|
315
|
+
| `MCP_JWT_EXPECTED_ISSUER` | Required `iss` claim in JWT mode. Configure it alongside the audience. | none |
|
|
311
316
|
| `MCP_LOG_LEVEL` | Log level (`debug`, `info`, `warning`, `error`, etc.) | `info` |
|
|
312
317
|
| `MCP_GC_PRESSURE_INTERVAL_MS` | Opt-in forced-GC loop interval in ms (Bun only); try `60000` if heap grows under HTTP load | `0` (disabled) |
|
|
313
|
-
| `LOGS_DIR` | Directory for log files
|
|
318
|
+
| `LOGS_DIR` | Directory for log files. Relative paths resolve from the server package root. | `<server-package-root>/logs` |
|
|
314
319
|
| `STORAGE_PROVIDER_TYPE` | Storage backend: `in-memory`, `filesystem`, `supabase`, `cloudflare-kv/r2/d1` | `in-memory` |
|
|
315
320
|
| `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry) | `false` |
|
|
316
321
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Filter schools by price, completion, and certification, and compare outcomes with the reported cohorts and measures."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.6.0 — 2026-11-13
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`scorecard_search_schools`** filters by maximum net price, minimum completion rate, HBCU status, and locale before pagination. ([#55](https://github.com/cyanheads/college-scorecard-mcp-server/issues/55))
|
|
12
|
+
- **School profiles and value analysis** return two- and four-year undergraduate federal Direct Loan borrower statuses with OPEID6 scope, cohort counts, and the published decimals or bins. ([#58](https://github.com/cyanheads/college-scorecard-mcp-server/issues/58))
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- Remove inherited titles from concrete school and program resource entries; template titles remain.
|
|
17
|
+
- **Runtime** requires Bun 1.4.4 or later when running on Bun.
|
|
18
|
+
|
|
19
|
+
## Fixed
|
|
20
|
+
|
|
21
|
+
- **Three-year declining-balance repayment** carries its discontinued status and 2016–17 file vintage in school profiles, value analysis, and comparisons. ([#51](https://github.com/cyanheads/college-scorecard-mcp-server/issues/51))
|
|
22
|
+
- **Program tools and comparison prompt** lead with completion-based earnings and distinguish the legacy highest-credential series. Program tools render all results as readable text with availability, provenance, and continuation. ([#52](https://github.com/cyanheads/college-scorecard-mcp-server/issues/52))
|
|
23
|
+
- **`scorecard_list_fields`** reports observed API sort support and includes pooled full-time retention for four-year and less-than-four-year institutions. ([#53](https://github.com/cyanheads/college-scorecard-mcp-server/issues/53))
|
|
24
|
+
- **Operating certification** appears where reported in school tools and resources, with an explicit certification filter in school search. ([#54](https://github.com/cyanheads/college-scorecard-mcp-server/issues/54))
|
|
25
|
+
- **`scorecard_compare_schools`** leaves descriptive metrics and single-school results unranked and preserves unranked rows in the comparison prompt. ([#56](https://github.com/cyanheads/college-scorecard-mcp-server/issues/56))
|
|
26
|
+
- **Input normalization** clamps negative dollar inputs to zero with a notice, deduplicates earnings vintages in caller order, and maps six-digit CIP queries to their four-digit group. Exhausted CIP pages explain how to restart. ([#57](https://github.com/cyanheads/college-scorecard-mcp-server/issues/57))
|
|
27
|
+
- **Readable output** preserves reported numeric precision for comparison values, historical repayment, and family income. Upstream HTTP error bodies stay server-side by default.
|
|
28
|
+
- **MCPB packaging** retains runtime files when stripping dependency development files.
|
|
29
|
+
|
|
30
|
+
## Dependencies
|
|
31
|
+
|
|
32
|
+
- **`@cyanheads/mcp-ts-core`** ^0.13.18 → ^0.13.22
|
|
33
|
+
- **`@biomejs/biome`** ^2.6.4 → ^2.6.7
|
|
34
|
+
- **`vitest`** ^5.0.5 → ^5.1.0
|
package/changelog/template.md
CHANGED
|
@@ -116,14 +116,21 @@ security: false
|
|
|
116
116
|
resolves to whatever real item already owns 42, and timeline previews pull
|
|
117
117
|
in that unrelated item's metadata.
|
|
118
118
|
|
|
119
|
+
Outside reporters: when the issue or PR came from outside the project
|
|
120
|
+
(`git-wrapup` step 5 says how to tell), thank its author in the same
|
|
121
|
+
parenthetical, profile linked by full URL for the same reason:
|
|
122
|
+
|
|
123
|
+
([#38](https://github.com/cyanheads/mcp-ts-core/issues/38), thanks [@octocat](https://github.com/octocat)!)
|
|
124
|
+
|
|
119
125
|
TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
|
|
120
126
|
via `gh release create --notes-from-tag`. It is a condensed digest of this
|
|
121
127
|
entry, never a copy, and its format is owned by the `release-and-publish`
|
|
122
128
|
skill (step 4, "Create the annotated tag"): a short subject line without the
|
|
123
129
|
version, flat headline bullets — no Keep-a-Changelog section headers, no
|
|
124
|
-
gates line — at most one deps line, issue backlinks
|
|
125
|
-
last. In release-PR mode the `git-wrapup`
|
|
126
|
-
PR body's `## Changes` and the tag copies
|
|
130
|
+
gates line — at most one deps line, issue backlinks with any outside-reporter
|
|
131
|
+
thanks, and the changelog link last. In release-PR mode the `git-wrapup`
|
|
132
|
+
skill authors those bullets as the PR body's `## Changes` and the tag copies
|
|
133
|
+
them.
|
|
127
134
|
-->
|
|
128
135
|
|
|
129
136
|
## Added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-catalog.d.ts","sourceRoot":"","sources":["../../src/data/field-catalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"field-catalog.d.ts","sourceRoot":"","sources":["../../src/data/field-catalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB;IAChB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;CAClD;AAED,mFAAmF;AACnF,eAAO,MAAM,aAAa,EAAE,UAAU,EAwpBrC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,UAAU,EAAE,CAsB1E"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Scorecard data dictionary. Static data — no API call required.
|
|
4
4
|
* @module data/field-catalog
|
|
5
5
|
*/
|
|
6
|
+
import { BORROWER_REPAYMENT_SERIES, BORROWER_REPAYMENT_STATUSES, borrowerRepaymentField, describeLegacyRepayment, LEGACY_REPAYMENT_CONTEXT, } from './repayment-context.js';
|
|
6
7
|
/** Core field catalog — most decision-relevant fields from the data dictionary. */
|
|
7
8
|
export const FIELD_CATALOG = [
|
|
8
9
|
// Identity
|
|
@@ -17,7 +18,7 @@ export const FIELD_CATALOG = [
|
|
|
17
18
|
path: 'id',
|
|
18
19
|
description: 'Unique unit ID (use for ID-based lookups)',
|
|
19
20
|
type: 'integer',
|
|
20
|
-
sortable:
|
|
21
|
+
sortable: true,
|
|
21
22
|
category: 'identity',
|
|
22
23
|
},
|
|
23
24
|
{
|
|
@@ -101,7 +102,7 @@ export const FIELD_CATALOG = [
|
|
|
101
102
|
path: 'school.minority_serving.historically_black',
|
|
102
103
|
description: 'Historically Black College or University flag',
|
|
103
104
|
type: 'integer',
|
|
104
|
-
sortable:
|
|
105
|
+
sortable: true,
|
|
105
106
|
category: 'identity',
|
|
106
107
|
},
|
|
107
108
|
{
|
|
@@ -151,70 +152,70 @@ export const FIELD_CATALOG = [
|
|
|
151
152
|
path: 'latest.cost.net_price.public.by_income_level.0-30000',
|
|
152
153
|
description: 'Net price for family income $0–$30,000 (public institutions)',
|
|
153
154
|
type: 'integer',
|
|
154
|
-
sortable:
|
|
155
|
+
sortable: false,
|
|
155
156
|
category: 'cost',
|
|
156
157
|
},
|
|
157
158
|
{
|
|
158
159
|
path: 'latest.cost.net_price.public.by_income_level.30001-48000',
|
|
159
160
|
description: 'Net price for family income $30,001–$48,000 (public institutions)',
|
|
160
161
|
type: 'integer',
|
|
161
|
-
sortable:
|
|
162
|
+
sortable: false,
|
|
162
163
|
category: 'cost',
|
|
163
164
|
},
|
|
164
165
|
{
|
|
165
166
|
path: 'latest.cost.net_price.public.by_income_level.48001-75000',
|
|
166
167
|
description: 'Net price for family income $48,001–$75,000 (public institutions)',
|
|
167
168
|
type: 'integer',
|
|
168
|
-
sortable:
|
|
169
|
+
sortable: false,
|
|
169
170
|
category: 'cost',
|
|
170
171
|
},
|
|
171
172
|
{
|
|
172
173
|
path: 'latest.cost.net_price.public.by_income_level.75001-110000',
|
|
173
174
|
description: 'Net price for family income $75,001–$110,000 (public institutions)',
|
|
174
175
|
type: 'integer',
|
|
175
|
-
sortable:
|
|
176
|
+
sortable: false,
|
|
176
177
|
category: 'cost',
|
|
177
178
|
},
|
|
178
179
|
{
|
|
179
180
|
path: 'latest.cost.net_price.public.by_income_level.110001-plus',
|
|
180
181
|
description: 'Net price for family income $110,001+ (public institutions)',
|
|
181
182
|
type: 'integer',
|
|
182
|
-
sortable:
|
|
183
|
+
sortable: false,
|
|
183
184
|
category: 'cost',
|
|
184
185
|
},
|
|
185
186
|
{
|
|
186
187
|
path: 'latest.cost.net_price.private.by_income_level.0-30000',
|
|
187
188
|
description: 'Net price for family income $0–$30,000 (private institutions)',
|
|
188
189
|
type: 'integer',
|
|
189
|
-
sortable:
|
|
190
|
+
sortable: false,
|
|
190
191
|
category: 'cost',
|
|
191
192
|
},
|
|
192
193
|
{
|
|
193
194
|
path: 'latest.cost.net_price.private.by_income_level.30001-48000',
|
|
194
195
|
description: 'Net price for family income $30,001–$48,000 (private institutions)',
|
|
195
196
|
type: 'integer',
|
|
196
|
-
sortable:
|
|
197
|
+
sortable: false,
|
|
197
198
|
category: 'cost',
|
|
198
199
|
},
|
|
199
200
|
{
|
|
200
201
|
path: 'latest.cost.net_price.private.by_income_level.48001-75000',
|
|
201
202
|
description: 'Net price for family income $48,001–$75,000 (private institutions)',
|
|
202
203
|
type: 'integer',
|
|
203
|
-
sortable:
|
|
204
|
+
sortable: false,
|
|
204
205
|
category: 'cost',
|
|
205
206
|
},
|
|
206
207
|
{
|
|
207
208
|
path: 'latest.cost.net_price.private.by_income_level.75001-110000',
|
|
208
209
|
description: 'Net price for family income $75,001–$110,000 (private institutions)',
|
|
209
210
|
type: 'integer',
|
|
210
|
-
sortable:
|
|
211
|
+
sortable: false,
|
|
211
212
|
category: 'cost',
|
|
212
213
|
},
|
|
213
214
|
{
|
|
214
215
|
path: 'latest.cost.net_price.private.by_income_level.110001-plus',
|
|
215
216
|
description: 'Net price for family income $110,001+ (private institutions)',
|
|
216
217
|
type: 'integer',
|
|
217
|
-
sortable:
|
|
218
|
+
sortable: false,
|
|
218
219
|
category: 'cost',
|
|
219
220
|
},
|
|
220
221
|
{
|
|
@@ -347,31 +348,52 @@ export const FIELD_CATALOG = [
|
|
|
347
348
|
},
|
|
348
349
|
{
|
|
349
350
|
path: 'latest.repayment.repayment_cohort.3_year_declining_balance',
|
|
350
|
-
description:
|
|
351
|
+
description: `Share of borrowers paying down principal (declining loan balance) 3 years after entering repayment (0–1), ${describeLegacyRepayment(LEGACY_REPAYMENT_CONTEXT[3])}`,
|
|
351
352
|
type: 'float',
|
|
352
353
|
sortable: false,
|
|
353
354
|
category: 'aid',
|
|
354
355
|
},
|
|
355
356
|
{
|
|
356
357
|
path: 'latest.repayment.repayment_cohort.1_year_declining_balance',
|
|
357
|
-
description:
|
|
358
|
+
description: `Share of borrowers paying down principal (declining loan balance) 1 year after entering repayment (0–1), ${describeLegacyRepayment(LEGACY_REPAYMENT_CONTEXT[1])}`,
|
|
358
359
|
type: 'float',
|
|
359
360
|
sortable: false,
|
|
360
361
|
category: 'aid',
|
|
361
362
|
},
|
|
362
363
|
{
|
|
363
364
|
path: 'latest.repayment.repayment_cohort.5_year_declining_balance',
|
|
364
|
-
description:
|
|
365
|
+
description: `Share of borrowers paying down principal (declining loan balance) 5 years after entering repayment (0–1), ${describeLegacyRepayment(LEGACY_REPAYMENT_CONTEXT[5])}`,
|
|
365
366
|
type: 'float',
|
|
366
367
|
sortable: false,
|
|
367
368
|
category: 'aid',
|
|
368
369
|
},
|
|
370
|
+
...BORROWER_REPAYMENT_SERIES.flatMap((series) => {
|
|
371
|
+
const { horizon_years, data_file, repayment_entry_cohorts, measurement_period } = series;
|
|
372
|
+
const countPath = borrowerRepaymentField(horizon_years, 'count');
|
|
373
|
+
const vintage = `OPEID6 pooled; ${data_file} file, repayment-entry cohorts ${repayment_entry_cohorts.join(', ')}, measured ${measurement_period.join(', ')}`;
|
|
374
|
+
return [
|
|
375
|
+
{
|
|
376
|
+
path: countPath,
|
|
377
|
+
description: `Cohort count of undergraduate federal Direct Loan borrowers for the ${horizon_years}-year statuses (${vintage})`,
|
|
378
|
+
type: 'integer',
|
|
379
|
+
sortable: false,
|
|
380
|
+
category: 'aid',
|
|
381
|
+
},
|
|
382
|
+
...Object.values(BORROWER_REPAYMENT_STATUSES).map(({ label, suffix }) => ({
|
|
383
|
+
path: borrowerRepaymentField(horizon_years, suffix),
|
|
384
|
+
description: `Share of undergraduate federal Direct Loan borrowers assigned ${label} at ${horizon_years} years, published as a decimal or bin. Denominator is ${countPath} (${vintage})`,
|
|
385
|
+
type: 'string',
|
|
386
|
+
sortable: false,
|
|
387
|
+
category: 'aid',
|
|
388
|
+
})),
|
|
389
|
+
];
|
|
390
|
+
}),
|
|
369
391
|
// Completion / Outcomes
|
|
370
392
|
{
|
|
371
393
|
path: 'latest.completion.rate_suppressed.overall',
|
|
372
394
|
description: 'Completion rate at 150% normal time (overall)',
|
|
373
395
|
type: 'float',
|
|
374
|
-
sortable:
|
|
396
|
+
sortable: true,
|
|
375
397
|
category: 'completion',
|
|
376
398
|
},
|
|
377
399
|
{
|
|
@@ -385,9 +407,24 @@ export const FIELD_CATALOG = [
|
|
|
385
407
|
path: 'latest.completion.consumer_rate',
|
|
386
408
|
description: 'Consumer-friendly completion rate',
|
|
387
409
|
type: 'float',
|
|
388
|
-
sortable:
|
|
410
|
+
sortable: true,
|
|
389
411
|
category: 'completion',
|
|
390
412
|
},
|
|
413
|
+
// Retention
|
|
414
|
+
{
|
|
415
|
+
path: 'latest.student.retention_rate_suppressed.four_year.full_time_pooled',
|
|
416
|
+
description: 'Pooled share of first-time, full-time bachelor’s or equivalent degree-seeking undergraduates who return the next fall at four-year institutions',
|
|
417
|
+
type: 'float',
|
|
418
|
+
sortable: false,
|
|
419
|
+
category: 'retention',
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
path: 'latest.student.retention_rate_suppressed.lt_four_year.full_time_pooled',
|
|
423
|
+
description: 'Pooled share of first-time, full-time degree- or certificate-seeking undergraduates who return the next fall at less-than-four-year institutions',
|
|
424
|
+
type: 'float',
|
|
425
|
+
sortable: false,
|
|
426
|
+
category: 'retention',
|
|
427
|
+
},
|
|
391
428
|
// Earnings — Institution Level
|
|
392
429
|
{
|
|
393
430
|
path: 'latest.earnings.6_yrs_after_entry.median',
|
|
@@ -530,7 +567,7 @@ export const FIELD_CATALOG = [
|
|
|
530
567
|
path: 'latest.programs.cip_4_digit.earnings.4_yr.overall_median_earnings',
|
|
531
568
|
description: 'Median earnings of graduates working and not enrolled 4 years after completion, pooled by OPEID6, CIP, and credential',
|
|
532
569
|
type: 'integer',
|
|
533
|
-
sortable:
|
|
570
|
+
sortable: false,
|
|
534
571
|
category: 'programs',
|
|
535
572
|
},
|
|
536
573
|
{
|
|
@@ -551,7 +588,7 @@ export const FIELD_CATALOG = [
|
|
|
551
588
|
path: 'latest.programs.cip_4_digit.code',
|
|
552
589
|
description: 'CIP 4-digit program code (e.g. "11.07")',
|
|
553
590
|
type: 'string',
|
|
554
|
-
sortable:
|
|
591
|
+
sortable: false,
|
|
555
592
|
category: 'programs',
|
|
556
593
|
},
|
|
557
594
|
{
|
|
@@ -579,28 +616,28 @@ export const FIELD_CATALOG = [
|
|
|
579
616
|
path: 'latest.programs.cip_4_digit.debt.staff_grad_plus.all.all_inst.median',
|
|
580
617
|
description: 'Median cumulative Stafford/Grad PLUS borrowing among completers across institutions at the same academic level',
|
|
581
618
|
type: 'integer',
|
|
582
|
-
sortable:
|
|
619
|
+
sortable: false,
|
|
583
620
|
category: 'programs',
|
|
584
621
|
},
|
|
585
622
|
{
|
|
586
623
|
path: 'latest.programs.cip_4_digit.counts.ipeds_awards1',
|
|
587
624
|
description: 'IPEDS awards in year 1 of the pooled debt cohort; not enrollment or unique students',
|
|
588
625
|
type: 'integer',
|
|
589
|
-
sortable:
|
|
626
|
+
sortable: false,
|
|
590
627
|
category: 'programs',
|
|
591
628
|
},
|
|
592
629
|
{
|
|
593
630
|
path: 'latest.programs.cip_4_digit.counts.ipeds_awards2',
|
|
594
631
|
description: 'IPEDS awards in year 2 of the pooled debt cohort; not enrollment or unique students',
|
|
595
632
|
type: 'integer',
|
|
596
|
-
sortable:
|
|
633
|
+
sortable: false,
|
|
597
634
|
category: 'programs',
|
|
598
635
|
},
|
|
599
636
|
{
|
|
600
637
|
path: 'latest.programs.cip_4_digit.credential.level',
|
|
601
638
|
description: 'Credential level: 1=undergraduate certificate, 2=associate, 3=bachelor, 4=post-baccalaureate certificate, 5=master, 6=doctoral, 7=first professional, 8=graduate/professional certificate, 99=non-credential',
|
|
602
639
|
type: 'integer',
|
|
603
|
-
sortable:
|
|
640
|
+
sortable: false,
|
|
604
641
|
category: 'programs',
|
|
605
642
|
},
|
|
606
643
|
];
|