Scientific Brainstorming
spacering-net/codeg
Creative research ideation and exploration. An agent skill from spacering-net/codeg.
Scaffold a new service integration. An agent skill from cyanheads/pubmed-mcp-server.
$ npx skills add cyanheads/pubmed-mcp-server --skill add-service -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install cyanheads/pubmed-mcp-server add-service --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .claude/skills && cp -r skills-src/framework-skills/add-service .claude/skills/add-service && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "add-service" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-service into .claude/skills/add-service/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-service", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-serviceType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add cyanheads/pubmed-mcp-server --skill add-service -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install cyanheads/pubmed-mcp-server add-service --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .agents/skills && cp -r skills-src/framework-skills/add-service .agents/skills/add-service && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "add-service" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-service into .agents/skills/add-service/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-service", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add cyanheads/pubmed-mcp-server --skill add-service -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install cyanheads/pubmed-mcp-server add-service --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/framework-skills/add-service .cursor/skills/add-service && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "add-service" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-service into .cursor/skills/add-service/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-service", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/cyanheads/pubmed-mcp-server.git --path framework-skills/add-service--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add cyanheads/pubmed-mcp-server --skill add-service -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install cyanheads/pubmed-mcp-server add-service --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/framework-skills/add-service .gemini/skills/add-service && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "add-service" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-service into .gemini/skills/add-service/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-service", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install cyanheads/pubmed-mcp-server add-serviceInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add cyanheads/pubmed-mcp-server --skill add-service -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .github/skills && cp -r skills-src/framework-skills/add-service .github/skills/add-service && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "add-service" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-service into .github/skills/add-service/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-service", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add cyanheads/pubmed-mcp-server --skill add-service -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install cyanheads/pubmed-mcp-server add-service --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/framework-skills/add-service .opencode/skills/add-service && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "add-service" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/add-service into .opencode/skills/add-service/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-service", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
add-serviceScaffold a new service integration. An agent skill from cyanheads/pubmed-mcp-server.
Add Service is an agent skill from cyanheads/pubmed-mcp-server. Scaffold a new service integration. Use when the user asks to add a service, integrate an external API, or create a reusable domain module with its own initialization and state.
Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Research & Science. The repository describes itself as: Search PubMed/Europe PMC, fetch articles and full text (PMC/EPMC/Unpaywall), citations, MeSH terms via MCP. STDIO or Streamable HTTP. The licence is Apache-2.0.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 79145a6. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
bunFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Add Service loads about 3.6k tokens when it runs. Until then it costs about 47 tokens; SKILL.md has 1,258 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from cyanheads/pubmed-mcp-server at commit 79145a6, republished under its Apache-2.0 licence (© cyanheads). 1,258 words, ~3,634 tokens.
.claude/skills/add-service/SKILL.md (or your agent's skills folder).Services use the init/accessor pattern: initialized once in createApp's setup() callback, then accessed at request time via a lazy getter. Each service lives in src/services/[domain]/ with an init function and accessor.
Service methods receive Context for correlated logging (ctx.log) and tenant-scoped storage (ctx.state). Convention: ctx.requestInput should only be called from tool, resource, and prompt handlers, not from services — a service can call it, but the never return means TypeScript cannot narrow across it at the handler's call site.
For the full service pattern, CoreServices, and Context interface, read the framework's CLAUDE.md/AGENTS.md (loaded at session start).
src/services/{{domain}}/src/services/{{domain}}/{{domain}}-service.tssrc/services/{{domain}}/types.ts if neededsetup() in the server's entry point (src/index.ts, or src/worker.ts for Worker-only servers)bun run devcheck to verify/**
* @fileoverview {{SERVICE_DESCRIPTION}}
* @module services/{{domain}}/{{domain}}-service
*/
import type { AppConfig } from '@cyanheads/mcp-ts-core/config';
import type { StorageService } from '@cyanheads/mcp-ts-core/storage';
import type { Context } from '@cyanheads/mcp-ts-core';
export class {{ServiceName}} {
constructor(
private readonly config: AppConfig,
private readonly storage: StorageService,
) {}
async doWork(input: string, ctx: Context): Promise<string> {
ctx.log.debug('Processing', { input });
// Domain logic here
return `result: ${input}`;
}
}
// --- Init/accessor pattern ---
let _service: {{ServiceName}} | undefined;
export function init{{ServiceName}}(config: AppConfig, storage: StorageService): void {
_service = new {{ServiceName}}(config, storage);
}
export function get{{ServiceName}}(): {{ServiceName}} {
if (!_service) {
throw new Error('{{ServiceName}} not initialized — call init{{ServiceName}}() in setup()');
}
return _service;
}Add the setup() callback and import to the existing createApp() call — preserve the existing tool/resource/prompt arrays:
// In src/index.ts (or src/worker.ts for Worker-only servers)
import { init{{ServiceName}} } from './services/{{domain}}/{{domain}}-service.js';
// Add setup() alongside existing options:
setup(core) {
init{{ServiceName}}(core.config, core.storage);
},import { get{{ServiceName}} } from '@/services/{{domain}}/{{domain}}-service.js';
handler: async (input, ctx) => {
return get{{ServiceName}}().doWork(input.query, ctx);
},When a service wraps an external API, apply these patterns. For the framework retry contract, see framework-skills/api-utils/SKILL.md.
Place retry at the service method level — covering both HTTP fetch and response parsing/validation. The HTTP client should be single-attempt; the service owns retry. Use withRetry from @cyanheads/mcp-ts-core/utils:
import { withRetry, fetchWithTimeout } from '@cyanheads/mcp-ts-core/utils';
import type { Context } from '@cyanheads/mcp-ts-core';
async fetchItem(id: string, ctx: Context): Promise<Item> {
return withRetry(
async () => {
const response = await fetchWithTimeout(
`${this.baseUrl}/items/${id}`,
10_000,
ctx,
{ signal: ctx.signal },
);
const text = await response.text();
return this.parseResponse<Item>(text);
},
{
operation: 'fetchItem',
context: ctx,
baseDelayMs: 1000, // calibrate to upstream recovery time
signal: ctx.signal,
},
);
}baseDelayMs: 1000 suits most APIs.fetchWithTimeout already throws on non-OK responses with granular status mapping (401→Unauthorized, 403→Forbidden, 404→NotFound, 408/425→Timeout, 422→ValidationError, 429→RateLimited, 5xx→ServiceUnavailable/InternalError) — this prevents feeding HTML error pages into XML/JSON parsers.ServiceUnavailable (transient) instead of SerializationError (non-transient). Exception — deterministic HTTP 200 errors fail fast, not transient. Some upstreams return HTTP 200 with a structured error body for failures that will never succeed regardless of how many times you retry: a query too expensive for the server's budget, an oversized result set, or a malformed request the server rejects. Retrying these wastes upstream capacity and delays the client. Declare them in the contract with retryable: false (or pass { retryable: false } in data at the throw site) — withRetry's default predicate reads error.data.retryable === false and fails immediately, even for Timeout/ServiceUnavailable codes. ctx.fail auto-populates data.retryable from the contract entry, so declaring it once in errors[] is enough.withRetry automatically enriches the final error with attempt count — callers know retries were already attempted.fetchWithTimeout already maps status codes to appropriate error codes (see key principle 2 above). Use httpErrorFromResponse instead when you need Retry-After header capture, request body passthrough in error data, or custom service/data fields on the thrown error:
import { httpErrorFromResponse, withRetry } from '@cyanheads/mcp-ts-core/utils';
async fetchItem(id: string, ctx: Context): Promise<Item> {
return withRetry(
async () => {
const response = await fetch(`${this.baseUrl}/items/${id}`, { signal: ctx.signal });
if (!response.ok) {
throw await httpErrorFromResponse(response, {
service: 'MyAPI',
data: { itemId: id },
});
}
return this.parseResponse<Item>(await response.text());
},
{ operation: 'fetchItem', context: ctx, signal: ctx.signal },
);
}httpErrorFromResponse maps the full status table (401/403/408/422/429/5xx) to the appropriate JsonRpcErrorCode, captures the response body (truncated), and forwards Retry-After headers into error.data.retryAfter. The codes it produces line up with withRetry's transient-code set, so retryable HTTP failures (429, 503, 504) are retried automatically and non-retryable ones (401, 404, 422) fail immediately.
import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
parseResponse<T>(text: string): T {
// Detect HTML error pages masquerading as successful responses
if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
throw serviceUnavailable('API returned HTML instead of expected format — likely rate-limited.');
}
// Parse and validate...
}Third-party APIs often omit fields entirely instead of returning null. If your raw response types, normalized domain types, or tool output schemas are stricter than the real upstream payloads, you'll either fail validation or silently invent facts.
Guidance:
false, 0, '', or an empty array.exactOptionalPropertyTypes, omit absent fields instead of returning undefined. Conditional spreads keep the normalized object honest.type RawRepo = {
id: string;
name: string;
archived?: boolean;
star_count?: number;
description?: string | null;
};
type Repo = {
id: string;
name: string;
archived?: boolean;
starCount?: number;
description?: string;
};
function normalizeRepo(raw: RawRepo): Repo {
const description = raw.description?.trim();
return {
id: raw.id,
name: raw.name,
...(typeof raw.archived === 'boolean' && { archived: raw.archived }),
...(typeof raw.star_count === 'number' && { starCount: raw.star_count }),
...(description ? { description } : {}),
};
}Services don't declare errors: [...] contracts and don't have ctx.fail — that contract surface is tool/resource-only. Inside services:
Throw via factories when a specific code matters: throw notFound(...), throw rateLimited(...), throw serviceUnavailable(...). The framework's auto-classifier catches anything else.
Wrap risky pipelines in ErrorHandler.tryCatch when you want structured logging + auto-classification without writing try/catch boilerplate. It always rethrows — never swallows. Useful for parsing untrusted input (JSON, config) or third-party SDK calls whose error types you don't control:
import { ErrorHandler } from '@cyanheads/mcp-ts-core/utils';
const parsed = await ErrorHandler.tryCatch(
() => JSON.parse(rawConfig),
{ operation: 'MyService.parseConfig', errorCode: JsonRpcErrorCode.ConfigurationError },
);Tool/resource handlers bubble service errors unchanged — the contract advertises the advertised failure surface, and any code thrown from a service still reaches the client correctly via the auto-classifier. The conformance lint scans handler source text only, so service-thrown codes aren't flagged.
Carry contract reason via data: { reason } when the calling tool declares an errors[] contract entry for this failure mode. Services can't call ctx.fail, but passing the reason in data flows through the auto-classifier untouched, so clients see the same error.data.reason they'd see from ctx.fail — and the framework fills that entry's recovery as data.recovery.hint when the throw carries none. No handler-side catch-and-rethrow needed:
// tool declares: errors: [{ reason: 'empty_expression', code: JsonRpcErrorCode.ValidationError,
// when: '…', recovery: '…', thrownBy: 'service' }]
throw validationError('Expression cannot be empty.', { reason: 'empty_expression' });The tool's entry carries thrownBy: 'service' so error-contract-unthrown — which reads the handler body and cannot see this throw — skips it while still checking whatever the handler throws itself. Lint-only metadata; nothing at runtime reads it.
The contract recovery follows the reason. The calling tool's declared recovery (validated ≥5 words at lint time) is the single source of truth, and the handler factory puts it on the wire for any failure carrying that reason — matched on the reason alone, whatever factory the service picked — so a service throw needs nothing beyond { reason }. For dynamic recovery (interpolating runtime values into the hint), pass an explicit { recovery: { hint: '…' } }, which always wins.
When a service wraps an external API, design methods to minimize upstream calls. These patterns compound — a tool calling 3 service methods that each make N requests is 3N calls; batching drops it to 3.
If the API supports filter-by-IDs, bulk GET, or batch query endpoints, expose a batch method instead of (or alongside) the single-item method. One request for 20 items beats 20 sequential requests — it eliminates serial latency, avoids rate-limit accumulation, and simplifies error handling.
/** Fetch multiple studies in a single request via filter.ids. */
async getStudiesBatch(nctIds: string[], ctx: Context): Promise<Study[]> {
const response = await this.searchStudies({
filterIds: nctIds,
fields: ['NCTId', 'BriefTitle', 'HasResults', 'ResultsSection'],
pageSize: nctIds.length,
}, ctx);
return response.studies;
}Cross-reference the response against the requested IDs to detect missing items — don't assume the API returns everything you asked for.
If the API supports fields, select, or include parameters, request only what the caller needs. A full record might be 70KB; four fields might be 5KB. Expose field selection as a parameter on the service method, or use sensible defaults per method.
If a batch request might exceed the API's page size limit, either:
nextPageToken present)Silent truncation is a data integrity bug — the caller thinks it has all results when it doesn't.
src/services/{{domain}}/init function accepts (config: AppConfig, storage: StorageService) and stores the instanceError if not initialized@fileoverview and @module header presentconsole calls — use ctx.log for service-level loggingContext for logging and storageinit function registered in setup() callback in the server's entry point (src/index.ts or src/worker.ts)bun run devcheck passes© cyanheads, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in framework-skills/add-service of cyanheads/pubmed-mcp-server.
Open the folder on GitHubat commit 79145a6
Add Service next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Add Service this skillcyanheads/pubmed-mcp-server | 158 | — | ~3.6k | Automated safety check: Pass | Apache-2.0 | |
| Scientific Brainstormingspacering-net/codeg | 3.9k | 13 repos | ~2k | Automated safety check: Pass | MIT | |
| MFA Pipeline Orchestratoraiming-lab/AutoResearchClaw | 15k | — | ~923 | Automated safety check: Pass | MIT | |
| Research RefinezjYao36/Auto-Research-Refine | 128 | 6 repos | ~6.9k | Automated safety check: Notes | None | |
| Read GitHubAgentTeam-TaichuAI/ScienceClaw | 671 | 2 repos | ~638 | Automated safety check: Pass | None | |
| Web ResearchJuncai22/spring-ai-agent-learning | 124 | 2 repos | ~1.1k | Automated safety check: Pass | Apache-2.0 |
spacering-net/codeg
Creative research ideation and exploration. An agent skill from spacering-net/codeg.
aiming-lab/AutoResearchClaw
Runs a metabolic flux analysis from model loading to phenotype prediction and figures by handing work to four sub-agents in sequence.
zjYao36/Auto-Research-Refine
Turns a vague research direction into a focused, problem-anchored method plan through up to five review rounds with a second model.
AgentTeam-TaichuAI/ScienceClaw
Read and search GitHub repository documentation via gitmcp.io MCP service.
Juncai22/spring-ai-agent-learning
A skill your agent uses for requests related to web research; it provides a structured approach to conducting comprehensive web research
Socialpranker/deepdive
Meta-research под вопрос или решение: веб-поиск, источники, Q&A отчёт с цитатами по файлам для повторного использования.
cyanheads/pubmed-mcp-server
Scaffold an MCP App tool + UI resource pair. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a new MCP prompt template. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a new MCP resource definition. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a test file for an existing tool, resource, or service.
cyanheads/pubmed-mcp-server
Authentication, authorization, and multi-tenancy patterns for @cyanheads/mcp-ts-core.
cyanheads/pubmed-mcp-server
Stand up a persistent, self-refreshing local mirror of a bulk upstream dataset with the MirrorService (@cyanheads/mcp-ts-core/mirror).
Categories
Scaffold a new service integration. An agent skill from cyanheads/pubmed-mcp-server. Add Service is an agent skill from cyanheads/pubmed-mcp-server. Scaffold a new service integration.
Add Service fits situations like: the user asks to add a service; integrate an external API; create a reusable domain module with its own initialization and state.
Run `npx skills add cyanheads/pubmed-mcp-server --skill add-service -a claude-code`. Or copy the skill folder (framework-skills/add-service in cyanheads/pubmed-mcp-server) into .claude/skills/add-service in your project. Claude Code loads it when a task matches its description.
Run `npx skills add cyanheads/pubmed-mcp-server --skill add-service -a codex`. Or copy the skill folder (framework-skills/add-service in cyanheads/pubmed-mcp-server) into .agents/skills/add-service in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add cyanheads/pubmed-mcp-server --skill add-service -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/add-service, .gemini/skills/add-service, .github/skills/add-service and .opencode/skills/add-service in your project.
Going by SKILL.md and its folder, Add Service needs the command-line tools its instructions call (bun).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Add Service is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.6k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Add Service: Scientific Brainstorming (spacering-net/codeg, 3.9k stars), MFA Pipeline Orchestrator (aiming-lab/AutoResearchClaw, 15k stars), Research Refine (zjYao36/Auto-Research-Refine, 128 stars) and Read GitHub (AgentTeam-TaichuAI/ScienceClaw, 671 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
cyanheads (a GitHub user) maintains it in cyanheads/pubmed-mcp-server, which has 158 GitHub stars. The repository holds 30 skills in this directory. The repository was last updated on October 9, 2026.
Source: cyanheads/pubmed-mcp-server on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.