degreeroi
README.md
# degreeroi
What is a degree actually worth, in dollars, over a
working life? degreeroi answers with data instead of
brochure copy: lifetime return on investment for
college majors, and 30-year net present value for the
U.S. colleges where the maths clears a positive bar.
It is a thin, read-only client for the LE TEEN College
ROI API — static JSON, no key, no signup — exposed
both as a small CLI and as a stdio MCP server from a
single bin.
The major figures cover 19 categories and 115 CIP
subfields: median and mean lifetime ROI, the share of
graduates who never break even, the break-even age,
and an AI-exposure band, with full distributions on
the detail view. The college figures cover the 500
four-year schools that clear a positive-NPV envelope
(out of roughly 1,656 U.S. four-years): what a degree
is worth over 30 years to a resident and to a
non-resident, what attendance costs, what graduates
earn, and when the degree pays for itself. Every
dollar figure is a lifetime / 30-year total in USD.
One consequence of the envelope is worth stating
plainly: a school that is not in the 500 is not in
the data. Asking for it returns a not-found, because
absence is itself the signal — degreeroi never
invents a record for a school the dataset leaves out.
## Configuration
- `COLLEGE_ROI_API_URL` (optional) — API base URL.
Defaults to `https://le-teen.com/api`.
That is all. There is no API key: the upstream API is
free and keyless. Responses are cached in-process
for 24 hours, matching the API's own CDN cache, and
nothing is ever written back.
## Tools
- `list_majors` — compact ROI rows for the major
categories and subfields. Optional filters:
`kind` (`category` or `subfield`), `parent` (the
category a subfield belongs to), `sort`
(`median_roi`, `mean_roi`, `break_even_age` or
`name`) and `limit`. Only the filters you set are
sent.
- `get_major` — the full record for one major:
the ROI distribution (p25, median, mean, p75),
completion-adjusted and dropout ROI, graduate and
program counts, and the AI-exposure detail.
- `search_colleges` — search the 500 envelope
colleges by `name`, `state` or `control`, with a
`limit`. Rows carry resident and non-resident
30-year NPV, cost of attendance, median earnings
and break-even age.
- `get_college` — the full record for one college,
including its IPEDS unitid and FREOPP coverage.
A college outside the envelope answers
`college not found: <college>`.
- `best_value_colleges` — best-value four-years at
resident pricing: the top 15 per state when a
`state` is given (trim with `limit`), or a
nationwide top-pick summary when it is not.
- `out_of_state_penalty` — public four-years ranked
by how much 30-year NPV a non-resident gives up
versus a resident; optionally narrow with `state`
and `limit`.
- `get_api_info` — metadata for the underlying API:
endpoints, licence, dataset DOI and attribution.
Answered locally from the pinned metadata; it makes
no upstream call.
Behaviour worth knowing:
- List tools pass the API's compact projections
through unchanged; detail tools pass the full
upstream record through unchanged.
- A non-2xx upstream reply fails with
`degreeroi error: HTTP <status>` (except the
detail tools' 404, which is the honest not-found
above), and an unreachable API with
`degreeroi unreachable`.
### Endpoint provenance
The original project's README pins the seven tools,
their semantics, the API base
(`https://le-teen.com/api`, static JSON), the filter
notions on `list_majors` (kind/parent, sort, limit)
and on `search_colleges` (name/state/control), and
the dataset facts (19 categories, 115 subfields, 500
envelope colleges, DOI `10.5281/zenodo.21351602`,
CC BY 4.0, LE TEEN at le-teen.com). It does not
enumerate endpoint paths or parameter tables, so
those are labelled reconstructions in this rebuild —
one GET per networked tool under the API base:
- `GET <base>/majors` with only the set filters as
query parameters (used by `list_majors`).
- `GET <base>/majors/{major}` (used by `get_major`).
- `GET <base>/colleges` with only the set filters
as query parameters (used by `search_colleges`).
- `GET <base>/colleges/{college}` (used by
`get_college`).
- `GET <base>/best-value-colleges` with `state` /
`limit` when set (used by `best_value_colleges`).
- `GET <base>/out-of-state-penalty` with `state` /
`limit` when set (used by `out_of_state_penalty`).
- `get_api_info` is served from the pinned metadata,
with the endpoints as implemented above.
The `major` and `college` path segments are
URL-encoded.
Data sources behind the API: FREOPP program-level
estimates, IPEDS institutional data and BEA price
deflators. Data licence CC BY 4.0 — cite LE TEEN,
le-teen.com.
## CLI
Each tool is a subcommand taking one JSON argument
string:
```bash
npx @reneturcios/degreeroi list_majors '{"kind":"subfield","sort":"median_roi","limit":10}'
npx @reneturcios/degreeroi get_major '{"major":"computer-science"}'
npx @reneturcios/degreeroi search_colleges '{"state":"CA","control":"public"}'
npx @reneturcios/degreeroi get_college '{"college":"example-state-university"}'
npx @reneturcios/degreeroi best_value_colleges '{"state":"CA"}'
npx @reneturcios/degreeroi out_of_state_penalty '{"limit":20}'
npx @reneturcios/degreeroi get_api_info '{}'
npx @reneturcios/degreeroi --version
```
Output is the tool's result text (the upstream body
on success). Exit codes: `0` on success, `1` on a
runtime error, `2` on a usage error.
## MCP server
```bash
npx -y @reneturcios/degreeroi mcp
```
MCP client config:
```json
{
"mcpServers": {
"degreeroi": {
"command": "npx",
"args": ["-y", "@reneturcios/degreeroi", "mcp"]
}
}
}
```
## Docker
```bash
docker run -i ghcr.io/cloudcorprecords/degreeroi
docker run --rm ghcr.io/cloudcorprecords/degreeroi get_api_info '{}'
```
## Development
```bash
npm install
npm run build # tsc -> dist/
npm test # tsx --test test/*.test.ts (fake fetch only, no network)
npm run dev # run the CLI from source
```
## License
MIT — Copyright (c) 2026 Rene Turcios
The data served by the upstream API is CC BY 4.0
(LE TEEN, le-teen.com; dataset DOI
10.5281/zenodo.21351602).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues