opennih
42 fiscal years of entity-resolved NIH grant data via 14 read-only, provenance-carrying MCP tools.
사용해야 할까요
품질 및 안전성
발견 사항 (3)
- HIGH
- MEDIUMrank_institutions에서
- LOWfetch에서
도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.
컨텍스트 비용
이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.
설치
원클릭 설치
`claude_desktop_config.json` 파일에 다음을 추가하세요:
{
"mcpServers": {
"opennih": {
"url": "https://mcp.opennih.org/mcp"
}
}
}원격 엔드포인트
https://mcp.opennih.org/mcpstreamable-http할 수 있는 일
도구 목록
도구 (14)
🟢source_status
Use this tool when the user asks whether the OpenNIH corpus is loaded, which official sidecars are available, or how stale the data might be — and before reporting 'no such grant', since corpus_lag_note explains that a grant added to RePORTER after the snapshot cutoff is absent here, not nonexistent. Read-only status for the deployed NIH project corpus and official sidecars. Takes no parameters; no caller paths or external URLs are accepted.
입력 스키마
{
"type": "object",
"properties": {},
"required": [],
"title": "source_statusArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "source_statusDictOutput"
}🟢search_grants(query, text_search, project_num, fiscal_year_start, fiscal_year_end, ...)
Use this tool when the user asks to find NIH grants — by topic, principal investigator, institution, NIH Institute/Center, activity code, fiscal year, or project number ('what NIH grants exist on CRISPR', 'show me Stanford's R01s in 2022', 'look up 5R01CA036569-02'). This is the primary entry point: results carry pi_profile_id, the key get_pi_profile takes. Read-only bounded search over the entity-resolved NIH ExPORTER/RePORTER corpus; results include mechanism_class, funding_basis and provenance, and a null award_amount means not reported, never zero. Bounds: query/text_search/institution/pi_name 2-64 chars, project_num ^[A-Z0-9-]{1,24}$, activity_code ^[A-Z0-9]{1,5}$, fiscal years 1985-2100, limit 1-50 (default 20), offset 0-100000 (offset>10000 is rate-limited to 12/min — partition by fiscal_year instead). meta.total_funding is the full matching-slice sum, not the returned page. Results are cached for ~1 hour. Counting: one result is one source application-year row, so (project_num, fiscal_year) is NOT unique - a multi-component award (P/U center) emits one row per sub-project, so the same project_num can appear several times in one fiscal year with different PIs and titles. These are distinct NIH application records, not duplicates. Each row carries appl_id, the NIH application id and authoritative row identity - two rows sharing (project_num, fiscal_year) with different appl_id are distinct sub-project applications, and appl_id is the key to de-duplicate on. Use meta.total for rows, meta.unique_project_nums for distinct project numbers, and meta.distinct_awards (row field core_project_num) for distinct awards; never report meta.total as a grant count.
입력 스키마
{
"type": "object",
"properties": {
"query": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Query"
},
"text_search": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Text Search"
},
"project_num": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Project Num"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"activity_code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Activity Code"
},
"ic": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Ic"
},
"institution": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Institution"
},
"pi_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Pi Name"
},
"limit": {
"default": 20,
"title": "Limit",
"type": "integer"
},
"offset": {
"default": 0,
"title": "Offset",
"type": "integer"
}
},
"required": [],
"title": "search_grantsArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "search_grantsDictOutput"
}🟢rank_institutions(fiscal_year_start, fiscal_year_end, ic, sort_by, limit, ...)
Use this tool when the user asks which institutions get the most NIH money — 'top NIH-funded universities', 'where does NCI money go', 'rank research hospitals by R01 funding'. It also yields the entity_id that get_institution_profile, mechanism_mix and funding_growth take. Ranks institutions by competitive RPG-research NIH funding (R01 baseline), excluding intramural/contracts/centers/career/training, de-duplicated on core_project_num; NULL total_funding is not reported, never $0. Its total_funding is RPG-research-only and is NOT comparable to funding_trend's all-mechanism total. Bounds: limit 1-50 (default 20), offset 0-100000, fiscal years 1985-2100, ic 2-64 chars (NIH abbreviation or code, e.g. NCI or CA), sort_by one of composite | funding_scale | portfolio_breadth | new_grant_activity | avg_award_size.
입력 스키마
{
"type": "object",
"properties": {
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"ic": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Ic"
},
"sort_by": {
"default": "composite",
"title": "Sort By",
"type": "string"
},
"limit": {
"default": 20,
"title": "Limit",
"type": "integer"
},
"offset": {
"default": 0,
"title": "Offset",
"type": "integer"
}
},
"required": [],
"title": "rank_institutionsArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "rank_institutionsDictOutput"
}🟢get_pi_profile(profile_id, fiscal_year_start, fiscal_year_end, limit, offset)
Use this tool when the user asks about one researcher — 'how much NIH funding does Dr. X have', 'list this PI's grants', 'who does she collaborate with'. Run search_grants (or the find-pi-funding prompt) first: profile_id is the NIH RePORTER PI identifier carried in each result's pi_profile_id field and is not guessable. Read-only PI profile: grants, collaborators, publications, funding totals; the headline name/institution follow the PI's LATEST grant. A fiscal-year window with no grants returns the profile with total_grants=0, not an error. fiscal_year_start/fiscal_year_end scope EVERY aggregate section — grants, profile totals AND collaborators all report only that window (issue #342; collaborators previously ignored it and returned the all-time list). COLLABORATOR COVERAGE, read this before concluding a PI has no collaborators: the collaborator sidecar covers only SOME fiscal years, so an empty collaborators list can mean 'unknown for these years' rather than 'none'. meta.collaborator_coverage.window_covered tells you which: false = no data for any year in the window, and true with window_fully_covered=false means PARTIAL coverage; read missing_fiscal_years_in_window before treating an empty list as a complete answer. fiscal_years_with_collaborator_data lists the years that do have it. Bounds: profile_id 1-20 digits (^[0-9]{1,20}$), fiscal years 1985-2100, limit 1-50 (default 20), offset 0-100000.
입력 스키마
{
"type": "object",
"properties": {
"profile_id": {
"title": "Profile Id",
"type": "string"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"limit": {
"default": 20,
"title": "Limit",
"type": "integer"
},
"offset": {
"default": 0,
"title": "Offset",
"type": "integer"
}
},
"required": [
"profile_id"
],
"title": "get_pi_profileArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "get_pi_profileDictOutput"
}🟢get_institution_profile(entity_id, fiscal_year_start, fiscal_year_end)
Use this tool when the user asks about one named institution — 'what is Harvard's NIH funding history', 'which PIs does this university fund', 'what mechanisms does it win'. Call rank_institutions first to obtain the entity_id; search_grants results do NOT carry one. Read-only institution profile: funding history, mechanism mix, top PIs. fiscal_year_start/fiscal_year_end scope EVERY aggregate section — mechanism_mix, funding_trend AND top_pis all report only that fiscal-year window, and provenance.fiscal_year_window echoes the window actually applied; omit both arguments for all fiscal years. meta.found and profile.organization are deliberately window-independent (they answer existence/identity, so a real entity with no funding in the window stays found with its name). meta.found is always an explicit boolean: false (with profile=null) when the entity_id matches nothing in the corpus, true otherwise — branch on it instead of null-checking funding fields. funding_trend[].fiscal_year is int OR null: null means 'fiscal year not reported', never 0, and such a group belongs to no fiscal-year window, so it is absent from every scoped section. Bounds: entity_id 2-256 characters, fiscal years 1985-2100.
입력 스키마
{
"type": "object",
"properties": {
"entity_id": {
"title": "Entity Id",
"type": "string"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
}
},
"required": [
"entity_id"
],
"title": "get_institution_profileArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "get_institution_profileDictOutput"
}🟢funding_trend(fiscal_year_start, fiscal_year_end, ic, activity_code, institution)
Use this tool to get yearly NIH funding totals and grant counts. Returns a time series for the whole NIH, one Institute/Center, one activity code, or one institution. Use it when the user asks 'how much NIH funding was awarded in FY2020', 'how has NIH's budget changed over time', or 'plot R01 dollars by year'. total_funding spans ALL NIH mechanisms (funding_scope="all_mechanisms") and is therefore 1.5-1.7x larger than rank_institutions' RPG-research-only total_funding for the same slice — never cross-compare the two. Rows flag the partial current fiscal year. Bounds: fiscal years 1985-2100 and fiscal_year_start <= fiscal_year_end; ic, activity_code and institution are free-text filters with no length cap (matched as parameterized SQL, never interpolated). Not paginated: the whole requested year range is returned.
입력 스키마
{
"type": "object",
"properties": {
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"ic": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Ic"
},
"activity_code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Activity Code"
},
"institution": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Institution"
}
},
"required": [],
"title": "funding_trendArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "funding_trendDictOutput"
}🟢topic_trend(query, fiscal_year_start, fiscal_year_end)
Use this tool when the user asks how a research topic has trended over time — 'is CRISPR funding growing', 'how many p53 grants per year', 'when did NIH start funding long COVID'. Returns yearly project-row counts plus recorded award totals for a title keyword match; multi-word queries AND their words in any order. For the grants themselves use search_grants; for whole-NIH dollars use funding_trend. Bounds: query is REQUIRED, 2-64 characters; fiscal years 1985-2100 with fiscal_year_start <= fiscal_year_end. Not paginated.
입력 스키마
{
"type": "object",
"properties": {
"query": {
"title": "Query",
"type": "string"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
}
},
"required": [
"query"
],
"title": "topic_trendArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "topic_trendDictOutput"
}🟢activity_code_distribution(fiscal_year_start, fiscal_year_end, ic)
Use this tool when the user asks what KINDS of awards NIH (or one Institute) makes — 'how much goes to R01s vs training grants', 'what share of NCI's portfolio is centers', 'break NIH down by mechanism'. Returns counts and recorded totals per mechanism class (research / career / training / center / contract / intramural / ...) from ranking_core.classify. Use mechanism_mix instead when the question is about ONE institution. Bounds: fiscal years 1985-2100 with fiscal_year_start <= fiscal_year_end; ic is a free-text filter with no length cap. Not paginated.
입력 스키마
{
"type": "object",
"properties": {
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"ic": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Ic"
}
},
"required": [],
"title": "activity_code_distributionArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "activity_code_distributionDictOutput"
}🟢institution_concentration(fiscal_year_start, fiscal_year_end, ic)
Use this tool when the user asks how concentrated or unequal NIH funding is across institutions — 'is NIH money concentrated in a few universities', 'what share do the top 5 take', 'has inequality grown since 2000'. Returns gini, hhi, top5_share and the top-5 institutions over the competitive RPG-research scope (NULL awards excluded, never padded to $0). Bounds: fiscal years 1985-2100 with fiscal_year_start <= fiscal_year_end. Optional `ic` narrows the scope to one NIH institute: pass an IC abbreviation such as NCI or NIGMS. Any other string is matched as a NAME FRAGMENT and can span several institutes — check `meta.ic_scope.kind`, which reports `fragment` and how many institutes matched. Omit `ic` for all-NIH. Not paginated.
입력 스키마
{
"type": "object",
"properties": {
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"ic": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Ic"
}
},
"required": [],
"title": "institution_concentrationArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "institution_concentrationDictOutput"
}🟢mechanism_mix(entity_id, fiscal_year_start, fiscal_year_end)
Use this tool when the user asks what mix of award types ONE institution wins — 'is this university mostly R01s or centers', 'how much of its NIH money is training', 'compare two schools' portfolios'. Get the entity_id from rank_institutions first. With entity_id it returns that institution's whole NIH-administered portfolio (all mechanism classes); without it, the system-wide RPG-research breakdown — the two scopes are NOT comparable. Counts are grouped by comparability_group and never summed across classes. Bounds: fiscal years 1985-2100 with fiscal_year_start <= fiscal_year_end; entity_id is matched exactly (padded and unpadded DUNS spellings both resolve) with no length cap. Not paginated.
입력 스키마
{
"type": "object",
"properties": {
"entity_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Entity Id"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
}
},
"required": [],
"title": "mechanism_mixArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "mechanism_mixDictOutput"
}🟢ic_topic_cross(ic, query, fiscal_year_start, fiscal_year_end, match_strategy)
Use this tool when the user asks what ONE NIH Institute funds in a topic — 'what is NCI spending on immunotherapy', 'does NIMH fund psychedelics research', 'compare NIAID and NCI on vaccines' (call it once per Institute), or ic='ALL' for every IC at once. The response states which surface produced the numbers in match_strategy: 'rcdc' (official NIH RCDC categories, FY2008+) or 'text' (project_title, the topic_trend surface, used when the topic is not an RCDC category or the requested window is below the measured 50% RCDC-density minimum; provenance.rcdc_window_coverage reports the actual density). On the RCDC surface each grant is counted once even when several of its categories match. Bounds: ic and query are BOTH REQUIRED, 2-64 characters each; fiscal years 1985-2100 with fiscal_year_start <= fiscal_year_end. Not paginated.
입력 스키마
{
"type": "object",
"properties": {
"ic": {
"title": "Ic",
"type": "string"
},
"query": {
"title": "Query",
"type": "string"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
},
"match_strategy": {
"default": "auto",
"title": "Match Strategy",
"type": "string"
}
},
"required": [
"ic",
"query"
],
"title": "ic_topic_crossArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "ic_topic_crossDictOutput"
}🟢funding_growth(entity_id, fiscal_year_start, fiscal_year_end)
Use this tool when the user asks about the RATE of change rather than the level — 'is this university's NIH funding growing', 'what's the CAGR since 2015', 'who grew fastest'. Returns year-over-year growth plus a window CAGR for one institution (entity_id from rank_institutions) or all NIH. Both yoy_growth_pct and cagr_pct are PERCENTS (2.5905 means 2.5905%/yr, not 259%); the old fractional `cagr` key is gone. NULL awards are excluded, never padded to $0. meta echoes entity_id + organization so looped calls stay attributable. Use funding_trend for the raw yearly dollars. Bounds: fiscal years 1985-2100 with fiscal_year_start <= fiscal_year_end; entity_id is matched exactly with no length cap. Not paginated.
입력 스키마
{
"type": "object",
"properties": {
"entity_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Entity Id"
},
"fiscal_year_start": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year Start"
},
"fiscal_year_end": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Fiscal Year End"
}
},
"required": [],
"title": "funding_growthArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "funding_growthDictOutput"
}🟢search(query, limit, offset)
Use this tool when a Deep Research or connector client needs citation-shaped NIH grant hits for a natural-language query. Returns {"results": [{id, title, text, url}]} where id is the NIH project_num to pass to fetch and url is the public OpenNIH grant page. Each record is PROJECT-level, not project-year: ids are unique within a response, and the record always describes the project's CANONICAL row — its latest fiscal year, resolved WITHOUT the query filter, so it is exactly the row fetch returns for that id. READ THE RETURNED TITLE BEFORE QUOTING A HIT: one NIH project number can span many sub-awards with unrelated titles (center grants such as P41/P50/P01 are the common case), so the returned title and snippet MAY CONTAIN NONE OF YOUR QUERY TERMS — the sibling row that matched your text is not necessarily the canonical row, and the canonical row is the page the citation opens. Do not assert that a returned grant is 'about' your query on the strength of the match alone; use search_grants when you need the row that actually matched. This is the OpenAI Deep Research compatibility wrapper around search_grants — prefer search_grants directly when you need filters (institution, IC, fiscal year, activity code), funding totals, or provenance. Bounds: query is REQUIRED and matched over grant titles at 2-64 characters (a blank query returns no results instead of the whole corpus); limit 1-50 (default 20) distinct grants per page; offset 0-10000 skips matching project-year rows exactly as search_grants does, so stepping offset by limit walks the full result set page by page — results past the first page are reachable, not invisible. A page is the de-duplicated projection of that row window: one project number owning rows in two windows (multi-component awards emit one row per sub-project) can appear on more than one page, and ids are unique within each response.
입력 스키마
{
"type": "object",
"properties": {
"query": {
"title": "Query",
"type": "string"
},
"limit": {
"default": 20,
"title": "Limit",
"type": "integer"
},
"offset": {
"default": 0,
"title": "Offset",
"type": "integer"
}
},
"required": [
"query"
],
"title": "searchArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "searchDictOutput"
}🟢fetch(id)
Use this tool to retrieve the full record for one NIH grant after search returned its id. Returns {id, title, text, url, metadata} with url set to the public OpenNIH grant page so the client can cite it. This is the OpenAI Deep Research compatibility wrapper around the same canonical-row resolver search uses. The record is PROJECT-level, not project-year: when a project number owns several project-year rows the LATEST fiscal year is returned (metadata.matching_rows reports how many rows exist), and because both tools resolve it the same way this is always the row search described for that id. Bounds: id is REQUIRED and must be a full NIH project number matching ^[A-Z0-9-]{1,24}$ (e.g. 1R01CA123456-01A1); core project numbers and partial numbers do not match. An id that matches no row in the corpus raises an error — check source_status before concluding the grant does not exist, because grants RePORTER added after the snapshot cutoff are absent here rather than nonexistent.
입력 스키마
{
"type": "object",
"properties": {
"id": {
"title": "Id",
"type": "string"
}
},
"required": [
"id"
],
"title": "fetchArguments",
"additionalProperties": false
}출력 스키마
{
"type": "object",
"additionalProperties": true,
"title": "fetchDictOutput"
}커뮤니티
증거