@cyanheads/cyanheads-mcp-server 0.1.2 → 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 +1 -1
- package/CLAUDE.md +1 -1
- package/Dockerfile +3 -2
- package/README.md +199 -75
- package/changelog/0.1.x/0.1.3.md +11 -0
- package/changelog/0.1.x/0.1.4.md +22 -0
- package/dist/services/catalog/embeddings-runtime.d.ts.map +1 -1
- package/dist/services/catalog/embeddings-runtime.js +13 -1
- package/dist/services/catalog/embeddings-runtime.js.map +1 -1
- package/manifest.json +48 -0
- package/package.json +5 -1
- package/server.json +9 -3
package/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** cyanheads-mcp-server
|
|
4
|
-
**Version:** 0.1.
|
|
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.
|
|
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/Dockerfile
CHANGED
|
@@ -17,8 +17,9 @@ RUN bun install --frozen-lockfile
|
|
|
17
17
|
# Copy the rest of the source code
|
|
18
18
|
COPY . .
|
|
19
19
|
|
|
20
|
-
# Build the application
|
|
21
|
-
|
|
20
|
+
# Build the application. Invoke Bun on the script directly; `bun run build` goes
|
|
21
|
+
# through tsx, which trips a CJS resolver issue in Bun 1.3.x containers.
|
|
22
|
+
RUN bun scripts/build.ts
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
# ==============================================================================
|
package/README.md
CHANGED
|
@@ -1,143 +1,267 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
8
|
+
<div align="center">
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/cyanheads-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/cyanheads-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div align="center">
|
|
15
|
+
|
|
16
|
+
[](https://github.com/cyanheads/cyanheads-mcp-server/releases/latest/download/cyanheads-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=cyanheads-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvY3lhbmhlYWRzLW1jcC1zZXJ2ZXIiXX0=) [](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
|
+
[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
8
19
|
|
|
9
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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": "
|
|
98
|
+
"type": "streamable-http",
|
|
24
99
|
"url": "https://cyanheads.caseyjhand.com/mcp"
|
|
25
100
|
}
|
|
26
101
|
}
|
|
27
102
|
}
|
|
28
103
|
```
|
|
29
104
|
|
|
30
|
-
|
|
105
|
+
For Claude Code:
|
|
31
106
|
|
|
32
107
|
```sh
|
|
33
|
-
claude mcp add --transport
|
|
108
|
+
claude mcp add --transport http cyanheads https://cyanheads.caseyjhand.com/mcp
|
|
34
109
|
```
|
|
35
110
|
|
|
36
|
-
###
|
|
111
|
+
### Self-Hosted / Local
|
|
37
112
|
|
|
38
|
-
|
|
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": "
|
|
45
|
-
"
|
|
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
|
-
|
|
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
|
-
|
|
149
|
+
Or with Docker:
|
|
54
150
|
|
|
55
151
|
```json
|
|
56
152
|
{
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
+
- [Bun v1.3.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
79
173
|
|
|
80
|
-
|
|
174
|
+
### Installation
|
|
81
175
|
|
|
82
|
-
|
|
176
|
+
1. **Clone the repository:**
|
|
83
177
|
|
|
84
|
-
|
|
178
|
+
```sh
|
|
179
|
+
git clone https://github.com/cyanheads/cyanheads-mcp-server.git
|
|
180
|
+
```
|
|
85
181
|
|
|
86
|
-
|
|
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
|
-
|
|
184
|
+
```sh
|
|
185
|
+
cd cyanheads-mcp-server
|
|
186
|
+
```
|
|
94
187
|
|
|
95
|
-
|
|
188
|
+
3. **Install dependencies:**
|
|
96
189
|
|
|
97
|
-
|
|
190
|
+
```sh
|
|
191
|
+
bun install
|
|
192
|
+
```
|
|
98
193
|
|
|
99
|
-
|
|
194
|
+
## Configuration
|
|
100
195
|
|
|
101
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
215
|
+
## Running the server
|
|
109
216
|
|
|
110
|
-
|
|
217
|
+
### Local development
|
|
111
218
|
|
|
112
|
-
|
|
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
|
-
|
|
221
|
+
```sh
|
|
222
|
+
# One-time build
|
|
223
|
+
bun run rebuild
|
|
121
224
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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
|
-
|
|
250
|
+
See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
|
|
136
251
|
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
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,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Fix Dockerfile build to invoke Bun on the script directly so multi-arch image builds succeed"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.3 — 2026-05-28
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- **`Dockerfile`** build stage now runs `bun scripts/build.ts` instead of `bun run build`. The previous form went through `tsx`, which trips a CJS resolver issue inside `oven/bun:1.3` containers (`Cannot find module './cjs/index.cjs'`) on both `linux/amd64` and `linux/arm64`. Required for the multi-arch GHCR image to build at all.
|
|
@@ -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;
|
|
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":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAkC,QAAQ,EAAE,MAAM,2BAA2B,CAAC;
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
71
|
+
"version": "0.1.4",
|
|
66
72
|
"packageArguments": [
|
|
67
73
|
{ "type": "positional", "value": "run" },
|
|
68
74
|
{ "type": "positional", "value": "start:http" }
|