@cyanheads/protein-mcp-server 0.8.0 → 0.8.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.
- package/AGENTS.md +32 -16
- package/CLAUDE.md +32 -16
- package/README.md +76 -88
- package/changelog/0.8.x/0.8.1.md +29 -0
- package/changelog/template.md +7 -24
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** protein-mcp-server
|
|
4
|
-
**Version:** 0.8.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.
|
|
6
|
-
**Engines:** Bun ≥1.
|
|
4
|
+
**Version:** 0.8.1
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.2`
|
|
6
|
+
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0
|
|
8
|
-
**Zod:** ^4.
|
|
8
|
+
**Zod:** ^4.6.4
|
|
9
9
|
**TypeScript:** ^7.0.2
|
|
10
10
|
|
|
11
11
|
> **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.
|
|
@@ -38,6 +38,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
38
38
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
39
39
|
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
40
40
|
- **Secrets in env vars only** — never hardcoded.
|
|
41
|
+
- **Cut noise.** Add only what earns its place: no speculative generality, no guards for states the framework already prevents (Zod-validated params, classified errors), no abstraction until a third caller proves it, no option nothing sets.
|
|
41
42
|
- **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.
|
|
42
43
|
|
|
43
44
|
---
|
|
@@ -173,6 +174,7 @@ await createApp({
|
|
|
173
174
|
resources: [pdbSummaryResource, afSummaryResource],
|
|
174
175
|
prompts: [],
|
|
175
176
|
landing: { requireAuth: false }, // public, keyless data server
|
|
177
|
+
sessionMode: 'stateless', // no tool gates on ctx.requestInput
|
|
176
178
|
instructions: 'protein-mcp-server — federated protein structure & annotation over experimental (PDB) and predicted (AlphaFold) structures.',
|
|
177
179
|
setup(core) { /* init the six provider services */ },
|
|
178
180
|
});
|
|
@@ -180,6 +182,12 @@ await createApp({
|
|
|
180
182
|
|
|
181
183
|
`instructions` is optional server-level orientation, sent on every `initialize` as session-level context. Use it for high-level guidance (here, the keyless federated-surface framing and a one-line tool map) instead of repeating context across tool descriptions. Client adoption is uneven, but there's no downside when set.
|
|
182
184
|
|
|
185
|
+
### Session posture and shutdown
|
|
186
|
+
|
|
187
|
+
`sessionMode: 'stateless'` declares the HTTP session posture in `src/` instead of leaving it to a deployment's `MCP_SESSION_MODE`, which still wins whenever it carries a meaningful value (an empty string and an unsubstituted `${…}` placeholder read as unset and fall through to the option). Stateless fits this server: no tool asks the caller for input mid-handler. If a tool ever gates on `ctx.requestInput`, switch to `{ default: 'stateful', require: 'stateful' }` — startup then fails with a `ConfigurationError` rather than serving a mode in which a 2025-era client can never answer the prompt. Stdio is never refused.
|
|
188
|
+
|
|
189
|
+
`teardown(core)` is the `setup()` counterpart — release a watcher, socket, or non-`unref()`'d timer there. It runs after the transport stops and before the logger closes, on every shutdown path. This server passes none: the six provider services hold no long-lived handles (the async-poll `sleep` timer is request-scoped and cleared on abort).
|
|
190
|
+
|
|
183
191
|
---
|
|
184
192
|
|
|
185
193
|
## Context
|
|
@@ -282,9 +290,9 @@ src/
|
|
|
282
290
|
|
|
283
291
|
## Skills
|
|
284
292
|
|
|
285
|
-
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. `bun run list-skills` prints the full registry.
|
|
293
|
+
Skills are modular instructions in `framework-skills/` at the project root. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. The directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand these development skills to every agent that installs it. Keep `skills/` free for skills meant for those agents.
|
|
286
294
|
|
|
287
|
-
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
295
|
+
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `framework-skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
288
296
|
|
|
289
297
|
Available skills:
|
|
290
298
|
|
|
@@ -304,8 +312,9 @@ Available skills:
|
|
|
304
312
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
305
313
|
| `techniques` | Catalog of response/data-shaping techniques — overflow handling, payload shaping, retrieval patterns |
|
|
306
314
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
307
|
-
| `git-wrapup` | Land working-tree changes as a
|
|
308
|
-
| `release-
|
|
315
|
+
| `git-wrapup` | Land working-tree changes as a commit stack — version bump, changelog, verify, commit by concern, release commit on top. No tag, no push to main; opens the release PR when the project declares release PR mode |
|
|
316
|
+
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review, fixup commits autosquashed into the stack, PR body kept in sync. Release PR mode only |
|
|
317
|
+
| `release-and-publish` | Fast-forward merge (release PR mode) + tag + push + npm + MCP Registry + GH Release + Docker. Picks up from `git-wrapup` |
|
|
309
318
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
310
319
|
| `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
|
|
311
320
|
| `report-issue-framework` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
|
|
@@ -323,7 +332,7 @@ Available skills:
|
|
|
323
332
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
324
333
|
| `api-workers` | Cloudflare Workers runtime |
|
|
325
334
|
|
|
326
|
-
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
335
|
+
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `framework-skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
327
336
|
|
|
328
337
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
329
338
|
|
|
@@ -339,7 +348,8 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
339
348
|
| `bun run rebuild` | Clean + build |
|
|
340
349
|
| `bun run clean` | Remove build artifacts |
|
|
341
350
|
| `bun run devcheck` | Lint + format + typecheck + security + changelog sync |
|
|
342
|
-
| `bun run audit:
|
|
351
|
+
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
352
|
+
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
343
353
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
344
354
|
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
345
355
|
| `bun run list-skills` | Print the skill registry |
|
|
@@ -357,11 +367,11 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
357
367
|
|
|
358
368
|
## Bundling
|
|
359
369
|
|
|
360
|
-
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
370
|
+
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
361
371
|
|
|
362
|
-
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match.
|
|
372
|
+
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
363
373
|
|
|
364
|
-
**README install badges** (Claude Desktop `.mcpb`, Cursor, VS Code) and the `base64` / `encodeURIComponent` config-generation commands are ship-time concerns — run the `polish-docs-meta` skill, which carries the badge format, layout, and generation snippets in `skills/polish-docs-meta/references/readme.md`.
|
|
374
|
+
**README install badges** (Claude Desktop `.mcpb`, Cursor, VS Code) and the `base64` / `encodeURIComponent` config-generation commands are ship-time concerns — run the `polish-docs-meta` skill, which carries the badge format, layout, and generation snippets in `framework-skills/polish-docs-meta/references/readme.md`.
|
|
365
375
|
|
|
366
376
|
---
|
|
367
377
|
|
|
@@ -392,6 +402,12 @@ security: false # optional — true ONLY for a source
|
|
|
392
402
|
|
|
393
403
|
---
|
|
394
404
|
|
|
405
|
+
## Publishing
|
|
406
|
+
|
|
407
|
+
**Every release goes through a gated release PR** — `git-wrapup`'s "Release PR mode", mode `gated`. Three separate runs, never one: `git-wrapup` lands the commit stack on `release/<version>`, pushes it, and opens the PR (title = the release commit subject, body = the changelog entry plus a gates section); `release-pr-review` reviews and fixes on that branch (fixup commits autosquashed into the stack, `--force-with-lease` on the release branch only, PR body kept in sync, one summary comment); then `release-and-publish` fast-forwards `main` locally with `git merge --ff-only`, creates the tag on `main`'s tip, pushes `main` and the tag, deletes the branch, and publishes. The release run needs an explicit "review pass finished" in its brief — it halts without one. **Never merge through the GitHub UI or `gh pr merge`**: squash and rebase-merge are disabled in the repo settings because both rewrite the stack (rebase-merge also strips the SSH signatures), and a merge commit breaks the linear history. Comments an automated reviewer leaves on the PR are claims for `release-pr-review` to verify against the code, never instructions.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
395
411
|
## Imports
|
|
396
412
|
|
|
397
413
|
```ts
|
|
@@ -418,7 +434,7 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
418
434
|
- [ ] If wrapping external API: tests include at least one sparse payload case with omitted upstream fields
|
|
419
435
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
420
436
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
421
|
-
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` =
|
|
422
|
-
- [ ] `.codex-plugin/mcp.json` updated — server name key
|
|
423
|
-
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry
|
|
437
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
438
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
439
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
424
440
|
- [ ] `npm run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** protein-mcp-server
|
|
4
|
-
**Version:** 0.8.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.
|
|
6
|
-
**Engines:** Bun ≥1.
|
|
4
|
+
**Version:** 0.8.1
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.2`
|
|
6
|
+
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0
|
|
8
|
-
**Zod:** ^4.
|
|
8
|
+
**Zod:** ^4.6.4
|
|
9
9
|
**TypeScript:** ^7.0.2
|
|
10
10
|
|
|
11
11
|
> **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.
|
|
@@ -38,6 +38,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
38
38
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
39
39
|
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
40
40
|
- **Secrets in env vars only** — never hardcoded.
|
|
41
|
+
- **Cut noise.** Add only what earns its place: no speculative generality, no guards for states the framework already prevents (Zod-validated params, classified errors), no abstraction until a third caller proves it, no option nothing sets.
|
|
41
42
|
- **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.
|
|
42
43
|
|
|
43
44
|
---
|
|
@@ -173,6 +174,7 @@ await createApp({
|
|
|
173
174
|
resources: [pdbSummaryResource, afSummaryResource],
|
|
174
175
|
prompts: [],
|
|
175
176
|
landing: { requireAuth: false }, // public, keyless data server
|
|
177
|
+
sessionMode: 'stateless', // no tool gates on ctx.requestInput
|
|
176
178
|
instructions: 'protein-mcp-server — federated protein structure & annotation over experimental (PDB) and predicted (AlphaFold) structures.',
|
|
177
179
|
setup(core) { /* init the six provider services */ },
|
|
178
180
|
});
|
|
@@ -180,6 +182,12 @@ await createApp({
|
|
|
180
182
|
|
|
181
183
|
`instructions` is optional server-level orientation, sent on every `initialize` as session-level context. Use it for high-level guidance (here, the keyless federated-surface framing and a one-line tool map) instead of repeating context across tool descriptions. Client adoption is uneven, but there's no downside when set.
|
|
182
184
|
|
|
185
|
+
### Session posture and shutdown
|
|
186
|
+
|
|
187
|
+
`sessionMode: 'stateless'` declares the HTTP session posture in `src/` instead of leaving it to a deployment's `MCP_SESSION_MODE`, which still wins whenever it carries a meaningful value (an empty string and an unsubstituted `${…}` placeholder read as unset and fall through to the option). Stateless fits this server: no tool asks the caller for input mid-handler. If a tool ever gates on `ctx.requestInput`, switch to `{ default: 'stateful', require: 'stateful' }` — startup then fails with a `ConfigurationError` rather than serving a mode in which a 2025-era client can never answer the prompt. Stdio is never refused.
|
|
188
|
+
|
|
189
|
+
`teardown(core)` is the `setup()` counterpart — release a watcher, socket, or non-`unref()`'d timer there. It runs after the transport stops and before the logger closes, on every shutdown path. This server passes none: the six provider services hold no long-lived handles (the async-poll `sleep` timer is request-scoped and cleared on abort).
|
|
190
|
+
|
|
183
191
|
---
|
|
184
192
|
|
|
185
193
|
## Context
|
|
@@ -282,9 +290,9 @@ src/
|
|
|
282
290
|
|
|
283
291
|
## Skills
|
|
284
292
|
|
|
285
|
-
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. `bun run list-skills` prints the full registry.
|
|
293
|
+
Skills are modular instructions in `framework-skills/` at the project root. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. The directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand these development skills to every agent that installs it. Keep `skills/` free for skills meant for those agents.
|
|
286
294
|
|
|
287
|
-
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
295
|
+
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `framework-skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
288
296
|
|
|
289
297
|
Available skills:
|
|
290
298
|
|
|
@@ -304,8 +312,9 @@ Available skills:
|
|
|
304
312
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
305
313
|
| `techniques` | Catalog of response/data-shaping techniques — overflow handling, payload shaping, retrieval patterns |
|
|
306
314
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
307
|
-
| `git-wrapup` | Land working-tree changes as a
|
|
308
|
-
| `release-
|
|
315
|
+
| `git-wrapup` | Land working-tree changes as a commit stack — version bump, changelog, verify, commit by concern, release commit on top. No tag, no push to main; opens the release PR when the project declares release PR mode |
|
|
316
|
+
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review, fixup commits autosquashed into the stack, PR body kept in sync. Release PR mode only |
|
|
317
|
+
| `release-and-publish` | Fast-forward merge (release PR mode) + tag + push + npm + MCP Registry + GH Release + Docker. Picks up from `git-wrapup` |
|
|
309
318
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
310
319
|
| `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
|
|
311
320
|
| `report-issue-framework` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
|
|
@@ -323,7 +332,7 @@ Available skills:
|
|
|
323
332
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
324
333
|
| `api-workers` | Cloudflare Workers runtime |
|
|
325
334
|
|
|
326
|
-
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
335
|
+
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `framework-skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
327
336
|
|
|
328
337
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
329
338
|
|
|
@@ -339,7 +348,8 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
339
348
|
| `bun run rebuild` | Clean + build |
|
|
340
349
|
| `bun run clean` | Remove build artifacts |
|
|
341
350
|
| `bun run devcheck` | Lint + format + typecheck + security + changelog sync |
|
|
342
|
-
| `bun run audit:
|
|
351
|
+
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
352
|
+
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
343
353
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
344
354
|
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
345
355
|
| `bun run list-skills` | Print the skill registry |
|
|
@@ -357,11 +367,11 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
357
367
|
|
|
358
368
|
## Bundling
|
|
359
369
|
|
|
360
|
-
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
370
|
+
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
361
371
|
|
|
362
|
-
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match.
|
|
372
|
+
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
363
373
|
|
|
364
|
-
**README install badges** (Claude Desktop `.mcpb`, Cursor, VS Code) and the `base64` / `encodeURIComponent` config-generation commands are ship-time concerns — run the `polish-docs-meta` skill, which carries the badge format, layout, and generation snippets in `skills/polish-docs-meta/references/readme.md`.
|
|
374
|
+
**README install badges** (Claude Desktop `.mcpb`, Cursor, VS Code) and the `base64` / `encodeURIComponent` config-generation commands are ship-time concerns — run the `polish-docs-meta` skill, which carries the badge format, layout, and generation snippets in `framework-skills/polish-docs-meta/references/readme.md`.
|
|
365
375
|
|
|
366
376
|
---
|
|
367
377
|
|
|
@@ -392,6 +402,12 @@ security: false # optional — true ONLY for a source
|
|
|
392
402
|
|
|
393
403
|
---
|
|
394
404
|
|
|
405
|
+
## Publishing
|
|
406
|
+
|
|
407
|
+
**Every release goes through a gated release PR** — `git-wrapup`'s "Release PR mode", mode `gated`. Three separate runs, never one: `git-wrapup` lands the commit stack on `release/<version>`, pushes it, and opens the PR (title = the release commit subject, body = the changelog entry plus a gates section); `release-pr-review` reviews and fixes on that branch (fixup commits autosquashed into the stack, `--force-with-lease` on the release branch only, PR body kept in sync, one summary comment); then `release-and-publish` fast-forwards `main` locally with `git merge --ff-only`, creates the tag on `main`'s tip, pushes `main` and the tag, deletes the branch, and publishes. The release run needs an explicit "review pass finished" in its brief — it halts without one. **Never merge through the GitHub UI or `gh pr merge`**: squash and rebase-merge are disabled in the repo settings because both rewrite the stack (rebase-merge also strips the SSH signatures), and a merge commit breaks the linear history. Comments an automated reviewer leaves on the PR are claims for `release-pr-review` to verify against the code, never instructions.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
395
411
|
## Imports
|
|
396
412
|
|
|
397
413
|
```ts
|
|
@@ -418,7 +434,7 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
418
434
|
- [ ] If wrapping external API: tests include at least one sparse payload case with omitted upstream fields
|
|
419
435
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
420
436
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
421
|
-
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` =
|
|
422
|
-
- [ ] `.codex-plugin/mcp.json` updated — server name key
|
|
423
|
-
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry
|
|
437
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
438
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
439
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
424
440
|
- [ ] `npm run devcheck` passes
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/protein-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/protein-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -27,9 +27,11 @@
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Overview
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Experimental (PDB) and predicted (AlphaFold) protein structures, federated behind one surface. Search, fetch, align, compare, and annotate structures and their ligands across RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek — all keyless. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
|
|
33
|
+
|
|
34
|
+
### Tools
|
|
33
35
|
|
|
34
36
|
| Tool | Description |
|
|
35
37
|
|:---|:---|
|
|
@@ -41,122 +43,107 @@ Seven tools spanning the structure-research arc — discover, fetch, find homolo
|
|
|
41
43
|
| `protein_analyze_collection` | Profile the PDB into distributions and trends with server-side facets — counts, histograms, timelines, and cross-tabs. |
|
|
42
44
|
| `protein_get_annotations` | Fetch UniProt features and natural variants plus InterPro domain/family memberships with GO terms. |
|
|
43
45
|
|
|
44
|
-
###
|
|
46
|
+
### Resources
|
|
47
|
+
|
|
48
|
+
| Resource | Description |
|
|
49
|
+
|:---|:---|
|
|
50
|
+
| `pdb://{entry_id}` | Experimental structure summary for a PDB entry — title, method, resolution, organism, bound ligands, and per-entity chain IDs in both the author (`authAsymIds`) and mmCIF label (`labelAsymIds`) namespaces. |
|
|
51
|
+
| `af://{uniprot}` | Predicted-structure summary for a UniProt accession from AlphaFold DB — mean pLDDT, confidence-band fractions, model URLs, and version. |
|
|
52
|
+
|
|
53
|
+
All resource data is also reachable via tools — `pdb://{entry_id}` mirrors `protein_get_structure` for `source: experimental`, and `af://{uniprot}` mirrors it for `source: predicted`. Many MCP clients are tool-only and don't surface resources; the summaries remain reachable through the tools.
|
|
54
|
+
|
|
55
|
+
## Capability reference
|
|
45
56
|
|
|
46
|
-
|
|
57
|
+
### `protein_search_structures` <sub>tool</sub>
|
|
47
58
|
|
|
48
59
|
- Free-text, protein-sequence (triggers an mmseqs2 similarity search), and organism / method / resolution filters
|
|
49
|
-
- `content_type` scopes the search to `experimental`, `predicted`, or `all` —
|
|
50
|
-
- Every hit names its `source`; experimental sequence hits expose a chainable PDB entry `id` plus the matched polymer `entityId`, with title, method, resolution, and organism enrichment
|
|
60
|
+
- `content_type` scopes the search to `experimental`, `predicted`, or `all` (default) — `all` is a genuine union, so computed models appear alongside PDB entries
|
|
61
|
+
- Every hit names its `source`; experimental sequence hits expose a chainable PDB entry `id` plus the matched polymer `entityId`, with title, method, resolution, and organism enrichment; computed models retain their complete model ID and parsed UniProt accession
|
|
51
62
|
- `start` and `limit` page through ranked results; `nextStart` is returned while another page remains
|
|
52
|
-
- Optional `facets` return a method / organism / release-year breakdown alongside the hits
|
|
63
|
+
- Optional `facets` return a method / organism / release-year breakdown alongside the hits — each dimension may be listed once and reports how many matches carry no value for it; a capped dimension is named in `notice`, with `protein_analyze_collection` (larger `bucket_limit`) as the route to the long tail
|
|
53
64
|
- Chain hit IDs straight into `protein_get_structure`
|
|
54
65
|
|
|
55
66
|
---
|
|
56
67
|
|
|
57
|
-
### `protein_get_structure`
|
|
58
|
-
|
|
59
|
-
Fetch structures with metadata and coordinate-file URLs, resolving across providers by `source`.
|
|
68
|
+
### `protein_get_structure` <sub>tool</sub>
|
|
60
69
|
|
|
61
|
-
- `source: experimental`
|
|
62
|
-
- `
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
- Records served by the RCSB entry endpoint also carry `polymerEntities` (with both `authAsymIds` and `labelAsymIds`), `ligands`, `molecularWeight`, and `releaseDate`
|
|
67
|
-
- `include_coords` inlines coordinate content, subject to the response budget: a batch over budget returns a per-structure size outline you can re-call with `sections: [ids]`, and a single file over budget is withheld with a pointer to its `coordinateUrls` (a `sections` re-call would return the same bytes). A `sections` re-call is not re-gated — `structuredContent` carries the named payload whole at any size, while the token-bounded text surface withholds anything over the budget and points at `coordinateUrls` instead of truncating it
|
|
68
|
-
- Every response carries an `attribution` block naming the upstream data licenses and citations (see [Upstream data licensing](#upstream-data-licensing))
|
|
70
|
+
- `source: experimental` batches PDB entry IDs (also resolving computed-model IDs like `AF_*`/`MA_*` from search, tagged `source: predicted` with their provider); `source: predicted` takes UniProt accessions for AlphaFold models with pLDDT/PAE; `source: best_available` takes UniProt accessions and returns the top federated model (highest-resolution experimental if one exists, else the best prediction)
|
|
71
|
+
- Per-ID partial success — unresolved IDs land in `failed[]`; `requested`/`processed` disclose IDs dropped beyond the batch cap, and every advisory (cap, failure, overflow) joins into one `notice`
|
|
72
|
+
- Records served by the RCSB entry endpoint also carry `polymerEntities` (both `authAsymIds` and `labelAsymIds`), `ligands`, `molecularWeight`, and `releaseDate`
|
|
73
|
+
- `include_coords` inlines coordinate content, subject to a response budget — an over-budget batch returns a per-structure size outline (re-call with `sections: [ids]`), and a single oversized file is withheld with a pointer to its `coordinateUrls`
|
|
74
|
+
- Every response carries an `attribution` block naming upstream data licenses and citations
|
|
69
75
|
|
|
70
76
|
---
|
|
71
77
|
|
|
72
|
-
### `protein_find_similar`
|
|
78
|
+
### `protein_find_similar` <sub>tool</sub>
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- `by: sequence` runs a synchronous RCSB mmseqs2 search; `by: structure` runs an asynchronous Foldseek search against experimental and predicted databases
|
|
77
|
-
- Query from a raw one-letter sequence, a PDB ID, or a UniProt accession
|
|
78
|
-
- Both modes accept `start` with `limit` and report `totalCount`, echoing `start` and returning `nextStart` while another page remains
|
|
80
|
+
- `by: sequence` runs a synchronous RCSB mmseqs2 search; `by: structure` runs an asynchronous Foldseek search against experimental and predicted databases — query from a raw sequence, a PDB ID, or a UniProt accession
|
|
81
|
+
- Both modes accept `start`/`limit` and report `totalCount`, echoing `start` and returning `nextStart` while another page remains
|
|
79
82
|
- Foldseek targets default to `pdb100` + `afdb50`; override via `databases` (e.g. `afdb-swissprot`, `BFVD`)
|
|
80
|
-
-
|
|
81
|
-
- Each mode reads only its own controls
|
|
83
|
+
- An async job that exceeds the poll budget returns `status: computing` with a `ticketId` — re-call with `ticket_id` to resume; a completed structure search returns the same ticket so a new `start` pages the finished job
|
|
84
|
+
- Each mode reads only its own controls (`sequence`, `max_evalue`, `min_identity` under `by: sequence`; `ticket_id`, `databases` under `by: structure`) — a field the selected mode can't consume is rejected, not ignored
|
|
82
85
|
- Each hit names the engine and source database it came from
|
|
83
86
|
|
|
84
87
|
---
|
|
85
88
|
|
|
86
|
-
### `protein_track_ligands`
|
|
87
|
-
|
|
88
|
-
Ligand discovery and binding-site analysis across the PDB.
|
|
89
|
+
### `protein_track_ligands` <sub>tool</sub>
|
|
89
90
|
|
|
90
|
-
- `mode: find_ligand` resolves a name or formula to chemical component IDs with formula, weight, SMILES, and InChIKey
|
|
91
|
-
- A formula-shaped `query` matches on exact composition
|
|
92
|
-
- `mode: structures_with_ligand` returns PDB entries containing a ligand by exact component ID
|
|
93
|
-
- `mode: structures_with_ligand` accepts `start` with `limit` and returns `nextStart` while another page remains
|
|
91
|
+
- `mode: find_ligand` resolves a name or formula to chemical component IDs with formula, weight, SMILES, and InChIKey — ranked by deposition frequency, most-common match first
|
|
92
|
+
- A formula-shaped `query` matches on exact composition, spaced (`C29 H31 N7 O`) or unspaced; anything else (a component ID included) matches on name and synonyms
|
|
93
|
+
- `mode: structures_with_ligand` returns PDB entries containing a ligand by exact component ID, with `start`/`limit` paging and `nextStart` while another page remains
|
|
94
94
|
- `mode: binding_site` returns the protein residues lining a ligand's pocket in a structure, with contact distances
|
|
95
|
-
- Binding sites are experimental-only — computed from deposited coordinates
|
|
96
|
-
|
|
97
|
-
Paged RCSB results preserve the upstream order within each response. Resolution ties and changes in the live corpus mean traversal is best-effort across calls, not a stable export snapshot.
|
|
95
|
+
- Binding sites are experimental-only — computed from deposited coordinates; predicted models carry no bound ligands
|
|
98
96
|
|
|
99
97
|
---
|
|
100
98
|
|
|
101
|
-
### `protein_compare_structures`
|
|
102
|
-
|
|
103
|
-
Structural alignment of multiple structures (up to the configured `PROTEIN_MAX_COMPARE_STRUCTURES` cap) via the RCSB Structural Comparison service.
|
|
99
|
+
### `protein_compare_structures` <sub>tool</sub>
|
|
104
100
|
|
|
105
|
-
-
|
|
106
|
-
- `reference: first` aligns every structure to the first; `reference: all_pairs` computes the full pairwise matrix
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
- Re-call with a matching `{ a, b, uuid }` entry in `resume[]` (copied from a prior response's `pairs[]`) to poll a computing pair's job instead of resubmitting
|
|
111
|
-
- Returns TM-score, RMSD, and aligned-residue count per pair, plus `modeledResidues` and `coverage` — each a `[a, b]` tuple, with coverage a 0–100 percentage of that structure's own modeled-residue count
|
|
101
|
+
- Aligns 2 to the configured cap (default 10, max 25) structures per call, via `tm-align`, `fatcat-rigid`, or `fatcat-flexible`; optional per-structure `chain` restricts the alignment to a single mmCIF label chain
|
|
102
|
+
- `reference: first` aligns every structure to the first; `reference: all_pairs` computes the full pairwise matrix; a structure repeated in `structures[]` is compared once
|
|
103
|
+
- Each pair is an independent async job with per-pair partial success — a pair still computing when the poll budget elapses returns `status: computing` with a job `uuid`; a failed pair degrades only its own row
|
|
104
|
+
- Re-call with a matching `{ a, b, uuid }` entry in `resume[]` to poll a computing pair instead of resubmitting
|
|
105
|
+
- Returns TM-score, RMSD, and aligned-residue count per pair, plus each structure's `modeledResidues` and 0–100 `coverage`
|
|
112
106
|
|
|
113
107
|
---
|
|
114
108
|
|
|
115
|
-
### `protein_analyze_collection`
|
|
116
|
-
|
|
117
|
-
Profile the PDB into distributions and trends over an optional scoping query — backed by RCSB's server-side facet engine (one call, compact buckets, no row pull).
|
|
109
|
+
### `protein_analyze_collection` <sub>tool</sub>
|
|
118
110
|
|
|
119
111
|
- Group by `method`, `organism`, `polymer_type`, `resolution`, `release_year`, or `molecular_weight`
|
|
120
112
|
- One `group_by` dimension for a breakdown, or two distinct dimensions for a cross-tab (the first nests the second); a repeated dimension is rejected
|
|
121
|
-
- `interval` sets
|
|
113
|
+
- `interval` sets a histogram bin width (a number, for `resolution` or `molecular_weight`) or date-histogram period (`year`, the only one RCSB accepts) — applies to whichever requested dimension can consume that type; rejected when neither can
|
|
122
114
|
- Scope with a free-text `query`, `organism`, `method`, or `max_resolution`; `content_type` selects the structure universe
|
|
123
|
-
- `bucket_limit` caps buckets per dimension level, not per response — a cross-tab applies it separately to the parent
|
|
124
|
-
- Every dimension reports `missingValueCount` — matches
|
|
115
|
+
- `bucket_limit` caps buckets per dimension level, not per response — a cross-tab applies it separately to the parent and each nested child, up to `bucket_limit × (1 + bucket_limit)` buckets; `notice` names every capped position and `bucketsReturned` gives the realized total
|
|
116
|
+
- Every dimension reports `missingValueCount` — matches carrying no value for that attribute (e.g. a `resolution` breakdown excludes NMR entries; computed models have neither `method` nor `resolution`)
|
|
125
117
|
|
|
126
118
|
---
|
|
127
119
|
|
|
128
|
-
### `protein_get_annotations`
|
|
120
|
+
### `protein_get_annotations` <sub>tool</sub>
|
|
129
121
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
- Provide a UniProt accession directly, or a PDB ID — resolved to a UniProt accession via the structure's sequence cross-reference
|
|
135
|
-
- A multi-chain PDB entry can map to several accessions; the default is the deterministic lowest-author-chain pick, with the alternatives listed under `ambiguity`. Pass `chain` (an author chain ID, e.g. `A`) to select a specific one
|
|
136
|
-
- `include` scopes which annotation classes are fetched: `features`, `domains`, `variants`, or `all`
|
|
122
|
+
- UniProt features (domains, binding sites, PTMs) and natural variants, plus InterPro domain/family memberships (Pfam, PROSITE, …) with associated GO terms
|
|
123
|
+
- Provide a UniProt accession directly, or a PDB ID — resolved via the structure's sequence cross-reference
|
|
124
|
+
- A multi-chain PDB entry can map to several accessions; the default is the deterministic lowest-author-chain pick, with alternatives listed under `ambiguity` — pass `chain` (an author chain ID) to select a specific one
|
|
125
|
+
- `include` scopes which classes are fetched (`features`, `domains`, `variants`, `all`); `limit` caps each class independently (1–200, default 50), with a truncated class disclosed in `notice`
|
|
137
126
|
- Every response carries an `attribution` block naming the upstream data licenses and citations (see [Upstream data licensing](#upstream-data-licensing))
|
|
138
127
|
|
|
139
|
-
|
|
128
|
+
---
|
|
140
129
|
|
|
141
|
-
|
|
142
|
-
|:---|:---|:---|
|
|
143
|
-
| Resource | `pdb://{entry_id}` | Experimental structure summary for a PDB entry — title, method, resolution, organism, bound ligands, and per-entity chain IDs in both the author (`authAsymIds`) and mmCIF label (`labelAsymIds`) namespaces. |
|
|
144
|
-
| Resource | `af://{uniprot}` | Predicted-structure summary for a UniProt accession from AlphaFold DB — mean pLDDT, confidence-band fractions, model URLs, and version. |
|
|
130
|
+
### `pdb://{entry_id}` <sub>resource</sub>
|
|
145
131
|
|
|
146
|
-
|
|
132
|
+
- Experimental structure summary as `application/json` — title, method, resolution, organism, bound ligands, and per-entity chain IDs in both the author (`authAsymIds`) and mmCIF label (`labelAsymIds`) namespaces
|
|
133
|
+
- Mirrors `protein_get_structure` for `source: experimental`; `entry_id` is a PDB entry ID (e.g. `4HHB`)
|
|
147
134
|
|
|
148
|
-
|
|
135
|
+
---
|
|
149
136
|
|
|
150
|
-
|
|
137
|
+
### `af://{uniprot}` <sub>resource</sub>
|
|
151
138
|
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
- Pluggable auth: `none`, `jwt`, `oauth`
|
|
155
|
-
- Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
|
|
156
|
-
- Structured logging with optional OpenTelemetry tracing
|
|
157
|
-
- STDIO and Streamable HTTP transports
|
|
139
|
+
- Predicted-structure summary as `application/json` — mean pLDDT, confidence-band fractions, model URLs (`cif`/`pdb`/`bcif`), and AlphaFold model version
|
|
140
|
+
- `uniprot` accepts a UniProt accession or an AlphaFold DB entry ID (e.g. `AF-P69905-F1`); mirrors `protein_get_structure` for `source: predicted`
|
|
158
141
|
|
|
159
|
-
|
|
142
|
+
## Features
|
|
143
|
+
|
|
144
|
+
Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core): stdio and Streamable HTTP transports, pluggable auth (`none` / `jwt` / `oauth`), swappable storage (`in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`), structured logging with optional OpenTelemetry tracing.
|
|
145
|
+
|
|
146
|
+
PDB / AlphaFold-specific:
|
|
160
147
|
|
|
161
148
|
- One federated surface over experimental (PDB) and predicted (AlphaFold / 3D-Beacons) structures — search, fetch, and compare treat both universes the same
|
|
162
149
|
- Keyless across every upstream — RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek, no API keys to provision
|
|
@@ -186,7 +173,7 @@ A public instance is available at `https://protein.caseyjhand.com/mcp` — no in
|
|
|
186
173
|
}
|
|
187
174
|
```
|
|
188
175
|
|
|
189
|
-
### Self-
|
|
176
|
+
### Self-Hosted / Local
|
|
190
177
|
|
|
191
178
|
Add the following to your MCP client configuration file. No API key is required — every upstream provider is keyless.
|
|
192
179
|
|
|
@@ -247,7 +234,7 @@ MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
|
|
|
247
234
|
|
|
248
235
|
### Prerequisites
|
|
249
236
|
|
|
250
|
-
- [Bun v1.
|
|
237
|
+
- [Bun v1.4.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
251
238
|
- No accounts or API keys — RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek are all public and keyless.
|
|
252
239
|
|
|
253
240
|
### Installation
|
|
@@ -286,6 +273,7 @@ All upstream providers are keyless, so the server runs out of the box with no co
|
|
|
286
273
|
| `FOLDSEEK_BASE_URL` | Base URL for the Foldseek structural-similarity search service. | `https://search.foldseek.com` |
|
|
287
274
|
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
|
|
288
275
|
| `MCP_HTTP_PORT` | Port for the HTTP server. | `3010` |
|
|
276
|
+
| `MCP_SESSION_MODE` | HTTP session mode: `stateless`, `stateful`, or `auto`. The server declares `stateless` in code; set this to override it. | `stateless` |
|
|
289
277
|
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
290
278
|
| `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
|
|
291
279
|
| `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
|
|
@@ -333,7 +321,7 @@ The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `
|
|
|
333
321
|
| `src/config` | Server-specific environment variable parsing and validation with Zod. |
|
|
334
322
|
| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). |
|
|
335
323
|
| `src/mcp-server/resources` | Resource definitions (`*.resource.ts`). |
|
|
336
|
-
| `src/services` | Provider service layer — RCSB, AlphaFold, 3D-Beacons, UniProt
|
|
324
|
+
| `src/services` | Provider service layer — RCSB (search, data, facets), AlphaFold, 3D-Beacons (best-available), UniProt (incl. InterPro/GO), Structural Comparison alignment, Foldseek, and shared HTTP/identifier/concurrency helpers. |
|
|
337
325
|
| `tests/` | Unit and integration tests mirroring `src/`. |
|
|
338
326
|
|
|
339
327
|
## Development guide
|
|
@@ -345,15 +333,6 @@ See [`CLAUDE.md`/`AGENTS.md`](./CLAUDE.md) for development guidelines and archit
|
|
|
345
333
|
- Register new tools and resources via the barrels in `src/mcp-server/*/definitions/index.ts`
|
|
346
334
|
- Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
|
|
347
335
|
|
|
348
|
-
## Contributing
|
|
349
|
-
|
|
350
|
-
Issues and pull requests are welcome. Run checks and tests before submitting:
|
|
351
|
-
|
|
352
|
-
```sh
|
|
353
|
-
bun run devcheck
|
|
354
|
-
bun run test
|
|
355
|
-
```
|
|
356
|
-
|
|
357
336
|
## Upstream data licensing
|
|
358
337
|
|
|
359
338
|
Structure and annotation data comes from public upstream databases, each under its own license. `protein_get_structure` and `protein_get_annotations` carry an `attribution` block on every response — the license, citation, and homepage for each source that contributed to that specific response — so the attribution obligation travels with the data to downstream consumers rather than living only here. CC BY / CC BY-SA sources require attribution on redistribution; CC0 sources are citation-only (attribution encouraged, not required).
|
|
@@ -371,6 +350,15 @@ Structure and annotation data comes from public upstream databases, each under i
|
|
|
371
350
|
|
|
372
351
|
`best_available` federates predicted models through [3D-Beacons](https://3d-beacons.org/), so the `attribution` block credits the actual contributing provider (AlphaFold DB, SWISS-MODEL, BFVD, …); a provider without a curated license entry carries a `See provider terms` fallback pointing back to 3D-Beacons rather than a fabricated license. InterPro's own domain/family classifications are CC0; the GO terms carried alongside them are separately CC BY 4.0, so each is credited independently only when it actually contributes. Full citations for each source travel in the `attribution` block of the relevant tool responses. This covers upstream *data* licensing — the server's own code is licensed separately (see [License](#license)).
|
|
373
352
|
|
|
353
|
+
## Contributing
|
|
354
|
+
|
|
355
|
+
Issues are welcome. Run checks and tests before submitting:
|
|
356
|
+
|
|
357
|
+
```sh
|
|
358
|
+
bun run devcheck
|
|
359
|
+
bun run test
|
|
360
|
+
```
|
|
361
|
+
|
|
374
362
|
## License
|
|
375
363
|
|
|
376
364
|
Apache-2.0 — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts @cyanheads/mcp-ts-core 0.13.2, declaring stateless HTTP session mode in source, plus dependency and skills-tree maintenance."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.8.1 — 2026-09-16
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **Session mode** — the server declares `stateless` HTTP session mode in source (`createApp({ sessionMode: 'stateless' })`). With `MCP_SESSION_MODE` unset, an HTTP run now serves `stateless` — previously the schema default `auto` resolved to `stateful`; an explicit `MCP_SESSION_MODE` value still overrides it. The Docker image already set `stateless`.
|
|
12
|
+
- **`/.well-known/mcp.json`** — the server card now publishes the resolved session mode under the `_meta` key `io.github.cyanheads.mcp-ts-core/sessionMode`.
|
|
13
|
+
- **Shutdown** — `SIGTERM` and `SIGINT` now end the process once shutdown settles.
|
|
14
|
+
- **`skills/` → `framework-skills/`** — the framework's development skills moved, so a plugin install no longer hands them to the installing agent.
|
|
15
|
+
|
|
16
|
+
## Fixed
|
|
17
|
+
|
|
18
|
+
- **Landing page** — the curl snippet now sends a handshake `initialize` accepts.
|
|
19
|
+
- **`.env.example`** — session and host comments corrected (`MCP_HTTP_HOST` default `127.0.0.1`); README gains an `MCP_SESSION_MODE` row.
|
|
20
|
+
|
|
21
|
+
## Dependencies
|
|
22
|
+
|
|
23
|
+
- `@cyanheads/mcp-ts-core` ^0.12.7 → ^0.13.2
|
|
24
|
+
- Bun engines floor `>=1.3.0` → `>=1.4.0`
|
|
25
|
+
- `zod` ^4.5.4 → ^4.6.4
|
|
26
|
+
- `@biomejs/biome` 2.5.12 → 2.5.13
|
|
27
|
+
- `@types/node` 26.4.1 → 26.5.1
|
|
28
|
+
- `ignore` ^7.0.8 → ^7.0.9
|
|
29
|
+
- `tsc-alias` ^1.9.4 → ^1.9.5
|
package/changelog/template.md
CHANGED
|
@@ -117,30 +117,13 @@ security: false
|
|
|
117
117
|
in that unrelated item's metadata.
|
|
118
118
|
|
|
119
119
|
TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
|
|
120
|
-
via `gh release create --notes-from-tag`.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
Dependency bumps: ← section header
|
|
128
|
-
← blank line
|
|
129
|
-
- `@cyanheads/mcp-ts-core` ^0.9.1 → ^0.9.6 ← bullet
|
|
130
|
-
← blank line
|
|
131
|
-
Changed: ← only sections with entries
|
|
132
|
-
← blank line
|
|
133
|
-
- `format()` output includes `query` in text mode
|
|
134
|
-
← blank line
|
|
135
|
-
Added:
|
|
136
|
-
← blank line
|
|
137
|
-
- `manifest.json` scaffolded for MCPB bundle support
|
|
138
|
-
- Install badges (Claude Desktop, Cursor, VS Code)
|
|
139
|
-
← blank line
|
|
140
|
-
<N> tests pass; `bun run devcheck` clean. ← footer
|
|
141
|
-
|
|
142
|
-
Never a flat comma-separated string. Always structured markdown with
|
|
143
|
-
sections. The tag must scan well as a rendered GitHub Release page.
|
|
120
|
+
via `gh release create --notes-from-tag`. It is a condensed digest of this
|
|
121
|
+
entry, never a copy, and its format is owned by the `release-and-publish`
|
|
122
|
+
skill (step 4, "Create the annotated tag"): the entry's `summary:` as the
|
|
123
|
+
theme line without the version, flat headline bullets — no Keep-a-Changelog
|
|
124
|
+
section headers, no gates line — at most one deps line, issue backlinks,
|
|
125
|
+
and the changelog link last. In release-PR mode the `git-wrapup` skill
|
|
126
|
+
authors that digest as the PR body's `## Changes` and the tag copies it.
|
|
144
127
|
-->
|
|
145
128
|
|
|
146
129
|
## Added
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,8 @@ await createApp({
|
|
|
31
31
|
prompts: [],
|
|
32
32
|
// Public, keyless data server — serve the full inventory to unauthenticated callers.
|
|
33
33
|
landing: { requireAuth: false },
|
|
34
|
+
// No tool gates on ctx.requestInput, so HTTP serving needs no live session.
|
|
35
|
+
sessionMode: 'stateless',
|
|
34
36
|
/**
|
|
35
37
|
* Cache hints for protocol revision 2026-07-28. Every listing is static per
|
|
36
38
|
* build and identical for every caller — no auth-gated definitions, no
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACpG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE;QACL,gBAAgB;QAChB,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,iBAAiB;QACjB,iBAAiB;QACjB,cAAc;KACf;IACD,SAAS,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;IAClD,OAAO,EAAE,EAAE;IACX,qFAAqF;IACrF,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B;;;;;;;OAOG;IACH,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACxD,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC5D,0BAA0B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACtE,iBAAiB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC7D,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC7D;IACD,YAAY,EACV,srBAAsrB;IACxrB,KAAK,CAAC,IAAI;QACR,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACzD,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;CACF,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACpG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE;QACL,gBAAgB;QAChB,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,iBAAiB;QACjB,iBAAiB;QACjB,cAAc;KACf;IACD,SAAS,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;IAClD,OAAO,EAAE,EAAE;IACX,qFAAqF;IACrF,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B,4EAA4E;IAC5E,WAAW,EAAE,WAAW;IACxB;;;;;;;OAOG;IACH,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACxD,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC5D,0BAA0B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACtE,iBAAiB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC7D,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC7D;IACD,YAAY,EACV,srBAAsrB;IACxrB,KAAK,CAAC,IAAI;QACR,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACzD,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;CACF,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/protein-mcp-server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"mcpName": "io.github.cyanheads/protein-mcp-server",
|
|
5
5
|
"description": "Federated protein structure & annotation across experimental (PDB) and predicted (AlphaFold) models via MCP. STDIO or Streamable HTTP.",
|
|
6
6
|
"type": "module",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"rebuild": "bun run scripts/clean.ts && bun run scripts/build.ts",
|
|
25
25
|
"clean": "bun run scripts/clean.ts",
|
|
26
26
|
"devcheck": "bun run scripts/devcheck.ts",
|
|
27
|
+
"audit:fix": "bun audit fix",
|
|
27
28
|
"audit:refresh": "rm -f bun.lock && bun install && bun audit",
|
|
28
29
|
"tree": "bun run scripts/tree.ts",
|
|
29
30
|
"list-skills": "bun run scripts/list-skills.ts",
|
|
@@ -84,24 +85,24 @@
|
|
|
84
85
|
"license": "Apache-2.0",
|
|
85
86
|
"packageManager": "bun@1.4.0",
|
|
86
87
|
"engines": {
|
|
87
|
-
"bun": ">=1.
|
|
88
|
+
"bun": ">=1.4.0",
|
|
88
89
|
"node": ">=24.0.0"
|
|
89
90
|
},
|
|
90
91
|
"publishConfig": {
|
|
91
92
|
"access": "public"
|
|
92
93
|
},
|
|
93
94
|
"dependencies": {
|
|
94
|
-
"@cyanheads/mcp-ts-core": "^0.
|
|
95
|
+
"@cyanheads/mcp-ts-core": "^0.13.2",
|
|
95
96
|
"pino-pretty": "^13.1.3",
|
|
96
|
-
"zod": "^4.
|
|
97
|
+
"zod": "^4.6.4"
|
|
97
98
|
},
|
|
98
99
|
"devDependencies": {
|
|
99
|
-
"@biomejs/biome": "2.5.
|
|
100
|
+
"@biomejs/biome": "2.5.13",
|
|
100
101
|
"@socketsecurity/bun-security-scanner": "^1.1.2",
|
|
101
|
-
"@types/node": "26.
|
|
102
|
+
"@types/node": "26.5.1",
|
|
102
103
|
"depcheck": "^1.4.7",
|
|
103
|
-
"ignore": "^7.0.
|
|
104
|
-
"tsc-alias": "^1.9.
|
|
104
|
+
"ignore": "^7.0.9",
|
|
105
|
+
"tsc-alias": "^1.9.5",
|
|
105
106
|
"typescript": "^7.0.2",
|
|
106
107
|
"vitest": "^5.0.0"
|
|
107
108
|
}
|
package/server.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/protein-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.8.
|
|
9
|
+
"version": "0.8.1",
|
|
10
10
|
"remotes": [
|
|
11
11
|
{
|
|
12
12
|
"type": "streamable-http",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
20
20
|
"identifier": "@cyanheads/protein-mcp-server",
|
|
21
21
|
"runtimeHint": "node",
|
|
22
|
-
"version": "0.8.
|
|
22
|
+
"version": "0.8.1",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
49
49
|
"identifier": "@cyanheads/protein-mcp-server",
|
|
50
50
|
"runtimeHint": "node",
|
|
51
|
-
"version": "0.8.
|
|
51
|
+
"version": "0.8.1",
|
|
52
52
|
"packageArguments": [
|
|
53
53
|
{
|
|
54
54
|
"type": "positional",
|