@cyanheads/pubmed-mcp-server 2.7.7 → 2.7.8
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 +365 -0
- package/CLAUDE.md +2 -2
- package/README.md +1 -1
- package/dist/mcp-server/tools/definitions/convert-ids.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/convert-ids.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/find-related.tool.d.ts +4 -3
- package/dist/mcp-server/tools/definitions/find-related.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/find-related.tool.js +17 -9
- package/dist/mcp-server/tools/definitions/find-related.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/format-citations.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/format-citations.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.d.ts +3 -2
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.js +7 -8
- package/dist/mcp-server/tools/definitions/lookup-mesh.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts +12 -11
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js +26 -13
- package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts +27 -26
- package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-articles.tool.js +51 -44
- package/dist/mcp-server/tools/definitions/search-articles.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/spell-check.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/spell-check.tool.d.ts.map +1 -1
- package/package.json +5 -4
- package/server.json +3 -3
package/AGENTS.md
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Agent Protocol
|
|
2
|
+
|
|
3
|
+
**Server:** @cyanheads/pubmed-mcp-server
|
|
4
|
+
**Version:** 2.7.8
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.16`
|
|
6
|
+
**Engines:** Bun ≥1.3.2, Node ≥24.0.0
|
|
7
|
+
|
|
8
|
+
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What's Next?
|
|
13
|
+
|
|
14
|
+
When the user asks what to do next, what's left, or needs direction, suggest relevant options based on the current project state:
|
|
15
|
+
|
|
16
|
+
1. **Re-run the `setup` skill** — ensures CLAUDE.md, skills, structure, and metadata are populated and up to date with the current codebase
|
|
17
|
+
2. **Run the `design-mcp-server` skill** — if the tool/resource surface hasn't been mapped yet, work through domain design
|
|
18
|
+
3. **Add tools/resources/prompts** — scaffold new definitions using the `add-tool`, `add-app-tool`, `add-resource`, `add-prompt` skills
|
|
19
|
+
4. **Add services** — scaffold domain service integrations using the `add-service` skill
|
|
20
|
+
5. **Add tests** — scaffold tests for existing definitions using the `add-test` skill
|
|
21
|
+
6. **Field-test definitions** — exercise tools/resources/prompts with real inputs using the `field-test` skill, get a report of issues and pain points
|
|
22
|
+
7. **Run `devcheck`** — lint, format, typecheck, and security audit
|
|
23
|
+
8. **Run the `security-pass` skill** — audit handlers for MCP-specific security gaps: output injection, scope blast radius, input sinks, tenant isolation
|
|
24
|
+
9. **Run the `polish-docs-meta` skill** — finalize README, CHANGELOG, metadata, and agent protocol for shipping
|
|
25
|
+
10. **Run the `maintenance` skill** — investigate changelogs, adopt upstream changes, and sync skills after `bun update --latest`
|
|
26
|
+
|
|
27
|
+
Tailor suggestions to what's actually missing or stale — don't recite the full list every time.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Core Rules
|
|
32
|
+
|
|
33
|
+
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
34
|
+
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
35
|
+
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
36
|
+
- **Check `ctx.elicit` / `ctx.sample`** for presence before calling.
|
|
37
|
+
- **Secrets in env vars only** — never hardcoded.
|
|
38
|
+
- **Close the loop on issues.** When implementing work tracked by a GitHub issue, comment on the issue with what landed and close it. Do both — a comment without a close leaves stale issues open; a close without a comment leaves no record of what shipped. The comment is for future readers — state the concrete changes, not the conversation that produced them.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Patterns
|
|
43
|
+
|
|
44
|
+
### Tool
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
48
|
+
import { getNcbiService } from '@/services/ncbi/ncbi-service.js';
|
|
49
|
+
|
|
50
|
+
export const spellCheckTool = tool('pubmed_spell_check', {
|
|
51
|
+
description: "Spell-check a query and get NCBI's suggested correction.",
|
|
52
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
53
|
+
|
|
54
|
+
input: z.object({
|
|
55
|
+
query: z.string().min(2).describe('PubMed search query to spell-check'),
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
output: z.object({
|
|
59
|
+
original: z.string().describe('Original query'),
|
|
60
|
+
corrected: z.string().describe('Corrected query (same as original if no suggestion)'),
|
|
61
|
+
hasSuggestion: z.boolean().describe('Whether NCBI suggested a correction'),
|
|
62
|
+
}),
|
|
63
|
+
|
|
64
|
+
async handler(input, ctx) {
|
|
65
|
+
ctx.log.info('Executing pubmed_spell_check tool', { query: input.query });
|
|
66
|
+
const result = await getNcbiService().eSpell({ db: 'pubmed', term: input.query });
|
|
67
|
+
return { original: result.original, corrected: result.corrected, hasSuggestion: result.hasSuggestion };
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
format: (result) => {
|
|
71
|
+
if (result.hasSuggestion) {
|
|
72
|
+
return [{ type: 'text', text: `**Suggested correction:** "${result.corrected}" (original: "${result.original}")` }];
|
|
73
|
+
}
|
|
74
|
+
return [{ type: 'text', text: `No spelling corrections suggested for: "${result.original}"` }];
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Resource
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { resource, z } from '@cyanheads/mcp-ts-core';
|
|
83
|
+
import { getNcbiService } from '@/services/ncbi/ncbi-service.js';
|
|
84
|
+
|
|
85
|
+
export const databaseInfoResource = resource('pubmed://database/info', {
|
|
86
|
+
name: 'database-info',
|
|
87
|
+
title: 'PubMed Database Info',
|
|
88
|
+
description: 'PubMed database metadata including field list, last update date, and record count.',
|
|
89
|
+
mimeType: 'application/json',
|
|
90
|
+
params: z.object({}),
|
|
91
|
+
output: OutputSchema,
|
|
92
|
+
|
|
93
|
+
async handler(_params, ctx) {
|
|
94
|
+
ctx.log.info('Fetching PubMed database info');
|
|
95
|
+
const raw = await getNcbiService().eInfo({ db: 'pubmed' });
|
|
96
|
+
// ... parse XML response ...
|
|
97
|
+
return { dbName, description, count, lastUpdate, fields };
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
list: () => ({
|
|
101
|
+
resources: [{ uri: 'pubmed://database/info', name: 'PubMed Database Info' }],
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Server config
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
// src/config/server-config.ts — lazy-parsed, separate from framework config
|
|
110
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
111
|
+
import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
112
|
+
|
|
113
|
+
const emptyAsUndefined = (v: unknown) => (v === '' ? undefined : v);
|
|
114
|
+
|
|
115
|
+
const ServerConfigSchema = z.object({
|
|
116
|
+
apiKey: z.preprocess(emptyAsUndefined, z.string().optional()).describe('NCBI API key'),
|
|
117
|
+
toolIdentifier: z.string().default('pubmed-mcp-server').describe('NCBI tool identifier'),
|
|
118
|
+
adminEmail: z.preprocess(emptyAsUndefined, z.email().optional()).describe('Admin contact email'),
|
|
119
|
+
requestDelayMs: z.coerce.number().min(50).max(5000).default(334).describe('Request delay in ms'),
|
|
120
|
+
maxRetries: z.coerce.number().min(0).max(10).default(6).describe('Max retry attempts'),
|
|
121
|
+
timeoutMs: z.coerce.number().min(1000).max(120000).default(30000).describe('Request timeout in ms'),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
let _config: z.infer<typeof ServerConfigSchema> | undefined;
|
|
125
|
+
export function getServerConfig(): z.infer<typeof ServerConfigSchema> {
|
|
126
|
+
_config ??= parseEnvConfig(ServerConfigSchema, {
|
|
127
|
+
apiKey: 'NCBI_API_KEY',
|
|
128
|
+
toolIdentifier: 'NCBI_TOOL_IDENTIFIER',
|
|
129
|
+
adminEmail: 'NCBI_ADMIN_EMAIL',
|
|
130
|
+
requestDelayMs: 'NCBI_REQUEST_DELAY_MS',
|
|
131
|
+
maxRetries: 'NCBI_MAX_RETRIES',
|
|
132
|
+
timeoutMs: 'NCBI_TIMEOUT_MS',
|
|
133
|
+
});
|
|
134
|
+
return _config;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`parseEnvConfig` maps Zod schema paths → env var names so validation errors name the actual variable (`NCBI_REQUEST_DELAY_MS` must be a number) rather than the internal path (`requestDelayMs: expected number`).
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Context
|
|
143
|
+
|
|
144
|
+
Handlers receive a unified `ctx` object. Key properties:
|
|
145
|
+
|
|
146
|
+
| Property | Description |
|
|
147
|
+
|:---------|:------------|
|
|
148
|
+
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. |
|
|
149
|
+
| `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |
|
|
150
|
+
| `ctx.elicit` | Ask user for structured input. **Check for presence first:** `if (ctx.elicit) { ... }` |
|
|
151
|
+
| `ctx.sample` | Request LLM completion from the client. **Check for presence first:** `if (ctx.sample) { ... }` |
|
|
152
|
+
| `ctx.progress` | Task progress (present when `task: true`) — `.setTotal(n)`, `.increment()`, `.update(message)`. |
|
|
153
|
+
| `ctx.recoveryFor(reason)` | Typed lookup of the contract `recovery` for a declared reason. Returns `{ recovery: { hint } }` for known reasons, `{}` otherwise. Spread into `ctx.fail` data to mirror the contract hint into `content[]`. |
|
|
154
|
+
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
155
|
+
| `ctx.requestId` | Unique request ID. |
|
|
156
|
+
| `ctx.tenantId` | Tenant ID from JWT, `'default'` for stdio or HTTP+`MCP_AUTH_MODE=none`. |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Errors
|
|
161
|
+
|
|
162
|
+
Handlers throw — the framework catches, classifies, and formats.
|
|
163
|
+
|
|
164
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive a typed `ctx.fail(reason, …)` keyed by the declared reason union. TypeScript catches `ctx.fail('typo')` at compile time, `data.reason` is auto-populated for observability, and the linter enforces conformance against the handler body. The `recovery` field is required (≥ 5 words, lint-validated) — it's the single source of truth for the recovery hint. Spread `ctx.recoveryFor('reason')` into `data` to mirror the contract recovery onto the wire (the framework mirrors `data.recovery.hint` into `content[]` text); pass an explicit `recovery: { hint: '...' }` when runtime context matters. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
errors: [
|
|
168
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
169
|
+
when: 'No requested PMID returned data',
|
|
170
|
+
recovery: 'Try pubmed_search_articles to discover valid PMIDs first.' },
|
|
171
|
+
],
|
|
172
|
+
async handler(input, ctx) {
|
|
173
|
+
const articles = await ncbi.fetch(input.pmids);
|
|
174
|
+
if (articles.length === 0) {
|
|
175
|
+
// Static contract recovery
|
|
176
|
+
throw ctx.fail('no_match', `None of ${input.pmids.length} PMIDs returned data`, {
|
|
177
|
+
...ctx.recoveryFor('no_match'),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return { articles };
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Fallback (no contract entry fits):** error factories or plain `Error`.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
// Error factories — explicit code, concise
|
|
188
|
+
import { notFound, serializationError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
189
|
+
throw notFound('Item not found', { itemId });
|
|
190
|
+
throw serviceUnavailable('API unavailable', { url }, { cause: err });
|
|
191
|
+
throw serializationError('Invalid XML response', { endpoint });
|
|
192
|
+
|
|
193
|
+
// Plain Error — framework auto-classifies from message patterns
|
|
194
|
+
throw new Error('Item not found'); // → NotFound
|
|
195
|
+
throw new Error('Invalid query format'); // → ValidationError
|
|
196
|
+
|
|
197
|
+
// McpError — full control when the code is dynamic
|
|
198
|
+
import { McpError, JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
199
|
+
throw new McpError(JsonRpcErrorCode.DatabaseError, 'Connection failed', { pool: 'primary' });
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
For HTTP responses, prefer `httpErrorFromResponse(response, { service, data })` from `/utils` over hand-rolled status ladders — covers the full 4xx/5xx → `JsonRpcErrorCode` table and captures body + `Retry-After`.
|
|
203
|
+
|
|
204
|
+
**Service-layer:** services don't have `ctx.fail`. To carry a contract `reason` from a service throw, pass `data: { reason: 'X' }` to the factory — the auto-classifier preserves `data` on the wire so clients see the same `error.data.reason` they'd see from `ctx.fail`.
|
|
205
|
+
|
|
206
|
+
See framework CLAUDE.md and the `api-errors` skill for the full auto-classification table, all factories, and the contract reference.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Structure
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
src/
|
|
214
|
+
index.ts # createApp() entry point
|
|
215
|
+
config/
|
|
216
|
+
server-config.ts # NCBI-specific env vars (Zod schema)
|
|
217
|
+
services/
|
|
218
|
+
ncbi/
|
|
219
|
+
ncbi-service.ts # NCBI E-utilities service (init/accessor)
|
|
220
|
+
api-client.ts # HTTP client for NCBI API
|
|
221
|
+
request-queue.ts # Rate-limited request queue
|
|
222
|
+
response-handler.ts # XML response parsing
|
|
223
|
+
types.ts # NCBI/PubMed domain types
|
|
224
|
+
parsing/ # XML parsers (article, esummary, PMC)
|
|
225
|
+
formatting/ # Citation formatter (APA, MLA, BibTeX, RIS)
|
|
226
|
+
mcp-server/
|
|
227
|
+
tools/definitions/ # 9 tool definitions (*.tool.ts)
|
|
228
|
+
resources/definitions/ # database-info.resource.ts
|
|
229
|
+
prompts/definitions/ # research-plan.prompt.ts
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Naming
|
|
235
|
+
|
|
236
|
+
| What | Convention | Example |
|
|
237
|
+
|:-----|:-----------|:--------|
|
|
238
|
+
| Files | kebab-case with suffix | `search-articles.tool.ts` |
|
|
239
|
+
| Tool/resource/prompt names | snake_case | `pubmed_search_articles` |
|
|
240
|
+
| Directories | kebab-case | `src/services/ncbi/` |
|
|
241
|
+
| Descriptions | Single string or template literal, no `+` concatenation | `'Search PubMed with full query syntax.'` |
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Skills
|
|
246
|
+
|
|
247
|
+
Skills are modular instructions in `skills/` at the project root. Read them directly when a task matches — e.g., `skills/add-tool/SKILL.md` when adding a tool.
|
|
248
|
+
|
|
249
|
+
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). This makes skills available as context without needing to reference `skills/` paths manually. After framework updates, run the `maintenance` skill — it re-syncs the agent directory automatically (Phase B).
|
|
250
|
+
|
|
251
|
+
Available skills:
|
|
252
|
+
|
|
253
|
+
| Skill | Purpose |
|
|
254
|
+
|:------|:--------|
|
|
255
|
+
| `setup` | Post-init project orientation |
|
|
256
|
+
| `design-mcp-server` | Design tool surface, resources, and services for a new server |
|
|
257
|
+
| `add-tool` | Scaffold a new tool definition |
|
|
258
|
+
| `add-app-tool` | Scaffold an MCP App tool + paired UI resource |
|
|
259
|
+
| `add-resource` | Scaffold a new resource definition |
|
|
260
|
+
| `add-prompt` | Scaffold a new prompt definition |
|
|
261
|
+
| `add-service` | Scaffold a new service integration |
|
|
262
|
+
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
263
|
+
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
264
|
+
| `tool-defs-analysis` | Read-only audit of definition language: voice, leaks, defaults, recovery hints, examples |
|
|
265
|
+
| `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
|
|
266
|
+
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
267
|
+
| `devcheck` | Lint, format, typecheck, audit |
|
|
268
|
+
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
269
|
+
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
270
|
+
| `git-wrapup` | Land working-tree changes as a versioned commit + annotated tag — version bump, changelog, verify, tag. Local only. |
|
|
271
|
+
| `release-and-publish` | Push + npm + MCP Registry + GH Release + Docker. Picks up from `git-wrapup` |
|
|
272
|
+
| `api-auth` | Auth modes, scopes, JWT/OAuth |
|
|
273
|
+
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
|
|
274
|
+
| `api-config` | AppConfig, parseConfig, env vars |
|
|
275
|
+
| `api-context` | Context interface, logger, state, progress |
|
|
276
|
+
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
277
|
+
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
278
|
+
| `api-services` | LLM, Speech, Graph services |
|
|
279
|
+
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
280
|
+
| `api-testing` | createMockContext, test patterns |
|
|
281
|
+
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
282
|
+
| `api-workers` | Cloudflare Workers runtime |
|
|
283
|
+
| `report-issue-framework` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
|
|
284
|
+
| `report-issue-local` | File a bug or feature request against this server's own repo via `gh` CLI |
|
|
285
|
+
|
|
286
|
+
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Commands
|
|
291
|
+
|
|
292
|
+
| Command | Purpose |
|
|
293
|
+
|:--------|:--------|
|
|
294
|
+
| `bun run build` | Compile TypeScript |
|
|
295
|
+
| `bun run rebuild` | Clean + build |
|
|
296
|
+
| `bun run clean` | Remove build artifacts |
|
|
297
|
+
| `bun run devcheck` | Lint + format + typecheck + security + packaging alignment |
|
|
298
|
+
| `bun run audit:refresh` | Delete `bun.lock`, reinstall, and re-run `bun audit`. Use when `devcheck` flags a transitive advisory — `bun update` is sticky on transitive resolutions, so the advisory may be a stale-lockfile false positive. If it survives the refresh, it's real. |
|
|
299
|
+
| `bun run tree` | Generate directory structure doc |
|
|
300
|
+
| `bun run format` | Auto-fix formatting |
|
|
301
|
+
| `bun run test` | Run tests |
|
|
302
|
+
| `bun run lint:mcp` | Validate MCP definitions against spec |
|
|
303
|
+
| `bun run lint:packaging` | Validate env var alignment between `manifest.json` and `server.json` (skipped cleanly when `manifest.json` is absent) |
|
|
304
|
+
| `bun run list-skills` | List skills in `skills/` with name + description |
|
|
305
|
+
| `bun run bundle` | Build and pack as `dist/pubmed-mcp-server.mcpb` for one-click Claude Desktop install |
|
|
306
|
+
| `bun run start:stdio` | Production mode (stdio) |
|
|
307
|
+
| `bun run start:http` | Production mode (HTTP) |
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Bundling
|
|
312
|
+
|
|
313
|
+
`bun run bundle` produces `dist/pubmed-mcp-server.mcpb` for one-click install in Claude Desktop. MCPB is stdio-only — HTTP and Docker deployments are unaffected. The `release-and-publish` skill attaches the bundle to the GitHub Release at a stable `releases/latest/download/pubmed-mcp-server.mcpb` URL that powers the README install badge.
|
|
314
|
+
|
|
315
|
+
**Adding an env var requires both files**: `server.json` stdio `environmentVariables[]` (registry discovery) and `manifest.json` `mcp_config.env` (bundle install UX, plus `user_config` if user-prompted). `bun run lint:packaging` (run by `devcheck`) verifies the env var names align.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Publishing
|
|
320
|
+
|
|
321
|
+
Run the `release-and-publish` skill after git wrapup — it runs the verification gate (`devcheck`, `rebuild`, `test`), pushes commits and tags, and publishes to npm, the MCP Registry, GHCR, and attaches the `.mcpb` bundle to the GitHub Release, halting on the first failure. For reference, the underlying commands are:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
bun publish --access public
|
|
325
|
+
|
|
326
|
+
docker buildx build --platform linux/amd64,linux/arm64 \
|
|
327
|
+
-t ghcr.io/cyanheads/pubmed-mcp-server:<version> \
|
|
328
|
+
-t ghcr.io/cyanheads/pubmed-mcp-server:latest \
|
|
329
|
+
--push .
|
|
330
|
+
|
|
331
|
+
mcp-publisher publish
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Imports
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
// Framework — z is re-exported, no separate zod import needed
|
|
340
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
341
|
+
import { McpError, JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
342
|
+
|
|
343
|
+
// Server's own code — via path alias
|
|
344
|
+
import { getNcbiService } from '@/services/ncbi/ncbi-service.js';
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Checklist
|
|
350
|
+
|
|
351
|
+
- [ ] Zod schemas: all fields have `.describe()`, only JSON-Schema-serializable types (no `z.custom()`, `z.date()`, `z.transform()`, `z.bigint()`, `z.symbol()`, `z.void()`, `z.map()`, `z.set()`, `z.function()`, `z.nan()`)
|
|
352
|
+
- [ ] Optional nested objects: handler guards for empty inner values from form-based clients (`if (input.obj?.field && ...)`, not just `if (input.obj)`). When regex/length constraints matter, use `z.union([z.literal(''), z.string().regex(...).describe(...)])` — literal variants are exempt from `describe-on-fields`.
|
|
353
|
+
- [ ] JSDoc `@fileoverview` + `@module` on every file
|
|
354
|
+
- [ ] `ctx.log` for logging, `ctx.state` for storage
|
|
355
|
+
- [ ] Handlers throw on failure — error factories or plain `Error`, no try/catch
|
|
356
|
+
- [ ] `format()` renders all data the LLM needs — different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data
|
|
357
|
+
- [ ] NCBI wrapping: raw/domain/output schemas reviewed against real upstream sparsity/nullability before finalizing required vs optional fields
|
|
358
|
+
- [ ] NCBI wrapping: normalization and `format()` preserve uncertainty; do not fabricate facts from missing upstream data
|
|
359
|
+
- [ ] NCBI wrapping: tests include at least one sparse payload case with omitted upstream fields
|
|
360
|
+
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
361
|
+
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
362
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = package name; `interface.shortDescription` from `package.json` description
|
|
363
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key matches `package.json` name; env vars added for any required API keys
|
|
364
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry with server name key, env vars for any required API keys
|
|
365
|
+
- [ ] `bun run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/pubmed-mcp-server
|
|
4
|
-
**Version:** 2.7.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.
|
|
4
|
+
**Version:** 2.7.8
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.16`
|
|
6
6
|
**Engines:** Bun ≥1.3.2, Node ≥24.0.0
|
|
7
7
|
|
|
8
8
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/pubmed-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/pubmed-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -51,5 +51,5 @@ export declare const convertIdsTool: import("@cyanheads/mcp-ts-core").ToolDefini
|
|
|
51
51
|
readonly when: "NCBI returned a structured \"not found\" error for the requested ID(s).";
|
|
52
52
|
readonly recovery: "Verify the ID exists in PubMed; the resource was not found in NCBI and retrying will not help.";
|
|
53
53
|
readonly retryable: false;
|
|
54
|
-
}]>;
|
|
54
|
+
}], undefined>;
|
|
55
55
|
//# sourceMappingURL=convert-ids.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert-ids.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/convert-ids.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAcjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"convert-ids.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/convert-ids.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAcjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2GzB,CAAC"}
|
|
@@ -104,5 +104,5 @@ export declare const fetchArticlesTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
104
104
|
readonly code: JsonRpcErrorCode.SerializationError;
|
|
105
105
|
readonly when: "NCBI EFetch returned a payload missing the PubmedArticleSet wrapper.";
|
|
106
106
|
readonly recovery: "Retry once; if it persists, NCBI returned malformed data — try fewer PMIDs at once.";
|
|
107
|
-
}]>;
|
|
107
|
+
}], undefined>;
|
|
108
108
|
//# sourceMappingURL=fetch-articles.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-articles.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-articles.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAyGjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"fetch-articles.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-articles.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAyGjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0K5B,CAAC"}
|
|
@@ -186,5 +186,5 @@ export declare const fetchFulltextTool: import("@cyanheads/mcp-ts-core").ToolDef
|
|
|
186
186
|
readonly when: "Europe PMC rejected the request input (empty query, unknown sort field, malformed parameter).";
|
|
187
187
|
readonly recovery: "Adjust the input — usually the query or sort field — before retrying; the same input will be rejected again.";
|
|
188
188
|
readonly retryable: false;
|
|
189
|
-
}]>;
|
|
189
|
+
}], undefined>;
|
|
190
190
|
//# sourceMappingURL=fetch-fulltext.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-fulltext.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-fulltext.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAoR/D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"fetch-fulltext.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fetch-fulltext.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAoR/D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgd5B,CAAC"}
|
|
@@ -26,8 +26,6 @@ export declare const findRelatedTool: import("@cyanheads/mcp-ts-core").ToolDefin
|
|
|
26
26
|
source: z.ZodOptional<z.ZodString>;
|
|
27
27
|
pubDate: z.ZodOptional<z.ZodString>;
|
|
28
28
|
}, z.core.$strip>>;
|
|
29
|
-
totalFound: z.ZodNumber;
|
|
30
|
-
notice: z.ZodOptional<z.ZodString>;
|
|
31
29
|
}, z.core.$strip>, readonly [{
|
|
32
30
|
readonly reason: "queue_full";
|
|
33
31
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.RateLimited;
|
|
@@ -58,5 +56,8 @@ export declare const findRelatedTool: import("@cyanheads/mcp-ts-core").ToolDefin
|
|
|
58
56
|
readonly when: "NCBI returned a structured \"not found\" error for the requested ID(s).";
|
|
59
57
|
readonly recovery: "Verify the ID exists in PubMed; the resource was not found in NCBI and retrying will not help.";
|
|
60
58
|
readonly retryable: false;
|
|
61
|
-
}]
|
|
59
|
+
}], {
|
|
60
|
+
readonly totalFound: z.ZodNumber;
|
|
61
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
62
|
+
}>;
|
|
62
63
|
//# sourceMappingURL=find-related.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-related.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/find-related.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAqCjD,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"find-related.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/find-related.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAqCjD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsM1B,CAAC"}
|
|
@@ -47,12 +47,22 @@ export const findRelatedTool = tool('pubmed_find_related', {
|
|
|
47
47
|
})
|
|
48
48
|
.describe('Related article with enriched summary'))
|
|
49
49
|
.describe('Related articles'),
|
|
50
|
+
}),
|
|
51
|
+
// Result-set context the agent reasons with — the pre-truncation match count and
|
|
52
|
+
// recovery guidance (invalid source PMID, or references for a non-PMC source).
|
|
53
|
+
// Surfaced via ctx.enrich(...) to structuredContent and content[]; out of the return.
|
|
54
|
+
enrichment: {
|
|
50
55
|
totalFound: z.number().describe('Total related articles found before truncation'),
|
|
51
56
|
notice: z
|
|
52
57
|
.string()
|
|
53
58
|
.optional()
|
|
54
59
|
.describe('Optional guidance when results are empty — e.g. invalid source PMID, or references requested for a non-PMC source. Absent on successful result pages.'),
|
|
55
|
-
}
|
|
60
|
+
},
|
|
61
|
+
// content[] trailer presentation for the enrichment block. totalFound is scalar —
|
|
62
|
+
// a label restores the human-readable key; notice renders as a blockquote kind-tag.
|
|
63
|
+
enrichmentTrailer: {
|
|
64
|
+
totalFound: { label: 'Total Found' },
|
|
65
|
+
},
|
|
56
66
|
async handler(input, ctx) {
|
|
57
67
|
const ncbi = getNcbiService();
|
|
58
68
|
ctx.log.debug('Finding related articles', {
|
|
@@ -90,6 +100,7 @@ export const findRelatedTool = tool('pubmed_find_related', {
|
|
|
90
100
|
}
|
|
91
101
|
}
|
|
92
102
|
const totalFound = foundPmids.length;
|
|
103
|
+
ctx.enrich({ totalFound });
|
|
93
104
|
if (foundPmids.length === 0) {
|
|
94
105
|
// ELink returns an empty LinkSet for both invalid source PMIDs and valid
|
|
95
106
|
// PMIDs that simply have no related articles, so a single ESummary on the
|
|
@@ -129,12 +140,12 @@ export const findRelatedTool = tool('pubmed_find_related', {
|
|
|
129
140
|
? `No reference list found in PMC for PMID ${input.pmid} (PMCID ${sourcePmcId}).`
|
|
130
141
|
: `Reference lists require the source article to be indexed in PMC. PMID ${input.pmid} has no PMCID — references unavailable. Use pubmed_fetch_articles to inspect the article record, or try relationship: "similar" / "cited_by".`;
|
|
131
142
|
}
|
|
143
|
+
if (notice)
|
|
144
|
+
ctx.enrich.notice(notice);
|
|
132
145
|
return {
|
|
133
146
|
sourcePmid: input.pmid,
|
|
134
147
|
relationship: input.relationship,
|
|
135
148
|
articles: [],
|
|
136
|
-
totalFound: 0,
|
|
137
|
-
...(notice && { notice }),
|
|
138
149
|
};
|
|
139
150
|
}
|
|
140
151
|
const pmidsToEnrich = foundPmids.slice(0, input.maxResults);
|
|
@@ -154,18 +165,15 @@ export const findRelatedTool = tool('pubmed_find_related', {
|
|
|
154
165
|
pubDate: details?.pubDate,
|
|
155
166
|
};
|
|
156
167
|
});
|
|
157
|
-
return { sourcePmid: input.pmid, relationship: input.relationship, articles
|
|
168
|
+
return { sourcePmid: input.pmid, relationship: input.relationship, articles };
|
|
158
169
|
},
|
|
159
170
|
format: (result) => {
|
|
160
171
|
const lines = [
|
|
161
172
|
`# Related Articles for PMID ${result.sourcePmid}`,
|
|
162
|
-
`**Relationship:** ${result.relationship}
|
|
173
|
+
`**Relationship:** ${result.relationship}`,
|
|
163
174
|
];
|
|
164
|
-
if (result.notice)
|
|
165
|
-
lines.push(`\n> ${result.notice}`);
|
|
166
175
|
if (result.articles.length === 0) {
|
|
167
|
-
|
|
168
|
-
lines.push('No related articles found.');
|
|
176
|
+
lines.push('No related articles found.');
|
|
169
177
|
}
|
|
170
178
|
else {
|
|
171
179
|
for (const a of result.articles) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-related.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/find-related.tool.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"find-related.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/find-related.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,5 +56,5 @@ export declare const formatCitationsTool: import("@cyanheads/mcp-ts-core").ToolD
|
|
|
56
56
|
readonly when: "NCBI returned a structured \"not found\" error for the requested ID(s).";
|
|
57
57
|
readonly recovery: "Verify the ID exists in PubMed; the resource was not found in NCBI and retrying will not help.";
|
|
58
58
|
readonly retryable: false;
|
|
59
|
-
}]>;
|
|
59
|
+
}], undefined>;
|
|
60
60
|
//# sourceMappingURL=format-citations.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-citations.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/format-citations.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAejD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"format-citations.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/format-citations.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAejD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAyG9B,CAAC"}
|
|
@@ -69,5 +69,5 @@ export declare const lookupCitationTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
69
69
|
readonly when: "NCBI returned a structured \"not found\" error for the requested ID(s).";
|
|
70
70
|
readonly recovery: "Verify the ID exists in PubMed; the resource was not found in NCBI and retrying will not help.";
|
|
71
71
|
readonly retryable: false;
|
|
72
|
-
}]>;
|
|
72
|
+
}], undefined>;
|
|
73
73
|
//# sourceMappingURL=lookup-citation.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup-citation.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-citation.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAyBjD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"lookup-citation.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-citation.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAyBjD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAwR7B,CAAC"}
|
|
@@ -17,7 +17,6 @@ export declare const lookupMeshTool: import("@cyanheads/mcp-ts-core").ToolDefini
|
|
|
17
17
|
scopeNote: z.ZodOptional<z.ZodString>;
|
|
18
18
|
entryTerms: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
19
19
|
}, z.core.$strip>>;
|
|
20
|
-
notice: z.ZodOptional<z.ZodString>;
|
|
21
20
|
}, z.core.$strip>, readonly [{
|
|
22
21
|
readonly reason: "queue_full";
|
|
23
22
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.RateLimited;
|
|
@@ -48,5 +47,7 @@ export declare const lookupMeshTool: import("@cyanheads/mcp-ts-core").ToolDefini
|
|
|
48
47
|
readonly when: "NCBI returned a structured \"not found\" error for the requested ID(s).";
|
|
49
48
|
readonly recovery: "Verify the ID exists in PubMed; the resource was not found in NCBI and retrying will not help.";
|
|
50
49
|
readonly retryable: false;
|
|
51
|
-
}]
|
|
50
|
+
}], {
|
|
51
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}>;
|
|
52
53
|
//# sourceMappingURL=lookup-mesh.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup-mesh.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-mesh.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAqFjD,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"lookup-mesh.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-mesh.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAqFjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6GzB,CAAC"}
|