@cyanheads/cyanheads-mcp-server 0.1.3 → 0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Developer Protocol
2
2
 
3
3
  **Server:** cyanheads-mcp-server
4
- **Version:** 0.1.3
4
+ **Version:** 0.1.4
5
5
  **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.11`
6
6
  **Engines:** Bun ≥1.3.0, Node ≥24.0.0
7
7
  **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
package/CLAUDE.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Developer Protocol
2
2
 
3
3
  **Server:** cyanheads-mcp-server
4
- **Version:** 0.1.3
4
+ **Version:** 0.1.4
5
5
  **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.11`
6
6
  **Engines:** Bun ≥1.3.0, Node ≥24.0.0
7
7
  **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
package/README.md CHANGED
@@ -1,143 +1,267 @@
1
- # cyanheads-mcp-server
1
+ <div align="center">
2
+ <h1>@cyanheads/cyanheads-mcp-server</h1>
3
+ <p><b>Discover MCP servers via semantic search. One endpoint, 40+ hosted servers, per-client install snippets. STDIO or Streamable HTTP.</b>
4
+ <div>2 Tools • 0 Resources • 0 Prompts</div>
5
+ </p>
6
+ </div>
2
7
 
3
- **One MCP endpoint. 40+ hosted servers. Semantic search over every tool.**
8
+ <div align="center">
4
9
 
5
- ```
6
- https://cyanheads.caseyjhand.com/mcp
7
- ```
10
+ [![Version](https://img.shields.io/badge/Version-0.1.4-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/cyanheads-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/cyanheads-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/cyanheads-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^5.9.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-%3E=1.3.0-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
+
12
+ </div>
13
+
14
+ <div align="center">
15
+
16
+ [![Install in Claude Desktop](https://img.shields.io/badge/Install_in-Claude_Desktop-D97757?style=for-the-badge&logo=anthropic&logoColor=white)](https://github.com/cyanheads/cyanheads-mcp-server/releases/latest/download/cyanheads-mcp-server.mcpb) [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=cyanheads-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvY3lhbmhlYWRzLW1jcC1zZXJ2ZXIiXX0=) [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22cyanheads-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads/cyanheads-mcp-server%22%5D%7D)
17
+
18
+ [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-67E8F9?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
8
19
 
9
- Add that URL to your MCP client. Your agent gets two tools — `cyanheads_search` and `cyanheads_describe` — and uses them to discover and install any server in the cyanheads fleet without you maintaining a sprawling local config.
20
+ </div>
21
+
22
+ <div align="center">
23
+
24
+ **Public Hosted Server:** [https://cyanheads.caseyjhand.com/mcp](https://cyanheads.caseyjhand.com/mcp)
25
+
26
+ </div>
10
27
 
11
28
  ---
12
29
 
13
- ## Add it to your client
30
+ ## Tools
31
+
32
+ Two tools, semantic ranking, hosted catalog. The catalog itself lives at [`caseyjhand.com/fleet.json`](https://caseyjhand.com/fleet.json) — a single JSON file with baked embeddings, regenerated when servers are added or updated. This server polls it hourly and serves search out of an in-memory vector index.
33
+
34
+ | Tool | Description |
35
+ |:---|:---|
36
+ | `cyanheads_search` | Search fleet tools and servers by natural-language query. Returns ranked matches with brief summaries and the owning server. |
37
+ | `cyanheads_describe` | Return the connection URL and per-client install snippets for a named tool or server. |
38
+
39
+ ### `cyanheads_search`
40
+
41
+ Semantic search across the fleet. Embeds the query with [Snowflake Arctic Embed M v1.5](https://huggingface.co/Snowflake/snowflake-arctic-embed-m-v1.5) (Matryoshka-truncated to 256 dimensions) and computes cosine similarity against the catalog's pre-computed document vectors.
42
+
43
+ - `scope: "tools"` (default) returns individual tool matches; `scope: "servers"` returns server-level matches
44
+ - `category` filter narrows to one of `research`, `government`, `public-data`, `utility`
45
+ - Configurable `limit` (1-20, default 5) and a server-side `SIMILARITY_FLOOR` threshold drop low-confidence hits
46
+ - Returns `score` (cosine similarity in [0, 1]) on every result for trust calibration
47
+ - `totalMatched` reports the count above the floor before the limit was applied
48
+
49
+ ---
50
+
51
+ ### `cyanheads_describe`
52
+
53
+ Resolve a name to its install instructions. Accepts either a tool name (snake_case, e.g. `earthquake_search`) or a server name (kebab-case, e.g. `earthquake-mcp-server`) — auto-detected from the format, or pinned via the `kind` parameter.
54
+
55
+ - For tools: returns the description and the owning server name
56
+ - For servers: returns description, version, npm package, GitHub URL, hosted endpoint URL, tool count, and per-client install snippets
57
+ - `client` filter narrows snippets to one of `claude-desktop`, `claude-code`, `cursor`, `cline`; omit to return all four
58
+ - Discriminated output on `kind` — callers branch on data, not string parsing
59
+
60
+ ## Features
61
+
62
+ Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core):
14
63
 
15
- ### Claude Desktop
64
+ - Declarative tool definitions — single file per tool, framework handles registration and validation
65
+ - Unified error handling with typed error contracts and recovery hints
66
+ - Pluggable auth (`none`, `jwt`, `oauth`)
67
+ - Structured logging with optional OpenTelemetry tracing
68
+ - Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
16
69
 
17
- Open `~/Library/Application Support/Claude/claude_desktop_config.json` and merge into `mcpServers`:
70
+ Fleet-specific:
71
+
72
+ - Hourly background catalog refresh with atomic swap on `generatedAt` change — no restart needed when the fleet updates
73
+ - L2-normalized 256-dim Matryoshka-truncated vectors keep memory under 100KB for a 40-server fleet
74
+ - Per-client install snippet generation (Claude Desktop, Claude Code, Cursor, Cline) at describe-time, not catalog-generation time — snippets stay in sync with the deployed endpoint
75
+ - Discriminated `result.kind` and typed `installSnippets[].client` enums — agents can branch reliably
76
+
77
+ ## What's in the fleet
78
+
79
+ 40+ MCP servers spanning four categories. Each is open source and individually addressable — `cyanheads_describe` returns its direct connection URL alongside the install snippet.
80
+
81
+ | Category | Examples |
82
+ |:--|:--|
83
+ | **Research** | arXiv, bioRxiv, ORCID, Crossref, Wikipedia, Wikidata, OpenLibrary |
84
+ | **Government** | OpenStates, USAspending, CourtListener, NIST NVD, Library of Congress |
85
+ | **Public Data** | Earthquake (USGS), NOAA Weather, GBIF Biodiversity, World Bank, WHO, Eurostat |
86
+ | **Utility** | OpenStreetMap geocoding, Reference Data (constants, timezones, units), WSDOT |
87
+
88
+ ## Getting started
89
+
90
+ ### Public Hosted Instance
91
+
92
+ A public instance is available at `https://cyanheads.caseyjhand.com/mcp` — no installation required. Point any MCP client at it via Streamable HTTP:
18
93
 
19
94
  ```json
20
95
  {
21
96
  "mcpServers": {
22
97
  "cyanheads": {
23
- "type": "sse",
98
+ "type": "streamable-http",
24
99
  "url": "https://cyanheads.caseyjhand.com/mcp"
25
100
  }
26
101
  }
27
102
  }
28
103
  ```
29
104
 
30
- ### Claude Code
105
+ For Claude Code:
31
106
 
32
107
  ```sh
33
- claude mcp add --transport sse cyanheads https://cyanheads.caseyjhand.com/mcp
108
+ claude mcp add --transport http cyanheads https://cyanheads.caseyjhand.com/mcp
34
109
  ```
35
110
 
36
- ### Cursor
111
+ ### Self-Hosted / Local
37
112
 
38
- Merge into `.cursor/mcp.json`:
113
+ Add the following to your MCP client configuration file.
39
114
 
40
115
  ```json
41
116
  {
42
117
  "mcpServers": {
43
118
  "cyanheads": {
44
- "type": "sse",
45
- "url": "https://cyanheads.caseyjhand.com/mcp"
119
+ "type": "stdio",
120
+ "command": "bunx",
121
+ "args": ["@cyanheads/cyanheads-mcp-server@latest"],
122
+ "env": {
123
+ "MCP_TRANSPORT_TYPE": "stdio",
124
+ "MCP_LOG_LEVEL": "info"
125
+ }
46
126
  }
47
127
  }
48
128
  }
49
129
  ```
50
130
 
51
- ### Cline
131
+ Or with npx (no Bun required):
132
+
133
+ ```json
134
+ {
135
+ "mcpServers": {
136
+ "cyanheads": {
137
+ "type": "stdio",
138
+ "command": "npx",
139
+ "args": ["-y", "@cyanheads/cyanheads-mcp-server@latest"],
140
+ "env": {
141
+ "MCP_TRANSPORT_TYPE": "stdio",
142
+ "MCP_LOG_LEVEL": "info"
143
+ }
144
+ }
145
+ }
146
+ }
147
+ ```
52
148
 
53
- Merge into Cline's MCP settings:
149
+ Or with Docker:
54
150
 
55
151
  ```json
56
152
  {
57
- "cyanheads": {
58
- "type": "sse",
59
- "url": "https://cyanheads.caseyjhand.com/mcp",
60
- "disabled": false,
61
- "autoApprove": []
153
+ "mcpServers": {
154
+ "cyanheads": {
155
+ "type": "stdio",
156
+ "command": "docker",
157
+ "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/cyanheads-mcp-server:latest"]
158
+ }
62
159
  }
63
160
  }
64
161
  ```
65
162
 
66
- ---
163
+ For Streamable HTTP, set the transport and start the server:
67
164
 
68
- ## What you can ask
165
+ ```sh
166
+ MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
167
+ # Server listens at http://localhost:3010/mcp
168
+ ```
69
169
 
70
- | You say | Agent finds |
71
- |:--|:--|
72
- | "search recent arxiv papers about quantum computing" | `arxiv_search` (arxiv-mcp-server), via semantic match on "research papers" |
73
- | "look up earthquake activity in California" | `earthquake_search` (earthquake-mcp-server) |
74
- | "what server handles federal spending data?" | `usaspending-mcp-server` (scope: servers) |
75
- | "find a tool that resolves a place name to coordinates" | `openstreetmap_geocode` (openstreetmap-mcp-server) |
76
- | "how do I add the bioRxiv server to Cursor?" | Install snippet via `cyanheads_describe` |
170
+ ### Prerequisites
77
171
 
78
- After each search match, the agent can ask `cyanheads_describe` to get the connection URL and per-client install snippet so you can add the underlying server directly if you want it always-on.
172
+ - [Bun v1.3.0](https://bun.sh/) or higher (or Node.js v24+).
79
173
 
80
- ---
174
+ ### Installation
81
175
 
82
- ## What's in the fleet
176
+ 1. **Clone the repository:**
83
177
 
84
- 40+ MCP servers spanning four domains. The catalog is regenerated on every portfolio deploy by walking each server's live endpoint — descriptions and tool names always match what the server actually exposes.
178
+ ```sh
179
+ git clone https://github.com/cyanheads/cyanheads-mcp-server.git
180
+ ```
85
181
 
86
- | Category | Examples |
87
- |:--|:--|
88
- | **Research** | arXiv, bioRxiv, ORCID, Crossref, Wikipedia, Wikidata, OpenLibrary |
89
- | **Government** | OpenStates, USAspending, CourtListener, NIST NVD, Library of Congress |
90
- | **Public Data** | Earthquake (USGS), NOAA Weather, GBIF Biodiversity, World Bank, WHO, Eurostat |
91
- | **Utility** | OpenStreetMap geocoding, Reference Data (constants, timezones, units), WSDOT |
182
+ 2. **Navigate into the directory:**
92
183
 
93
- Each server is open source and individually addressable — `cyanheads_describe` returns the direct connection URL alongside the install snippet.
184
+ ```sh
185
+ cd cyanheads-mcp-server
186
+ ```
94
187
 
95
- ---
188
+ 3. **Install dependencies:**
96
189
 
97
- ## How it works
190
+ ```sh
191
+ bun install
192
+ ```
98
193
 
99
- Two tools, semantic ranking, hosted catalog.
194
+ ## Configuration
100
195
 
101
- - **`cyanheads_search`** embeds your natural-language query with [Snowflake Arctic Embed M v1.5](https://huggingface.co/Snowflake/snowflake-arctic-embed-m-v1.5) (Matryoshka-truncated to 256 dimensions) and computes cosine similarity against the catalog's pre-computed document vectors. Returns the top-N matching tools or servers.
102
- - **`cyanheads_describe`** returns the description, connection URL, and per-client install snippet for any tool or server name.
196
+ All configuration is validated at startup via Zod schemas in `src/config/server-config.ts`. Every variable has a sensible default — out of the box, the server points at the canonical cyanheads fleet.
103
197
 
104
- The catalog itself lives at [`caseyjhand.com/fleet.json`](https://caseyjhand.com/fleet.json) — a single JSON file with baked embeddings, regenerated when servers are added or updated. This server polls it hourly and serves search out of an in-memory vector index.
198
+ | Variable | Description | Default |
199
+ |:---|:---|:---|
200
+ | `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http` | `stdio` |
201
+ | `MCP_HTTP_PORT` | HTTP server port | `3010` |
202
+ | `MCP_HTTP_HOST` | HTTP server bind host | `127.0.0.1` |
203
+ | `MCP_HTTP_ENDPOINT_PATH` | HTTP endpoint path where the MCP server is mounted | `/mcp` |
204
+ | `MCP_AUTH_MODE` | Authentication: `none`, `jwt`, or `oauth` | `none` |
205
+ | `MCP_LOG_LEVEL` | Log level (`debug`, `info`, `warning`, `error`, etc.) | `info` |
206
+ | `CATALOG_URL` | Remote fleet.json endpoint (schema v2 with baked embeddings). Override to front your own fleet. | `https://caseyjhand.com/fleet.json` |
207
+ | `CATALOG_FETCH_TIMEOUT_MS` | Per-request timeout for fleet.json fetches in ms | `10000` |
208
+ | `CATALOG_REFRESH_SECONDS` | Background poll interval for fleet.json refresh. `0` disables. | `3600` |
209
+ | `EMBEDDING_MODEL_ID` | Hugging Face model id for query embedding. Must match `fleet.json.embeddingModel`. | `Snowflake/snowflake-arctic-embed-m-v1.5` |
210
+ | `SIMILARITY_FLOOR` | Cosine similarity cutoff for `cyanheads_search` results (0-1) | `0.3` |
211
+ | `OTEL_ENABLED` | Enable OpenTelemetry | `false` |
105
212
 
106
- ---
213
+ To point at a different catalog, change `CATALOG_URL` to your own hosted JSON file. See [`docs/design.md`](./docs/design.md) for the producer-side script and schema.
107
214
 
108
- ## Self-hosting
215
+ ## Running the server
109
216
 
110
- You probably don't need this — the hosted endpoint is the product. The source is open for reference and the rare case where you want to front your own fleet.
217
+ ### Local development
111
218
 
112
- ```sh
113
- git clone https://github.com/cyanheads/cyanheads-mcp-server.git
114
- cd cyanheads-mcp-server
115
- bun install
116
- bun run build
117
- bun run start:http
118
- ```
219
+ - **Build and run the production version**:
119
220
 
120
- Environment variables (all optional):
221
+ ```sh
222
+ # One-time build
223
+ bun run rebuild
121
224
 
122
- | Variable | Default | Description |
123
- |:--|:--|:--|
124
- | `CATALOG_URL` | `https://caseyjhand.com/fleet.json` | Remote fleet.json endpoint (must be schema v2 with baked embeddings). |
125
- | `CATALOG_REFRESH_SECONDS` | `3600` | Background poll interval. 0 disables. |
126
- | `EMBEDDING_MODEL_ID` | `Snowflake/snowflake-arctic-embed-m-v1.5` | Must match `fleet.json.embeddingModel`. |
127
- | `SIMILARITY_FLOOR` | `0.3` | Cosine similarity threshold below which results are dropped. |
128
- | `MCP_TRANSPORT_TYPE` | `stdio` | `stdio` or `http`. |
129
- | `MCP_HTTP_PORT` | `3000` | HTTP port when transport is `http`. |
225
+ # Run the built server
226
+ bun run start:http
227
+ # or
228
+ bun run start:stdio
229
+ ```
130
230
 
131
- To point at a different catalog, change `CATALOG_URL` to your own hosted JSON file. See [the cyanheads-mcp-server design doc](./docs/design.md) for the producer-side script and schema.
231
+ - **Run checks and tests**:
232
+ ```sh
233
+ bun run devcheck # Lints, formats, type-checks, runs MCP and packaging linters
234
+ bun run test # Runs the test suite
235
+ ```
132
236
 
133
- ---
237
+ ## Project structure
238
+
239
+ | Directory | Purpose |
240
+ |:---|:---|
241
+ | `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). Two tools — `cyanheads_search` and `cyanheads_describe`. |
242
+ | `src/services/catalog` | Catalog service — remote fleet.json provider with atomic-swap refresh, vector index, snippet builders. |
243
+ | `src/services/embeddings` | Embedding runtime — query-time inference via `@huggingface/transformers`, with an injectable interface for deterministic tests. |
244
+ | `src/config` | Server-specific environment variable parsing and validation with Zod. |
245
+ | `tests/` | Unit and integration tests, mirroring the `src/` structure. |
246
+ | `docs/` | Design doc and schema reference. |
247
+
248
+ ## Development guide
134
249
 
135
- ## Built with
250
+ See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
136
251
 
137
- - [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) — TypeScript MCP server framework
138
- - [`@huggingface/transformers`](https://www.npmjs.com/package/@huggingface/transformers) — ONNX-based runtime for embeddings inference
139
- - [Snowflake Arctic Embed M v1.5](https://huggingface.co/Snowflake/snowflake-arctic-embed-m-v1.5) — embedding model (Apache 2.0)
252
+ - Handlers throw, framework catches — no `try/catch` in tool logic
253
+ - Use `ctx.log` for logging, `ctx.state` for storage
254
+ - Register new tools in `src/mcp-server/tools/definitions/index.ts`
255
+
256
+ ## Contributing
257
+
258
+ Issues and pull requests are welcome. Run checks and tests before submitting:
259
+
260
+ ```sh
261
+ bun run devcheck
262
+ bun run test
263
+ ```
140
264
 
141
265
  ## License
142
266
 
143
- Apache 2.0. See [LICENSE](./LICENSE).
267
+ This project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.
@@ -0,0 +1,22 @@
1
+ ---
2
+ summary: "README rewrite to match pubmed gold standard, .mcpb bundle restored for Claude Desktop one-click install, embeddings cache dir fix unblocks Docker non-root user, server.json advertises hosted endpoint via remotes[]"
3
+ breaking: false
4
+ security: false
5
+ ---
6
+
7
+ # 0.1.4 — 2026-05-28
8
+
9
+ ## Added
10
+
11
+ - **`manifest.json`** + **`.mcpbignore`** + `bun run bundle` script restore the `.mcpb` packaging path. The `Install in Claude Desktop` badge in the README now resolves to `releases/latest/download/cyanheads-mcp-server.mcpb` and one-click-installs into Claude Desktop without manual JSON editing. `manifest.json` exposes `CATALOG_URL` and `SIMILARITY_FLOOR` as `user_config` knobs so users can override the default fleet or tighten the relevance cutoff at install time.
12
+ - **`scripts/lint-packaging.ts`** — env-var alignment linter between `manifest.json` and `server.json` (stdio package `environmentVariables[]`). Wired into `devcheck` (skips cleanly when `manifest.json` is absent).
13
+ - **`server.json` `remotes[]`** — advertises `https://cyanheads.caseyjhand.com/mcp` as a streamable-http endpoint so MCP Registry consumers can discover the hosted instance without reading the README.
14
+ - **README** — full rewrite to match the pubmed-mcp-server gold standard: centered hero with title + tool count, badge row (Version, License, Docker, MCP SDK, npm, TypeScript, Bun), one-click install badges (Claude Desktop `.mcpb`, Cursor deeplink, VS Code), hosted-endpoint callout, per-tool detail sections, project structure, and a configuration table covering every env var with its default.
15
+
16
+ ## Changed
17
+
18
+ - **`server.json`** + **`package.json`** + **`manifest.json`** versions to `0.1.4`. `package.json` `files` array now includes `manifest.json` so it ships in the published tarball.
19
+
20
+ ## Fixed
21
+
22
+ - **Embeddings runtime cache dir** — `@huggingface/transformers` defaults its model cache to a subpath inside its own `node_modules` install (`node_modules/@huggingface/transformers/.cache`). Containers that `bun install` as root then drop to a non-root runtime user (the production Dockerfile pattern) crash on first query with `EACCES: permission denied, mkdir`. `src/services/catalog/embeddings-runtime.ts` now sets `env.cacheDir` at import time to `HF_HOME` / `TRANSFORMERS_CACHE` if set, otherwise a per-OS `tmpdir/cyanheads-mcp-server/hf-cache` fallback that's always writable.
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings-runtime.d.ts","sourceRoot":"","sources":["../../../src/services/catalog/embeddings-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACnF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,6BAA8B,YAAW,kBAAkB;aAG1C,OAAO,EAAE,MAAM;IAF3C,OAAO,CAAC,UAAU,CAA0C;gBAEhC,OAAO,EAAE,MAAM;IAErC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAmCzF"}
1
+ {"version":3,"file":"embeddings-runtime.d.ts","sourceRoot":"","sources":["../../../src/services/catalog/embeddings-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoBH,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACnF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,6BAA8B,YAAW,kBAAkB;aAG1C,OAAO,EAAE,MAAM;IAF3C,OAAO,CAAC,UAAU,CAA0C;gBAEhC,OAAO,EAAE,MAAM;IAErC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAmCzF"}
@@ -6,9 +6,21 @@
6
6
  * Matryoshka-truncates + L2-normalizes the output to match document vectors.
7
7
  * @module services/catalog/embeddings-runtime
8
8
  */
9
+ import os from 'node:os';
10
+ import path from 'node:path';
9
11
  import { JsonRpcErrorCode, McpError } from '@cyanheads/mcp-ts-core/errors';
10
12
  import { logger } from '@cyanheads/mcp-ts-core/utils';
11
- import { pipeline } from '@huggingface/transformers';
13
+ import { env, pipeline } from '@huggingface/transformers';
14
+ /**
15
+ * Redirect the model cache out of the package's `node_modules/.cache` default
16
+ * (unwritable in containers that install deps as root then drop to a non-root
17
+ * runtime user). HF_HOME / TRANSFORMERS_CACHE honored when set; otherwise fall
18
+ * back to a writable per-OS temp directory.
19
+ */
20
+ env.cacheDir =
21
+ process.env.HF_HOME ??
22
+ process.env.TRANSFORMERS_CACHE ??
23
+ path.join(os.tmpdir(), 'cyanheads-mcp-server', 'hf-cache');
12
24
  export class TransformersEmbeddingsRuntime {
13
25
  modelId;
14
26
  _extractor = null;
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings-runtime.js","sourceRoot":"","sources":["../../../src/services/catalog/embeddings-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embeddings-runtime.js","sourceRoot":"","sources":["../../../src/services/catalog/embeddings-runtime.ts"],"names":[],"mappings":"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"}
package/manifest.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "manifest_version": "0.3",
3
+ "name": "cyanheads-mcp-server",
4
+ "version": "0.1.4",
5
+ "description": "Fleet discovery for the cyanheads MCP ecosystem — semantic search + install snippets.",
6
+ "author": { "name": "cyanheads" },
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/cyanheads/cyanheads-mcp-server"
10
+ },
11
+ "homepage": "https://github.com/cyanheads/cyanheads-mcp-server#readme",
12
+ "license": "Apache-2.0",
13
+ "server": {
14
+ "type": "node",
15
+ "entry_point": "dist/index.js",
16
+ "mcp_config": {
17
+ "command": "node",
18
+ "args": ["${__dirname}/dist/index.js"],
19
+ "env": {
20
+ "MCP_TRANSPORT_TYPE": "stdio",
21
+ "MCP_AUTH_MODE": "none",
22
+ "NODE_ENV": "production",
23
+ "CATALOG_URL": "${user_config.catalog_url}",
24
+ "SIMILARITY_FLOOR": "${user_config.similarity_floor}"
25
+ }
26
+ }
27
+ },
28
+ "compatibility": {
29
+ "runtimes": { "node": ">=24.0.0" }
30
+ },
31
+ "tools_generated": true,
32
+ "user_config": {
33
+ "catalog_url": {
34
+ "type": "string",
35
+ "title": "Catalog URL",
36
+ "description": "Remote fleet.json endpoint (schema v2 with baked embeddings). Defaults to the canonical cyanheads fleet — override to point at your own hosted catalog.",
37
+ "required": false,
38
+ "default": "https://caseyjhand.com/fleet.json"
39
+ },
40
+ "similarity_floor": {
41
+ "type": "string",
42
+ "title": "Similarity Floor",
43
+ "description": "Cosine similarity cutoff for cyanheads_search results (0-1). Raise to require closer matches; lower to surface more candidates.",
44
+ "required": false,
45
+ "default": "0.3"
46
+ }
47
+ }
48
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cyanheads/cyanheads-mcp-server",
3
3
  "mcpName": "io.github.cyanheads/cyanheads-mcp-server",
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "description": "Fleet discovery for the cyanheads MCP ecosystem — semantic search + install snippets.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -17,6 +17,7 @@
17
17
  "CLAUDE.md",
18
18
  "AGENTS.md",
19
19
  "Dockerfile",
20
+ "manifest.json",
20
21
  "server.json"
21
22
  ],
22
23
  "author": "cyanheads <casey@caseyjhand.com> (https://github.com/cyanheads/cyanheads-mcp-server#readme)",
@@ -34,6 +35,9 @@
34
35
  "list-skills": "tsx scripts/list-skills.ts",
35
36
  "format": "biome check --write --unsafe .",
36
37
  "lint:mcp": "tsx scripts/lint-mcp.ts",
38
+ "lint:packaging": "tsx scripts/lint-packaging.ts",
39
+ "bundle": "tsx scripts/build.ts && npx -y @anthropic-ai/mcpb pack . dist/cyanheads-mcp-server.mcpb",
40
+ "publish-mcp": "mcp-publisher login github -token \"$(security find-generic-password -a \"$USER\" -s mcp-publisher-github-pat -w)\" && mcp-publisher publish",
37
41
  "changelog:build": "tsx scripts/build-changelog.ts",
38
42
  "changelog:check": "tsx scripts/build-changelog.ts --check",
39
43
  "test": "vitest run",
package/server.json CHANGED
@@ -6,14 +6,20 @@
6
6
  "url": "https://github.com/cyanheads/cyanheads-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.1.3",
9
+ "version": "0.1.4",
10
+ "remotes": [
11
+ {
12
+ "type": "streamable-http",
13
+ "url": "https://cyanheads.caseyjhand.com/mcp"
14
+ }
15
+ ],
10
16
  "packages": [
11
17
  {
12
18
  "registryType": "npm",
13
19
  "registryBaseUrl": "https://registry.npmjs.org",
14
20
  "identifier": "@cyanheads/cyanheads-mcp-server",
15
21
  "runtimeHint": "node",
16
- "version": "0.1.3",
22
+ "version": "0.1.4",
17
23
  "packageArguments": [
18
24
  { "type": "positional", "value": "run" },
19
25
  { "type": "positional", "value": "start:stdio" }
@@ -62,7 +68,7 @@
62
68
  "registryBaseUrl": "https://registry.npmjs.org",
63
69
  "identifier": "@cyanheads/cyanheads-mcp-server",
64
70
  "runtimeHint": "node",
65
- "version": "0.1.3",
71
+ "version": "0.1.4",
66
72
  "packageArguments": [
67
73
  { "type": "positional", "value": "run" },
68
74
  { "type": "positional", "value": "start:http" }