@cyanheads/pubmed-mcp-server 1.1.2 → 1.2.1

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.
Files changed (41) hide show
  1. package/README.md +25 -24
  2. package/dist/config/index.js +39 -1
  3. package/dist/mcp-server/server.d.ts +0 -7
  4. package/dist/mcp-server/server.js +17 -53
  5. package/dist/mcp-server/tools/fetchPubMedContent/logic.d.ts +6 -2
  6. package/dist/mcp-server/tools/fetchPubMedContent/logic.js +102 -311
  7. package/dist/mcp-server/tools/fetchPubMedContent/registration.d.ts +1 -1
  8. package/dist/mcp-server/tools/fetchPubMedContent/registration.js +50 -18
  9. package/dist/mcp-server/tools/generatePubMedChart/logic.d.ts +9 -28
  10. package/dist/mcp-server/tools/generatePubMedChart/logic.js +137 -198
  11. package/dist/mcp-server/tools/generatePubMedChart/registration.d.ts +1 -1
  12. package/dist/mcp-server/tools/generatePubMedChart/registration.js +62 -27
  13. package/dist/mcp-server/tools/getPubMedArticleConnections/logic/citationFormatter.d.ts +1 -1
  14. package/dist/mcp-server/tools/getPubMedArticleConnections/logic/citationFormatter.js +3 -3
  15. package/dist/mcp-server/tools/getPubMedArticleConnections/logic/elinkHandler.d.ts +1 -1
  16. package/dist/mcp-server/tools/getPubMedArticleConnections/logic/index.d.ts +27 -4
  17. package/dist/mcp-server/tools/getPubMedArticleConnections/logic/index.js +59 -51
  18. package/dist/mcp-server/tools/getPubMedArticleConnections/logic/types.d.ts +1 -1
  19. package/dist/mcp-server/tools/getPubMedArticleConnections/registration.d.ts +1 -26
  20. package/dist/mcp-server/tools/getPubMedArticleConnections/registration.js +58 -62
  21. package/dist/mcp-server/tools/pubmedResearchAgent/logic.d.ts +2 -5
  22. package/dist/mcp-server/tools/pubmedResearchAgent/logic.js +7 -40
  23. package/dist/mcp-server/tools/pubmedResearchAgent/registration.d.ts +1 -1
  24. package/dist/mcp-server/tools/pubmedResearchAgent/registration.js +55 -19
  25. package/dist/mcp-server/tools/searchPubMedArticles/logic.d.ts +12 -10
  26. package/dist/mcp-server/tools/searchPubMedArticles/logic.js +68 -121
  27. package/dist/mcp-server/tools/searchPubMedArticles/registration.d.ts +1 -1
  28. package/dist/mcp-server/tools/searchPubMedArticles/registration.js +54 -21
  29. package/dist/mcp-server/transports/httpTransport.d.ts +0 -8
  30. package/dist/mcp-server/transports/httpTransport.js +57 -345
  31. package/dist/utils/security/rateLimiter.d.ts +4 -0
  32. package/dist/utils/security/rateLimiter.js +4 -0
  33. package/package.json +7 -15
  34. package/dist/mcp-server/resources/echoResource/echoResourceLogic.d.ts +0 -79
  35. package/dist/mcp-server/resources/echoResource/echoResourceLogic.js +0 -82
  36. package/dist/mcp-server/resources/echoResource/index.d.ts +0 -13
  37. package/dist/mcp-server/resources/echoResource/index.js +0 -13
  38. package/dist/mcp-server/resources/echoResource/registration.d.ts +0 -30
  39. package/dist/mcp-server/resources/echoResource/registration.js +0 -168
  40. package/dist/mcp-server/tools/getPubMedArticleConnections/logic.d.ts +0 -6
  41. package/dist/mcp-server/tools/getPubMedArticleConnections/logic.js +0 -6
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-^5.8.3-blue.svg)](https://www.typescriptlang.org/)
4
4
  [![Model Context Protocol](https://img.shields.io/badge/MCP%20SDK-^1.12.1-green.svg)](https://modelcontextprotocol.io/)
5
- [![Version](https://img.shields.io/badge/Version-1.0.16-blue.svg)](./CHANGELOG.md)
5
+ [![Version](https://img.shields.io/badge/Version-1.2.1-blue.svg)](./CHANGELOG.md)
6
6
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Status](https://img.shields.io/badge/Status-Stable-green.svg)](https://github.com/cyanheads/pubmed-mcp-server/issues)
8
8
  [![GitHub](https://img.shields.io/github/stars/cyanheads/pubmed-mcp-server?style=social)](https://github.com/cyanheads/pubmed-mcp-server)
@@ -17,13 +17,13 @@ Built on the [`cyanheads/mcp-ts-template`](https://github.com/cyanheads/mcp-ts-t
17
17
 
18
18
  This server equips your AI with specialized tools to interact with PubMed:
19
19
 
20
- | Tool Name | Description | Key Features |
21
- | :-------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
- | [`search_pubmed_articles`](./src/mcp-server/tools/searchPubMedArticles/) | Searches PubMed for articles based on your query. (See [Example](./examples/search_pubmed_articles_example.md)) | - Filter by max results, sort order, date range, publication types.<br/>- Uses NCBI ESearch for PMIDs.<br/>- Optionally fetches brief summaries (title, authors, source, dates) via ESummary. |
23
- | [`fetch_pubmed_content`](./src/mcp-server/tools/fetchPubMedContent/) | Retrieves detailed information for PubMed articles. Can use a list of PMIDs or ESearch history (queryKey/webEnv) with pagination. (See [Example](./examples/fetch_pubmed_content_example.md)) | - Flexible `detailLevel`: `abstract_plus` (parsed details, optional MeSH/grant), `full_xml` (JSON representation of the PubMedArticle XML structure), `medline_text` (MEDLINE format), `citation_data` (minimal for citations).<br/>- Supports direct PMID list or `queryKey`/`webEnv` from ESearch history.<br/>- Supports `retstart`/`retmax` for pagination with history.<br/>- Uses NCBI EFetch. |
24
- | [`get_pubmed_article_connections`](./src/mcp-server/tools/getPubMedArticleConnections/) | Finds related articles (cited by, similar, references) or formats citations for a PMID. (See [Ex.1](./examples/get_pubmed_article_connections_1.md), [Ex.2](./examples/get_pubmed_article_connections_2.md)) | - Uses NCBI ELink for relationships.<br/>- Uses NCBI EFetch for citation data (RIS, BibTeX, APA, MLA).<br/>- Filter by max related results. |
25
- | [`pubmed_research_agent`](./src/mcp-server/tools/pubmedResearchAgent/) | Generates a standardized JSON research plan outline from component details. (See [Example](./examples/pubmed_research_agent_example.md)) | - Accepts granular inputs for all research phases.<br/>- Optionally embeds instructive prompts for agent execution.<br/>- Structures rough ideas into a formal, machine-readable plan for further processing. |
26
- | [`generate_pubmed_chart`](./src/mcp-server/tools/generatePubMedChart/) | Generates a chart image (PNG) from given input data. (See [Bar](./examples/generate_pubmed_chart_example_bar.svg), [Line](./examples/generate_pubmed_chart_example_line.svg), [Scatter](./examples/generate_pubmed_chart_example_scatter.svg)) | - Supports 'bar', 'line', and 'scatter' chart types.<br/>- Takes data values and field specifications for axes and encoding.<br/>- Constructs a Vega-Lite specification internally and renders it as a PNG. |
20
+ | Tool Name | Description | Key Features |
21
+ | :-------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
+ | [`search_pubmed_articles`](./src/mcp-server/tools/searchPubMedArticles/) | Searches PubMed for articles based on your query. (See [Example](./examples/search_pubmed_articles_example.md)) | - Filter by max results, sort order, date range, publication types.<br/>- Uses NCBI ESearch for PMIDs.<br/>- Optionally fetches brief summaries (title, authors, source, dates) via ESummary. |
23
+ | [`fetch_pubmed_content`](./src/mcp-server/tools/fetchPubMedContent/) | Retrieves detailed information for PubMed articles. Can use a list of PMIDs or ESearch history (queryKey/webEnv) with pagination. (See [Example](./examples/fetch_pubmed_content_example.md)) | - Flexible `detailLevel`: `abstract_plus` (parsed details, optional MeSH/grant), `full_xml` (JSON representation of the PubMedArticle XML structure), `medline_text` (MEDLINE format), `citation_data` (minimal for citations).<br/>- Supports direct PMID list or `queryKey`/`webEnv` from ESearch history.<br/>- Supports `retstart`/`retmax` for pagination with history.<br/>- Uses NCBI EFetch. |
24
+ | [`get_pubmed_article_connections`](./src/mcp-server/tools/getPubMedArticleConnections/) | Finds related articles (cited by, similar, references) or formats citations for a PMID. (See [Ex.1](./examples/get_pubmed_article_connections_1.md), [Ex.2](./examples/get_pubmed_article_connections_2.md)) | - Uses NCBI ELink for relationships.<br/>- Uses NCBI EFetch for citation data (RIS, BibTeX, APA, MLA).<br/>- Filter by max related results. |
25
+ | [`pubmed_research_agent`](./src/mcp-server/tools/pubmedResearchAgent/) | Generates a standardized JSON research plan outline from component details. (See [Example](./examples/pubmed_research_agent_example.md)) | - Accepts granular inputs for all research phases.<br/>- Optionally embeds instructive prompts for agent execution.<br/>- Structures rough ideas into a formal, machine-readable plan for further processing. |
26
+ | [`generate_pubmed_chart`](./src/mcp-server/tools/generatePubMedChart/) | Generates a chart image (PNG) from given input data. (See [Examples](./examples/generate_pubmed_chart)) | - Supports a wide range of chart types: `bar`, `line`, `scatter`, `pie`, `doughnut`, `bubble`, `radar`, and `polarArea`.<br/>- Takes data values and field specifications for axes and series.<br/>- Uses `Chart.js` and `chartjs-node-canvas` for direct server-side rendering. |
27
27
 
28
28
  ---
29
29
 
@@ -56,14 +56,15 @@ Built on the robust `mcp-ts-template`, this server provides a standardized, secu
56
56
 
57
57
  Leverages the robust utilities provided by the `mcp-ts-template`:
58
58
 
59
- - **Logging**: Structured, configurable logging (file rotation, console, MCP notifications) with sensitive data redaction.
59
+ - **Logging**: Structured, configurable logging (file rotation, stdout JSON, MCP notifications) with sensitive data redaction.
60
60
  - **Error Handling**: Centralized error processing, standardized error types (`McpError`), and automatic logging.
61
61
  - **Configuration**: Environment variable loading (`dotenv`) with comprehensive validation.
62
62
  - **Input Validation/Sanitization**: Uses `zod` for schema validation and custom sanitization logic.
63
- - **Request Context**: Tracking and correlation of operations via unique request IDs.
63
+ - **Request Context**: Tracking and correlation of operations via unique request IDs using `AsyncLocalStorage`.
64
64
  - **Type Safety**: Strong typing enforced by TypeScript and Zod schemas.
65
- - **HTTP Transport Option**: Built-in Express server with SSE, session management, CORS support, and JWT authentication.
66
- - **Rate Limiting**: Built-in request queuing and delay management for NCBI API compliance.
65
+ - **HTTP Transport**: High-performance HTTP server using **Hono**, featuring session management with garbage collection, CORS, and IP-based rate limiting.
66
+ - **Authentication**: Robust authentication layer supporting JWT and OAuth 2.1, with fine-grained scope enforcement.
67
+ - **Deployment**: Multi-stage `Dockerfile` for creating small, secure production images with native dependency support.
67
68
 
68
69
  ### PubMed Integration
69
70
 
@@ -72,7 +73,7 @@ Leverages the robust utilities provided by the `mcp-ts-template`:
72
73
  - **Full Article Metadata**: Retrieve complete publication data including abstracts, authors, affiliations, journal information, DOIs, and citation data.
73
74
  - **Citation Network Analysis**: Find related articles, citing articles, and reference lists through ELink integration.
74
75
  - **Research Planning**: Generate structured research plans with automated literature search strategies.
75
- - **Data Visualization**: Create PNG charts from publication metadata (bar charts, line graphs, scatter plots).
76
+ - **Data Visualization**: Create PNG charts from publication metadata (bar, line, scatter, pie, bubble, radar, polarArea).
76
77
  - **Multiple Output Formats**: Support for JSON, MEDLINE text, full XML, and formatted citations (RIS, BibTeX, APA, MLA).
77
78
  - **Batch Processing**: Efficient handling of multiple PMIDs with pagination support.
78
79
 
@@ -82,6 +83,7 @@ Leverages the robust utilities provided by the `mcp-ts-template`:
82
83
 
83
84
  - [Node.js (>=18.0.0)](https://nodejs.org/)
84
85
  - [npm](https://www.npmjs.com/) (comes with Node.js)
86
+ - [Docker](https://www.docker.com/) (optional, for containerized deployment)
85
87
  - **NCBI API Key** (recommended for higher rate limits) - [Get one here](https://ncbiinsights.ncbi.nlm.nih.gov/2017/11/02/new-api-keys-for-the-e-utilities/)
86
88
 
87
89
  ### Install via npm (recommended)
@@ -124,21 +126,23 @@ Configure the server using environment variables. These environmental variables
124
126
  | `MCP_HTTP_HOST` | Host address for the HTTP server (if `MCP_TRANSPORT_TYPE=http`). | `127.0.0.1` |
125
127
  | `MCP_ALLOWED_ORIGINS` | Comma-separated list of allowed origins for CORS (if `MCP_TRANSPORT_TYPE=http`). | (none) |
126
128
  | `MCP_LOG_LEVEL` | Logging level (`debug`, `info`, `notice`, `warning`, `error`, `crit`, `alert`, `emerg`). | `debug` |
127
- | `MCP_AUTH_SECRET_KEY` | **Required for HTTP transport.** Minimum 32-character secret key for JWT authentication. | (none) |
129
+ | `LOG_OUTPUT_MODE` | Logging output mode: `file` or `stdout`. | `file` |
130
+ | `MCP_AUTH_MODE` | Authentication mode for HTTP: `jwt` or `oauth`. | `jwt` |
131
+ | `MCP_AUTH_SECRET_KEY` | **Required for `jwt` auth.** Minimum 32-character secret key for JWT authentication. | (none) |
128
132
  | `NCBI_API_KEY` | **Recommended.** Your NCBI API Key for higher rate limits and reliable access. | (none) |
129
133
  | `NCBI_TOOL_IDENTIFIER` | Tool identifier for NCBI E-utility requests. | `@cyanheads/pubmed-mcp-server` |
130
- | `LOGS_DIR` | Directory for log file storage. | `logs/` |
134
+ | `LOGS_DIR` | Directory for log file storage (if `LOG_OUTPUT_MODE=file`). | `logs/` |
131
135
 
132
136
  ### MCP Client Settings
133
137
 
134
- Add to your MCP client settings (e.g., `cline_mcp_settings.json`):
138
+ Add the following to your MCP client's configuration file (e.g., `cline_mcp_settings.json`). This configuration uses `npx` to run the server, which will automatically install the package if not already present:
135
139
 
136
140
  ```json
137
141
  {
138
142
  "mcpServers": {
139
143
  "pubmed-mcp-server": {
140
- "command": "node",
141
- "args": ["/path/to/your/pubmed-mcp-server/dist/index.js"],
144
+ "command": "npx",
145
+ "args": ["@cyanheads/pubmed-mcp-server"],
142
146
  "env": {
143
147
  "NCBI_API_KEY": "your_ncbi_api_key_here"
144
148
  },
@@ -149,8 +153,6 @@ Add to your MCP client settings (e.g., `cline_mcp_settings.json`):
149
153
  }
150
154
  ```
151
155
 
152
- **Note**: You can see [mcp.json](mcp.json) for an example MCP client configuration file that includes the PubMed MCP Server.
153
-
154
156
  ## Project Structure
155
157
 
156
158
  The codebase follows a modular structure within the `src/` directory:
@@ -166,8 +168,7 @@ src/
166
168
  │ ├── resources/ # MCP Resource implementations
167
169
  │ └── tools/ # MCP Tool implementations (subdirs per tool)
168
170
  ├── services/ # External service integrations
169
- ├── NCBI/ # NCBI E-utilities API client and parsing
170
- │ └── llm-providers/ # LLM provider integrations (optional)
171
+ └── NCBI/ # NCBI E-utilities API client and parsing
171
172
  ├── types-global/ # Shared TypeScript type definitions
172
173
  └── utils/ # Common utility functions (logger, error handler, etc.)
173
174
  ```
@@ -184,7 +185,7 @@ The PubMed MCP Server provides a comprehensive suite of tools for biomedical lit
184
185
  | `fetch_pubmed_content` | Fetches detailed article information using PMIDs or search history. | `pmids?`, `queryKey?`, `webEnv?`, `detailLevel?`, `includeMeshTerms?`, `includeGrantInfo?` |
185
186
  | `get_pubmed_article_connections` | Finds related articles, citations, and references for a given PMID. | `sourcePmid`, `relationshipType?`, `maxRelatedResults?`, `citationStyles?` |
186
187
  | `pubmed_research_agent` | Generates structured research plans with literature search strategies. | `project_title_suggestion`, `primary_research_goal`, `research_keywords`, `organism_focus?`, `p1_*`, etc. |
187
- | `generate_pubmed_chart` | Creates customizable PNG charts from structured publication data. | `chartType`, `dataValues`, `xField`, `yField`, `title?`, `colorField?`, `seriesField?`, `sizeField?` |
188
+ | `generate_pubmed_chart` | Creates customizable PNG charts from structured publication data. | `chartType`, `dataValues`, `xField`, `yField`, `title?`, `seriesField?`, `sizeField?` |
188
189
 
189
190
  _Note: All tools support comprehensive error handling and return structured JSON responses._
190
191
 
@@ -196,7 +197,7 @@ Comprehensive usage examples are available in the [`examples/`](examples/) direc
196
197
  - [Fetch Article Content](examples/fetch_pubmed_content_example.md)
197
198
  - [Article Connections](examples/get_pubmed_article_connections_1.md)
198
199
  - [Research Planning](examples/pubmed_research_agent_example.md)
199
- - [Chart Generation](examples/) - Generated chart examples (bar, line, scatter) are available in the `examples/` directory.
200
+ - [Chart Generation](./examples/generate_pubmed_chart/) - Generated chart examples (bar, line, scatter, pie, bubble, radar, polarArea) are available in the `examples/generate_pubmed_chart/` directory.
200
201
 
201
202
  ## Development
202
203
 
@@ -71,7 +71,8 @@ catch (error) {
71
71
  * Provides type safety, validation, defaults, and clear error messages.
72
72
  * @private
73
73
  */
74
- const EnvSchema = z.object({
74
+ const EnvSchema = z
75
+ .object({
75
76
  /** Optional. The desired name for the MCP server. Defaults to `package.json` name. */
76
77
  MCP_SERVER_NAME: z.string().optional(),
77
78
  /** Optional. The version of the MCP server. Defaults to `package.json` version. */
@@ -146,6 +147,43 @@ const EnvSchema = z.object({
146
147
  NCBI_REQUEST_DELAY_MS: z.coerce.number().int().positive().optional(), // Default will be set conditionally
147
148
  /** Maximum number of retries for failed NCBI requests. Default: 3. */
148
149
  NCBI_MAX_RETRIES: z.coerce.number().int().nonnegative().default(3),
150
+ })
151
+ .superRefine((data, ctx) => {
152
+ // Rule 1: MCP_AUTH_SECRET_KEY is required for http transport in production with jwt auth
153
+ if (data.NODE_ENV === "production" &&
154
+ data.MCP_TRANSPORT_TYPE === "http" &&
155
+ data.MCP_AUTH_MODE === "jwt" &&
156
+ !data.MCP_AUTH_SECRET_KEY) {
157
+ ctx.addIssue({
158
+ code: z.ZodIssueCode.custom,
159
+ path: ["MCP_AUTH_SECRET_KEY"],
160
+ message: "MCP_AUTH_SECRET_KEY is required for 'jwt' auth with 'http' transport in a 'production' environment.",
161
+ });
162
+ }
163
+ // Rule 2: Core OAuth variables are required when MCP_AUTH_MODE is 'oauth'
164
+ if (data.MCP_AUTH_MODE === "oauth") {
165
+ if (!data.OAUTH_ISSUER_URL) {
166
+ ctx.addIssue({
167
+ code: z.ZodIssueCode.custom,
168
+ path: ["OAUTH_ISSUER_URL"],
169
+ message: "OAUTH_ISSUER_URL is required when MCP_AUTH_MODE is 'oauth'.",
170
+ });
171
+ }
172
+ if (!data.OAUTH_AUDIENCE) {
173
+ ctx.addIssue({
174
+ code: z.ZodIssueCode.custom,
175
+ path: ["OAUTH_AUDIENCE"],
176
+ message: "OAUTH_AUDIENCE is required when MCP_AUTH_MODE is 'oauth'.",
177
+ });
178
+ }
179
+ if (!data.OAUTH_JWKS_URI) {
180
+ ctx.addIssue({
181
+ code: z.ZodIssueCode.custom,
182
+ path: ["OAUTH_JWKS_URI"],
183
+ message: "OAUTH_JWKS_URI is required when MCP_AUTH_MODE is 'oauth'.",
184
+ });
185
+ }
186
+ }
149
187
  });
150
188
  const parsedEnv = EnvSchema.safeParse(process.env);
151
189
  if (!parsedEnv.success) {
@@ -18,12 +18,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
18
18
  /**
19
19
  * Main application entry point. Initializes and starts the MCP server.
20
20
  * Orchestrates server startup, transport selection, and top-level error handling.
21
- *
22
- * MCP Spec Relevance:
23
- * - Manages server startup, leading to a server ready for MCP messages.
24
- * - Handles critical startup failures, ensuring appropriate process exit.
25
- *
26
- * @returns For 'stdio', resolves with `McpServer`. For 'http', resolves with `http.Server`.
27
- * Rejects on critical failure, leading to process exit.
28
21
  */
29
22
  export declare function initializeAndStartServer(): Promise<void | McpServer | ServerType>;
@@ -16,6 +16,7 @@
16
16
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
17
17
  import { config, environment } from "../config/index.js";
18
18
  import { ErrorHandler, logger, requestContextService } from "../utils/index.js";
19
+ import { BaseErrorCode } from "../types-global/errors.js";
19
20
  import { registerFetchPubMedContentTool } from "./tools/fetchPubMedContent/index.js";
20
21
  import { registerGeneratePubMedChartTool } from "./tools/generatePubMedChart/index.js";
21
22
  import { registerGetPubMedArticleConnectionsTool } from "./tools/getPubMedArticleConnections/index.js";
@@ -34,10 +35,8 @@ import { connectStdioTransport } from "./transports/stdioTransport.js";
34
35
  * - Capabilities Declaration: Declares supported features (logging, dynamic resources/tools).
35
36
  * - Resource/Tool Registration: Makes capabilities discoverable and invocable.
36
37
  *
37
- * Design Note: This factory is called once for 'stdio' transport and per session for 'http' transport.
38
- *
39
38
  * @returns A promise resolving with the configured `McpServer` instance.
40
- * @throws {Error} If any resource or tool registration fails.
39
+ * @throws {McpError} If any resource or tool registration fails.
41
40
  * @private
42
41
  */
43
42
  async function createMcpServerInstance() {
@@ -50,18 +49,6 @@ async function createMcpServerInstance() {
50
49
  appVersion: config.mcpServerVersion,
51
50
  environment,
52
51
  });
53
- logger.debug("Instantiating McpServer with capabilities", {
54
- ...context,
55
- serverInfo: {
56
- name: config.mcpServerName,
57
- version: config.mcpServerVersion,
58
- },
59
- capabilities: {
60
- logging: {},
61
- resources: { listChanged: true },
62
- tools: { listChanged: true },
63
- },
64
- });
65
52
  const server = new McpServer({ name: config.mcpServerName, version: config.mcpServerVersion }, {
66
53
  capabilities: {
67
54
  logging: {}, // Server can receive logging/setLevel and send notifications/message
@@ -69,7 +56,7 @@ async function createMcpServerInstance() {
69
56
  tools: { listChanged: true }, // Server supports dynamic tool lists
70
57
  },
71
58
  });
72
- try {
59
+ await ErrorHandler.tryCatch(async () => {
73
60
  logger.debug("Registering resources and tools...", context);
74
61
  // IMPORTANT: Keep tool registrations in alphabetical order. Do not remove this comment.
75
62
  await registerFetchPubMedContentTool(server);
@@ -77,17 +64,13 @@ async function createMcpServerInstance() {
77
64
  await registerGetPubMedArticleConnectionsTool(server);
78
65
  await registerPubMedResearchAgentTool(server);
79
66
  await registerSearchPubMedArticlesTool(server);
80
- // Add other tool/resource registrations here
81
67
  logger.info("Resources and tools registered successfully", context);
82
- }
83
- catch (err) {
84
- logger.error("Failed to register resources/tools", {
85
- ...context,
86
- error: err instanceof Error ? err.message : String(err),
87
- stack: err instanceof Error ? err.stack : undefined,
88
- });
89
- throw err;
90
- }
68
+ }, {
69
+ operation: "registerAllTools",
70
+ context,
71
+ errorCode: BaseErrorCode.INITIALIZATION_FAILED,
72
+ critical: true,
73
+ });
91
74
  return server;
92
75
  }
93
76
  /**
@@ -98,7 +81,7 @@ async function createMcpServerInstance() {
98
81
  * - Transport Connection: Calls dedicated functions for chosen transport.
99
82
  * - Server Instance Lifecycle: Single instance for 'stdio', per-session for 'http'.
100
83
  *
101
- * @returns Resolves with `McpServer` for 'stdio', `http.Server` for 'http', or `void` if http transport manages its own lifecycle without returning a server.
84
+ * @returns Resolves with `McpServer` for 'stdio', `http.Server` for 'http', or `void`.
102
85
  * @throws {Error} If transport type is unsupported or setup fails.
103
86
  * @private
104
87
  */
@@ -110,32 +93,18 @@ async function startTransport() {
110
93
  });
111
94
  logger.info(`Starting transport: ${transportType}`, context);
112
95
  if (transportType === "http") {
113
- logger.debug("Delegating to startHttpTransport...", context);
114
- // For HTTP, startHttpTransport now returns the http.Server instance.
115
- const httpServerInstance = await startHttpTransport(createMcpServerInstance, context);
116
- return httpServerInstance;
96
+ return startHttpTransport(createMcpServerInstance, context);
117
97
  }
118
98
  if (transportType === "stdio") {
119
- logger.debug("Creating single McpServer instance for stdio transport...", context);
120
99
  const server = await createMcpServerInstance();
121
- logger.debug("Delegating to connectStdioTransport...", context);
122
100
  await connectStdioTransport(server, context);
123
- return server; // Return the single McpServer instance for stdio.
101
+ return server;
124
102
  }
125
- // Should not be reached if config validation is effective.
126
- logger.fatal(`Unsupported transport type configured: ${transportType}`, context);
127
103
  throw new Error(`Unsupported transport type: ${transportType}. Must be 'stdio' or 'http'.`);
128
104
  }
129
105
  /**
130
106
  * Main application entry point. Initializes and starts the MCP server.
131
107
  * Orchestrates server startup, transport selection, and top-level error handling.
132
- *
133
- * MCP Spec Relevance:
134
- * - Manages server startup, leading to a server ready for MCP messages.
135
- * - Handles critical startup failures, ensuring appropriate process exit.
136
- *
137
- * @returns For 'stdio', resolves with `McpServer`. For 'http', resolves with `http.Server`.
138
- * Rejects on critical failure, leading to process exit.
139
108
  */
140
109
  export async function initializeAndStartServer() {
141
110
  const context = requestContextService.createRequestContext({
@@ -148,18 +117,13 @@ export async function initializeAndStartServer() {
148
117
  return result;
149
118
  }
150
119
  catch (err) {
151
- logger.fatal("Critical error during MCP server initialization.", {
152
- ...context,
153
- error: err instanceof Error ? err.message : String(err),
154
- stack: err instanceof Error ? err.stack : undefined,
155
- });
156
- // Ensure the error is handled by our centralized handler, which might log more details or perform cleanup.
157
120
  ErrorHandler.handleError(err, {
158
- operation: "initializeAndStartServer", // More specific operation
159
- context: context, // Pass the existing context
160
- critical: true, // This is a critical failure
121
+ operation: "initializeAndStartServer",
122
+ context: context,
123
+ critical: true,
124
+ rethrow: false, // Ensure we don't rethrow, so we can exit gracefully.
161
125
  });
162
126
  logger.info("Exiting process due to critical initialization error.", context);
163
- process.exit(1); // Exit with a non-zero code to indicate failure.
127
+ process.exit(1);
164
128
  }
165
129
  }
@@ -5,7 +5,6 @@
5
5
  * MEDLINE text, and citation data.
6
6
  * @module src/mcp-server/tools/fetchPubMedContent/logic
7
7
  */
8
- import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
9
8
  import { z } from "zod";
10
9
  import { RequestContext } from "../../../utils/index.js";
11
10
  export declare const FetchPubMedContentInputSchema: z.ZodEffects<z.ZodObject<{
@@ -60,4 +59,9 @@ export declare const FetchPubMedContentInputSchema: z.ZodEffects<z.ZodObject<{
60
59
  outputFormat?: "json" | "raw_text" | undefined;
61
60
  }>;
62
61
  export type FetchPubMedContentInput = z.infer<typeof FetchPubMedContentInputSchema>;
63
- export declare function fetchPubMedContentLogic(input: FetchPubMedContentInput, parentRequestContext: RequestContext): Promise<CallToolResult>;
62
+ export type FetchPubMedContentOutput = {
63
+ content: string;
64
+ articlesReturned: number;
65
+ eFetchUrl: string;
66
+ };
67
+ export declare function fetchPubMedContentLogic(input: FetchPubMedContentInput, parentRequestContext: RequestContext): Promise<FetchPubMedContentOutput>;