# cyanheads/pubmed-mcp-server architecture

> Architecture diagram of the GitHub repository cyanheads/pubmed-mcp-server, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/cyanheads/pubmed-mcp-server
- Repository: https://github.com/cyanheads/pubmed-mcp-server

## Overview

This is a biomedical-literature MCP server: a client invokes registered tools to search and retrieve PubMed/Europe PMC records, resolve identifiers and citations, explore related work, and obtain full text or MeSH context. The entry point registers tools, a database-info resource, and a research-plan prompt, then initializes provider services. The README documents the full-text and related-article fallback tiers; those paths are reflected here, while unsampled tool implementations limit confirmation of finer-grained calls.

Main entry points: [`src/index.ts`](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/index.ts) (Server entry), [`src/services/ncbi/ncbi-service.ts`](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/ncbi-service.ts) (NCBI service), [`src/services/europe-pmc/europe-pmc-service.ts`](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/europe-pmc/europe-pmc-service.ts) (Europe PMC service), [`src/mcp-server/tools/definitions/find-related.tool.ts`](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/find-related.tool.ts) (Find related)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_server["MCP server"]
  node_entry["Server entry<br/>[index.ts]"]
  node_config["Server config<br/>[server-config.ts]"]
end

subgraph group_discovery["Search and discovery"]
  node_search["Search articles"]
  node_epmc_search["Europe PMC search"]
  node_spell["Spell check"]
  node_mesh["MeSH lookup"]
  node_related["Find related"]
end

subgraph group_retrieval["Article retrieval"]
  node_fetch_articles["Fetch articles"]
  node_fulltext["Fetch full text"]
  node_epmc_fetch["Fetch EPMC record"]
  node_citations["Format citations"]
  node_citation_lookup["Resolve citations"]
  node_convert_ids["Convert identifiers"]
  node_database_info["Database info"]
end

subgraph group_services["Provider services"]
  node_ncbi["NCBI service<br/>[ncbi-service.ts]"]
  node_ncbi_client["NCBI API client<br/>[api-client.ts]"]
  node_article_parser["PMC article parser"]
  node_epmc["Europe PMC service"]
  node_openalex["OpenAlex service"]
  node_unpaywall["Unpaywall service"]
end

subgraph group_guidance["Research support"]
  node_prompt["Research plan"]
end

node_client(("MCP client"))
node_pubmed_api["NCBI E-utilities"]
node_epmc_api["Europe PMC API"]
node_openalex_api["OpenAlex API"]
node_unpaywall_api["Unpaywall API"]

node_client -->|"connects"| node_entry
node_entry -->|"registers"| node_search
node_entry -->|"registers"| node_epmc_search
node_entry -->|"registers"| node_spell
node_entry -->|"registers"| node_mesh
node_entry -->|"registers"| node_related
node_entry -->|"registers"| node_fetch_articles
node_entry -->|"registers"| node_fulltext
node_entry -->|"registers"| node_epmc_fetch
node_entry -->|"registers"| node_citations
node_entry -->|"registers"| node_citation_lookup
node_entry -->|"registers"| node_convert_ids
node_entry -->|"registers"| node_database_info
node_entry -->|"registers"| node_prompt
node_entry -->|"loads"| node_config
node_search -->|"searches"| node_ncbi
node_spell -->|"checks spelling"| node_ncbi
node_mesh -->|"looks up terms"| node_ncbi
node_fetch_articles -->|"fetches records"| node_ncbi
node_citations -->|"fetches records"| node_ncbi
node_citation_lookup -->|"matches citations"| node_ncbi
node_convert_ids -->|"converts IDs"| node_ncbi
node_database_info -->|"reads metadata"| node_ncbi
node_epmc_search -->|"searches"| node_epmc
node_epmc_fetch -->|"fetches records"| node_epmc
node_related -->|"checks relations"| node_ncbi
node_related -.->|"fallback search"| node_epmc
node_related -.->|"fallback search"| node_openalex
node_fulltext -->|"tries PMC"| node_ncbi
node_fulltext -.->|"fallback fetch"| node_epmc
node_fulltext -.->|"fallback fetch"| node_unpaywall
node_ncbi -->|"requests"| node_ncbi_client
node_ncbi_client -->|"calls"| node_pubmed_api
node_epmc -->|"calls"| node_epmc_api
node_openalex -->|"calls"| node_openalex_api
node_unpaywall -->|"calls"| node_unpaywall_api
node_epmc -->|"parses JATS"| node_article_parser
node_ncbi -->|"parses PMC"| node_article_parser

click node_entry "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/index.ts"
click node_config "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/config/server-config.ts"
click node_search "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/search-articles.tool.ts"
click node_epmc_search "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/pubmed-europepmc-search.tool.ts"
click node_spell "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/spell-check.tool.ts"
click node_mesh "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/lookup-mesh.tool.ts"
click node_related "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/find-related.tool.ts"
click node_fetch_articles "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/fetch-articles.tool.ts"
click node_fulltext "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/fetch-fulltext.tool.ts"
click node_epmc_fetch "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.ts"
click node_citations "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/format-citations.tool.ts"
click node_citation_lookup "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/lookup-citation.tool.ts"
click node_convert_ids "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/convert-ids.tool.ts"
click node_database_info "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/resources/definitions/database-info.resource.ts"
click node_ncbi "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/ncbi-service.ts"
click node_ncbi_client "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/api-client.ts"
click node_article_parser "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/parsing/pmc-article-parser.ts"
click node_epmc "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/europe-pmc/europe-pmc-service.ts"
click node_openalex "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/openalex/openalex-service.ts"
click node_unpaywall "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/unpaywall/unpaywall-service.ts"
click node_prompt "https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/prompts/definitions/research-plan.prompt.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_config,node_client toneBlue
class node_search,node_epmc_search,node_spell,node_mesh,node_related toneAmber
class node_fetch_articles,node_fulltext,node_epmc_fetch,node_citations,node_citation_lookup,node_convert_ids,node_database_info,node_epmc_api,node_openalex_api,node_unpaywall_api toneMint
class node_ncbi,node_ncbi_client,node_article_parser,node_epmc,node_openalex,node_unpaywall toneRose
class node_prompt,node_pubmed_api toneIndigo
```

## Components

### MCP server

- [Server entry](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/index.ts): `src/index.ts`
- [Server config](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/config/server-config.ts): `src/config/server-config.ts`

### Search and discovery

- [Search articles](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/search-articles.tool.ts): `src/mcp-server/tools/definitions/search-articles.tool.ts`
- [Europe PMC search](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/pubmed-europepmc-search.tool.ts): `src/mcp-server/tools/definitions/pubmed-europepmc-search.tool.ts`
- [Spell check](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/spell-check.tool.ts): `src/mcp-server/tools/definitions/spell-check.tool.ts`
- [MeSH lookup](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/lookup-mesh.tool.ts): `src/mcp-server/tools/definitions/lookup-mesh.tool.ts`
- [Find related](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/find-related.tool.ts): `src/mcp-server/tools/definitions/find-related.tool.ts`

### Article retrieval

- [Fetch articles](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/fetch-articles.tool.ts): `src/mcp-server/tools/definitions/fetch-articles.tool.ts`
- [Fetch full text](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/fetch-fulltext.tool.ts): `src/mcp-server/tools/definitions/fetch-fulltext.tool.ts`
- [Fetch EPMC record](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.ts): `src/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.ts`
- [Format citations](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/format-citations.tool.ts): `src/mcp-server/tools/definitions/format-citations.tool.ts`
- [Resolve citations](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/lookup-citation.tool.ts): `src/mcp-server/tools/definitions/lookup-citation.tool.ts`
- [Convert identifiers](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/tools/definitions/convert-ids.tool.ts): `src/mcp-server/tools/definitions/convert-ids.tool.ts`
- [Database info](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/resources/definitions/database-info.resource.ts): `src/mcp-server/resources/definitions/database-info.resource.ts`

### Provider services

- [NCBI service](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/ncbi-service.ts): `src/services/ncbi/ncbi-service.ts`
- [NCBI API client](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/api-client.ts): `src/services/ncbi/api-client.ts`
- [PMC article parser](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/ncbi/parsing/pmc-article-parser.ts): `src/services/ncbi/parsing/pmc-article-parser.ts`
- [Europe PMC service](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/europe-pmc/europe-pmc-service.ts): `src/services/europe-pmc/europe-pmc-service.ts`
- [OpenAlex service](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/openalex/openalex-service.ts): `src/services/openalex/openalex-service.ts`
- [Unpaywall service](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/services/unpaywall/unpaywall-service.ts): `src/services/unpaywall/unpaywall-service.ts`

### Research support

- [Research plan](https://github.com/cyanheads/pubmed-mcp-server/blob/main/src/mcp-server/prompts/definitions/research-plan.prompt.ts): `src/mcp-server/prompts/definitions/research-plan.prompt.ts`

### Other components

- **MCP client**
- **NCBI E-utilities**
- **Europe PMC API**
- **OpenAlex API**
- **Unpaywall API**

## Connections

- MCP client → Server entry: connects
- Server entry → Search articles: registers
- Server entry → Europe PMC search: registers
- Server entry → Spell check: registers
- Server entry → MeSH lookup: registers
- Server entry → Find related: registers
- Server entry → Fetch articles: registers
- Server entry → Fetch full text: registers
- Server entry → Fetch EPMC record: registers
- Server entry → Format citations: registers
- Server entry → Resolve citations: registers
- Server entry → Convert identifiers: registers
- Server entry → Database info: registers
- Server entry → Research plan: registers
- Server entry → Server config: loads
- Search articles → NCBI service: searches
- Spell check → NCBI service: checks spelling
- MeSH lookup → NCBI service: looks up terms
- Fetch articles → NCBI service: fetches records
- Format citations → NCBI service: fetches records
- Resolve citations → NCBI service: matches citations
- Convert identifiers → NCBI service: converts IDs
- Database info → NCBI service: reads metadata
- Europe PMC search → Europe PMC service: searches
- Fetch EPMC record → Europe PMC service: fetches records
- Find related → NCBI service: checks relations
- Find related → Europe PMC service: fallback search
- Find related → OpenAlex service: fallback search
- Fetch full text → NCBI service: tries PMC
- Fetch full text → Europe PMC service: fallback fetch
- Fetch full text → Unpaywall service: fallback fetch
- NCBI service → NCBI API client: requests
- NCBI API client → NCBI E-utilities: calls
- Europe PMC service → Europe PMC API: calls
- OpenAlex service → OpenAlex API: calls
- Unpaywall service → Unpaywall API: calls
- Europe PMC service → PMC article parser: parses JATS
- NCBI service → PMC article parser: parses PMC
