@cyanheads/cyanheads-mcp-server 0.1.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.
Files changed (46) hide show
  1. package/AGENTS.md +367 -0
  2. package/CLAUDE.md +367 -0
  3. package/Dockerfile +99 -0
  4. package/LICENSE +201 -0
  5. package/README.md +143 -0
  6. package/changelog/0.1.x/0.1.0.md +12 -0
  7. package/changelog/0.1.x/0.1.1.md +38 -0
  8. package/changelog/template.md +127 -0
  9. package/dist/config/server-config.d.ts +19 -0
  10. package/dist/config/server-config.d.ts.map +1 -0
  11. package/dist/config/server-config.js +66 -0
  12. package/dist/config/server-config.js.map +1 -0
  13. package/dist/index.d.ts +7 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +26 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/mcp-server/tools/definitions/describe.tool.d.ts +67 -0
  18. package/dist/mcp-server/tools/definitions/describe.tool.d.ts.map +1 -0
  19. package/dist/mcp-server/tools/definitions/describe.tool.js +192 -0
  20. package/dist/mcp-server/tools/definitions/describe.tool.js.map +1 -0
  21. package/dist/mcp-server/tools/definitions/search.tool.d.ts +53 -0
  22. package/dist/mcp-server/tools/definitions/search.tool.d.ts.map +1 -0
  23. package/dist/mcp-server/tools/definitions/search.tool.js +123 -0
  24. package/dist/mcp-server/tools/definitions/search.tool.js.map +1 -0
  25. package/dist/services/catalog/catalog-service.d.ts +50 -0
  26. package/dist/services/catalog/catalog-service.d.ts.map +1 -0
  27. package/dist/services/catalog/catalog-service.js +233 -0
  28. package/dist/services/catalog/catalog-service.js.map +1 -0
  29. package/dist/services/catalog/embeddings-runtime.d.ts +21 -0
  30. package/dist/services/catalog/embeddings-runtime.d.ts.map +1 -0
  31. package/dist/services/catalog/embeddings-runtime.js +62 -0
  32. package/dist/services/catalog/embeddings-runtime.js.map +1 -0
  33. package/dist/services/catalog/remote-catalog-provider.d.ts +20 -0
  34. package/dist/services/catalog/remote-catalog-provider.d.ts.map +1 -0
  35. package/dist/services/catalog/remote-catalog-provider.js +84 -0
  36. package/dist/services/catalog/remote-catalog-provider.js.map +1 -0
  37. package/dist/services/catalog/snippets.d.ts +16 -0
  38. package/dist/services/catalog/snippets.d.ts.map +1 -0
  39. package/dist/services/catalog/snippets.js +51 -0
  40. package/dist/services/catalog/snippets.js.map +1 -0
  41. package/dist/services/catalog/types.d.ts +135 -0
  42. package/dist/services/catalog/types.d.ts.map +1 -0
  43. package/dist/services/catalog/types.js +8 -0
  44. package/dist/services/catalog/types.js.map +1 -0
  45. package/package.json +83 -0
  46. package/server.json +141 -0
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # cyanheads-mcp-server
2
+
3
+ **One MCP endpoint. 40+ hosted servers. Semantic search over every tool.**
4
+
5
+ ```
6
+ https://cyanheads.caseyjhand.com/mcp
7
+ ```
8
+
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.
10
+
11
+ ---
12
+
13
+ ## Add it to your client
14
+
15
+ ### Claude Desktop
16
+
17
+ Open `~/Library/Application Support/Claude/claude_desktop_config.json` and merge into `mcpServers`:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "cyanheads": {
23
+ "type": "sse",
24
+ "url": "https://cyanheads.caseyjhand.com/mcp"
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ ### Claude Code
31
+
32
+ ```sh
33
+ claude mcp add --transport sse cyanheads https://cyanheads.caseyjhand.com/mcp
34
+ ```
35
+
36
+ ### Cursor
37
+
38
+ Merge into `.cursor/mcp.json`:
39
+
40
+ ```json
41
+ {
42
+ "mcpServers": {
43
+ "cyanheads": {
44
+ "type": "sse",
45
+ "url": "https://cyanheads.caseyjhand.com/mcp"
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### Cline
52
+
53
+ Merge into Cline's MCP settings:
54
+
55
+ ```json
56
+ {
57
+ "cyanheads": {
58
+ "type": "sse",
59
+ "url": "https://cyanheads.caseyjhand.com/mcp",
60
+ "disabled": false,
61
+ "autoApprove": []
62
+ }
63
+ }
64
+ ```
65
+
66
+ ---
67
+
68
+ ## What you can ask
69
+
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` |
77
+
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.
79
+
80
+ ---
81
+
82
+ ## What's in the fleet
83
+
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.
85
+
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 |
92
+
93
+ Each server is open source and individually addressable — `cyanheads_describe` returns the direct connection URL alongside the install snippet.
94
+
95
+ ---
96
+
97
+ ## How it works
98
+
99
+ Two tools, semantic ranking, hosted catalog.
100
+
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.
103
+
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.
105
+
106
+ ---
107
+
108
+ ## Self-hosting
109
+
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.
111
+
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
+ ```
119
+
120
+ Environment variables (all optional):
121
+
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`. |
130
+
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.
132
+
133
+ ---
134
+
135
+ ## Built with
136
+
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)
140
+
141
+ ## License
142
+
143
+ Apache 2.0. See [LICENSE](./LICENSE).
@@ -0,0 +1,12 @@
1
+ ---
2
+ summary: "Initial scaffold bootstrap from @cyanheads/mcp-ts-core init"
3
+ breaking: false
4
+ security: false
5
+ ---
6
+
7
+ # 0.1.0 — 2026-05-28
8
+
9
+ ## Added
10
+
11
+ - Initial scaffold generated by `bunx @cyanheads/mcp-ts-core init`.
12
+ - Project structure, framework wiring, devcheck configuration, baseline project skills.
@@ -0,0 +1,38 @@
1
+ ---
2
+ summary: "First public release — cyanheads_search semantic discovery over the cyanheads MCP fleet, cyanheads_describe with per-client install snippets"
3
+ breaking: false
4
+ security: false
5
+ ---
6
+
7
+ # 0.1.1 — 2026-05-28
8
+
9
+ First substantive release. The scaffold tag (`v0.1.0`) carried no functionality; this release lands the full fleet discovery surface.
10
+
11
+ ## Added
12
+
13
+ - **`cyanheads_search`** — semantic search over fleet tools and servers. Embeds the query at runtime with [`Snowflake/snowflake-arctic-embed-m-v1.5`](https://huggingface.co/Snowflake/snowflake-arctic-embed-m-v1.5), dot-products against L2-normalized 256-dim Matryoshka-truncated document vectors, filters by category and similarity floor, returns ranked matches. Auth scope: `tool:cyanheads_search:read`.
14
+ - **`cyanheads_describe`** — returns description, hosted connection URL, and per-client install snippets (Claude Desktop, Claude Code, Cursor, Cline) for any named tool or server. Auto-detects kind from name format (underscores → tool, hyphens → server). Auth scope: `tool:cyanheads_describe:read`.
15
+ - **`CatalogService`** — in-memory packed `Float32Array` vector index, atomic-swap refresh on every `fleet.json` `generatedAt` change. Polls hourly by default.
16
+ - **`TransformersEmbeddingsRuntime`** — wraps `@huggingface/transformers`'s `feature-extraction` pipeline. Loads the model once at startup and reuses it for every query.
17
+ - **`RemoteJsonCatalogProvider`** — fetches and Zod-validates the v2 `fleet.json` payload from `CATALOG_URL` (default `https://caseyjhand.com/fleet.json`). Refuses to load on `embeddingModel` mismatch.
18
+ - **Env vars:** `CATALOG_URL`, `CATALOG_FETCH_TIMEOUT_MS`, `CATALOG_REFRESH_SECONDS`, `EMBEDDING_MODEL_ID`, `SIMILARITY_FLOOR`.
19
+ - **Marketing-style README** positioning the hosted endpoint (`https://cyanheads.caseyjhand.com/mcp`) as the product, with per-client install blocks and a category table for the fleet.
20
+
21
+ ## Changed
22
+
23
+ - **npm name** scoped to `@cyanheads/cyanheads-mcp-server`.
24
+ - **`mcpName`** added (`io.github.cyanheads/cyanheads-mcp-server`) for MCP Registry resolution.
25
+ - **`server.json`** declares all server-specific env vars on both stdio and HTTP package entries.
26
+
27
+ ## Removed
28
+
29
+ - **Echo scaffold** — five definition files and three tests carried over from `bunx init` removed once real definitions landed.
30
+ - **`manifest.json` / `.mcpbignore` / `.codex-plugin/` / `.claude-plugin/`** — the `.mcpb` bundle and plugin marketplace metadata assumed an npx-stdio install path that conflicts with the hosted-endpoint positioning. The corresponding `bundle` and `lint:packaging` scripts went with them.
31
+
32
+ Dependencies:
33
+
34
+ - `@cyanheads/mcp-ts-core` `^0.9.11`
35
+ - `@huggingface/transformers` `4.2.0`
36
+ - `zod` `^4.4.3`
37
+
38
+ 46 tests pass; `bun run devcheck` clean.
@@ -0,0 +1,127 @@
1
+ ---
2
+ # FORMAT REFERENCE — do not edit. Copy this file to
3
+ # `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.8.x/0.8.6.md`)
4
+ # to author a new release. Set that file's H1 to `# <version> — YYYY-MM-DD`
5
+ # with a concrete date.
6
+
7
+ # Required. One-line GitHub Release-style headline. 350 character cap.
8
+ # Default short and scannable. Don't pad, don't stitch unrelated changes with
9
+ # semicolons — pick the headline. Quotes required: unquoted YAML treats `: `
10
+ # inside the value as a key separator and fails GitHub's strict parser.
11
+ summary: ""
12
+
13
+ # Set `true` when consumers must change code to upgrade: API removals,
14
+ # signature changes, config renames, behavior changes that break existing
15
+ # usage. Flagged as `Breaking` in the rollup.
16
+ breaking: false
17
+
18
+ # Set `true` if this release contains any security fix. Pairs with the
19
+ # `## Security` section below. Flagged as `Security` in the rollup so
20
+ # users can triage upgrade urgency at a glance.
21
+ security: false
22
+
23
+ # Optional free-form notes for maintenance agents processing this release.
24
+ # Not rendered in CHANGELOG — consumed by agents running `maintenance` on
25
+ # downstream servers. Use for adoption instructions that don't fit the
26
+ # human-facing sections: new files to create, fields to populate, one-time
27
+ # migration steps. Omit the field entirely when there's nothing to say.
28
+ # agent-notes: |
29
+ # <instructions for downstream maintenance agents>
30
+ ---
31
+
32
+ # <version> — YYYY-MM-DD
33
+
34
+ <!--
35
+ AUTHORING GUIDE — applies to the new per-version file you create from this
36
+ template.
37
+
38
+ Audience: someone scanning release notes to decide what affects them. Lead
39
+ each bullet with the symbol or concept name in **bold** so they can skip
40
+ what's irrelevant and zoom in on what's not.
41
+
42
+ Tone: terse, fact-dense, not verbose. Default to one sentence per bullet —
43
+ name the symbol, state what changed, stop. Use a second sentence only when
44
+ it carries weight. If a bullet feels long, it is.
45
+
46
+ Cut: mechanism walkthroughs (those belong in JSDoc, AGENTS.md, or the
47
+ relevant skill), ceremonial framings ("This release introduces…",
48
+ backwards-compat paragraphs), file-by-file test enumerations, internal
49
+ implementation notes. Prefer code/symbol names over English re-explanations.
50
+
51
+ Narrative intro: skip by default. Add one short sentence only when the
52
+ release theme genuinely needs framing the bullets can't carry.
53
+
54
+ Sections: Keep a Changelog order — Added, Changed, Deprecated, Removed,
55
+ Fixed, Security. Include only sections with entries; delete the rest
56
+ (including the commented-out scaffolding below). Don't ship empty headers.
57
+
58
+ Include: every distinct fact a reader needs to adopt or audit the release —
59
+ new exports, signatures, lint rule IDs, env vars, breaking changes, version
60
+ bumps on shipped skills. Nothing more.
61
+
62
+ Links: link issues, PRs, docs, or skills where they help a reader jump to
63
+ context. Once per item per entry — don't re-link the same issue in summary,
64
+ narrative, and bullet. Skip links for inline symbol names; code spans speak
65
+ for themselves.
66
+
67
+ Issue/PR URLs: use full URLs. GitHub's bare `#NN` auto-link only resolves
68
+ inside its own UI, not in npm reads or local editors.
69
+
70
+ [#38](https://github.com/cyanheads/mcp-ts-core/issues/38) ← issue
71
+ [#42](https://github.com/cyanheads/mcp-ts-core/pull/42) ← PR
72
+
73
+ Verify numbers exist before linking (`gh issue view NN`, `gh pr view NN`).
74
+ Never speculate on a future number — `#42` for an upcoming PR silently
75
+ resolves to whatever real item already owns 42, and timeline previews pull
76
+ in that unrelated item's metadata.
77
+
78
+ TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
79
+ via `gh release create --notes-from-tag`. The tag is a derivative of this
80
+ changelog entry — a condensed, scannable version, not a copy. Format:
81
+
82
+ <theme — omit version number, GitHub prepends it>
83
+ ← blank line
84
+ <1-2 sentence context: what this release does>
85
+ ← blank line
86
+ Dependency bumps: ← section header
87
+ ← blank line
88
+ - `@cyanheads/mcp-ts-core` ^0.9.1 → ^0.9.6 ← bullet
89
+ ← blank line
90
+ Changed: ← only sections with entries
91
+ ← blank line
92
+ - `format()` output includes `query` in text mode
93
+ ← blank line
94
+ Added:
95
+ ← blank line
96
+ - `manifest.json` scaffolded for MCPB bundle support
97
+ - Install badges (Claude Desktop, Cursor, VS Code)
98
+ ← blank line
99
+ <N> tests pass; `bun run devcheck` clean. ← footer
100
+
101
+ Never a flat comma-separated string. Always structured markdown with
102
+ sections. The tag must scan well as a rendered GitHub Release page.
103
+ -->
104
+
105
+ ## Added
106
+
107
+ -
108
+
109
+ ## Changed
110
+
111
+ -
112
+
113
+ <!-- ## Deprecated
114
+
115
+ - -->
116
+
117
+ <!-- ## Removed
118
+
119
+ - -->
120
+
121
+ ## Fixed
122
+
123
+ -
124
+
125
+ <!-- ## Security
126
+
127
+ - -->
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview Server-specific configuration schema and lazy accessor.
3
+ * Separate from the framework's core config — never merge these two schemas.
4
+ * @module config/server-config
5
+ */
6
+ import { z } from '@cyanheads/mcp-ts-core';
7
+ declare const ServerConfigSchema: z.ZodObject<{
8
+ catalogUrl: z.ZodDefault<z.ZodString>;
9
+ catalogFetchTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
10
+ catalogRefreshSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
11
+ embeddingModelId: z.ZodDefault<z.ZodString>;
12
+ similarityFloor: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
13
+ }, z.core.$strip>;
14
+ export type ServerConfig = z.infer<typeof ServerConfigSchema>;
15
+ export declare function getServerConfig(): ServerConfig;
16
+ /** Reset cached config (test-only). */
17
+ export declare function resetServerConfig(): void;
18
+ export {};
19
+ //# sourceMappingURL=server-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,QAAA,MAAM,kBAAkB;;;;;;iBAgDtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,wBAAgB,eAAe,IAAI,YAAY,CAS9C;AAED,uCAAuC;AACvC,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @fileoverview Server-specific configuration schema and lazy accessor.
3
+ * Separate from the framework's core config — never merge these two schemas.
4
+ * @module config/server-config
5
+ */
6
+ import { z } from '@cyanheads/mcp-ts-core';
7
+ import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
8
+ const ServerConfigSchema = z.object({
9
+ /**
10
+ * Remote catalog JSON endpoint. Must return a JSON body matching the FleetPayload (v2) schema.
11
+ * Loaded at server startup via RemoteJsonCatalogProvider.
12
+ */
13
+ catalogUrl: z
14
+ .string()
15
+ .default('https://caseyjhand.com/fleet.json')
16
+ .describe('URL of the remote fleet.json catalog endpoint.'),
17
+ /**
18
+ * Timeout in milliseconds for the remote catalog fetch.
19
+ */
20
+ catalogFetchTimeoutMs: z.coerce
21
+ .number()
22
+ .default(10000)
23
+ .describe('HTTP timeout for remote catalog fetch in milliseconds.'),
24
+ /**
25
+ * Background poll interval. The service re-fetches fleet.json on this cadence
26
+ * and swaps in the new vector index if `generatedAt` changed.
27
+ * Set to 0 to disable background refresh.
28
+ */
29
+ catalogRefreshSeconds: z.coerce
30
+ .number()
31
+ .default(3600)
32
+ .describe('Seconds between background catalog re-fetches. 0 disables background refresh.'),
33
+ /**
34
+ * Embedding model identifier. Must match `embeddingModel` declared in fleet.json,
35
+ * or the server refuses to load (since vectors live in the same space as the
36
+ * model that produced them).
37
+ */
38
+ embeddingModelId: z
39
+ .string()
40
+ .default('Snowflake/snowflake-arctic-embed-m-v1.5')
41
+ .describe('Hugging Face model id used for query embedding at search time. Must match fleet.json.embeddingModel.'),
42
+ /**
43
+ * Minimum cosine similarity for a result to surface in cyanheads_search output.
44
+ * Tunable post-launch based on observed query patterns.
45
+ */
46
+ similarityFloor: z.coerce
47
+ .number()
48
+ .default(0.3)
49
+ .describe('Minimum cosine similarity in [0, 1] for a match to appear in search results.'),
50
+ });
51
+ let _config;
52
+ export function getServerConfig() {
53
+ _config ??= parseEnvConfig(ServerConfigSchema, {
54
+ catalogUrl: 'CATALOG_URL',
55
+ catalogFetchTimeoutMs: 'CATALOG_FETCH_TIMEOUT_MS',
56
+ catalogRefreshSeconds: 'CATALOG_REFRESH_SECONDS',
57
+ embeddingModelId: 'EMBEDDING_MODEL_ID',
58
+ similarityFloor: 'SIMILARITY_FLOOR',
59
+ });
60
+ return _config;
61
+ }
62
+ /** Reset cached config (test-only). */
63
+ export function resetServerConfig() {
64
+ _config = undefined;
65
+ }
66
+ //# sourceMappingURL=server-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC;;;OAGG;IACH,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,OAAO,CAAC,mCAAmC,CAAC;SAC5C,QAAQ,CAAC,gDAAgD,CAAC;IAE7D;;OAEG;IACH,qBAAqB,EAAE,CAAC,CAAC,MAAM;SAC5B,MAAM,EAAE;SACR,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,wDAAwD,CAAC;IAErE;;;;OAIG;IACH,qBAAqB,EAAE,CAAC,CAAC,MAAM;SAC5B,MAAM,EAAE;SACR,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,+EAA+E,CAAC;IAE5F;;;;OAIG;IACH,gBAAgB,EAAE,CAAC;SAChB,MAAM,EAAE;SACR,OAAO,CAAC,yCAAyC,CAAC;SAClD,QAAQ,CACP,sGAAsG,CACvG;IAEH;;;OAGG;IACH,eAAe,EAAE,CAAC,CAAC,MAAM;SACtB,MAAM,EAAE;SACR,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,8EAA8E,CAAC;CAC5F,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,cAAc,CAAC,kBAAkB,EAAE;QAC7C,UAAU,EAAE,aAAa;QACzB,qBAAqB,EAAE,0BAA0B;QACjD,qBAAqB,EAAE,yBAAyB;QAChD,gBAAgB,EAAE,oBAAoB;QACtC,eAAe,EAAE,kBAAkB;KACpC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,iBAAiB;IAC/B,OAAO,GAAG,SAAS,CAAC;AACtB,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview cyanheads-mcp-server entry point — fleet discovery and passthrough gateway.
4
+ * @module index
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview cyanheads-mcp-server entry point — fleet discovery and passthrough gateway.
4
+ * @module index
5
+ */
6
+ import { createApp } from '@cyanheads/mcp-ts-core';
7
+ import { getServerConfig } from './config/server-config.js';
8
+ import { describeTool } from './mcp-server/tools/definitions/describe.tool.js';
9
+ import { searchTool } from './mcp-server/tools/definitions/search.tool.js';
10
+ import { getCatalogService, initCatalogService } from './services/catalog/catalog-service.js';
11
+ await createApp({
12
+ name: 'cyanheads-mcp-server',
13
+ tools: [searchTool, describeTool],
14
+ resources: [],
15
+ prompts: [],
16
+ instructions: 'This server is the discovery front door to the cyanheads MCP fleet. ' +
17
+ 'Use cyanheads_search to find tools or servers by describing what you want to do. ' +
18
+ 'Use cyanheads_describe to get full schemas and per-client install snippets for any result. ' +
19
+ 'Scope "tools" (default) finds individual tools; scope "servers" finds which server owns a workflow.',
20
+ async setup() {
21
+ const config = getServerConfig();
22
+ initCatalogService(config);
23
+ await getCatalogService().initialize();
24
+ },
25
+ });
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,iDAAiD,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE9F,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,sBAAsB;IAC5B,KAAK,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC;IACjC,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,sEAAsE;QACtE,mFAAmF;QACnF,6FAA6F;QAC7F,qGAAqG;IAEvG,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QACjC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,iBAAiB,EAAE,CAAC,UAAU,EAAE,CAAC;IACzC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @fileoverview cyanheads_describe — return connection URL and per-client install snippets
3
+ * for a named tool or server.
4
+ * Uses z.discriminatedUnion on 'kind' so the linter walks each branch independently
5
+ * and format() can dispatch cleanly.
6
+ * @module mcp-server/tools/definitions/describe
7
+ */
8
+ import { z } from '@cyanheads/mcp-ts-core';
9
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
10
+ export declare const describeTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
11
+ name: z.ZodString;
12
+ kind: z.ZodOptional<z.ZodEnum<{
13
+ server: "server";
14
+ tool: "tool";
15
+ }>>;
16
+ client: z.ZodOptional<z.ZodEnum<{
17
+ "claude-desktop": "claude-desktop";
18
+ "claude-code": "claude-code";
19
+ cursor: "cursor";
20
+ cline: "cline";
21
+ }>>;
22
+ }, z.core.$strip>, z.ZodObject<{
23
+ result: z.ZodDiscriminatedUnion<[z.ZodObject<{
24
+ kind: z.ZodLiteral<"tool">;
25
+ name: z.ZodString;
26
+ description: z.ZodString;
27
+ server: z.ZodString;
28
+ }, z.core.$strip>, z.ZodObject<{
29
+ kind: z.ZodLiteral<"server">;
30
+ name: z.ZodString;
31
+ displayName: z.ZodString;
32
+ description: z.ZodString;
33
+ version: z.ZodString;
34
+ npm: z.ZodString;
35
+ github: z.ZodString;
36
+ endpoint: z.ZodString;
37
+ auth: z.ZodString;
38
+ toolCount: z.ZodNumber;
39
+ installSnippets: z.ZodArray<z.ZodObject<{
40
+ client: z.ZodEnum<{
41
+ "claude-desktop": "claude-desktop";
42
+ "claude-code": "claude-code";
43
+ cursor: "cursor";
44
+ cline: "cline";
45
+ }>;
46
+ label: z.ZodString;
47
+ payload: z.ZodString;
48
+ }, z.core.$strip>>;
49
+ }, z.core.$strip>], "kind">;
50
+ }, z.core.$strip>, readonly [{
51
+ readonly reason: "not_found";
52
+ readonly code: JsonRpcErrorCode.NotFound;
53
+ readonly when: "No tool or server with the given name exists in the catalog.";
54
+ readonly recovery: "Use cyanheads_search to find the correct name, then call cyanheads_describe again.";
55
+ }, {
56
+ readonly reason: "ambiguous_kind";
57
+ readonly code: JsonRpcErrorCode.InvalidParams;
58
+ readonly when: "Name matches both a tool and a server (collision in catalog).";
59
+ readonly recovery: "Set the kind parameter to \"tool\" or \"server\" to disambiguate.";
60
+ }, {
61
+ readonly reason: "catalog_empty";
62
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
63
+ readonly when: "Catalog has not finished loading.";
64
+ readonly recovery: "Retry in a few seconds; the catalog is still loading.";
65
+ readonly retryable: true;
66
+ }]>;
67
+ //# sourceMappingURL=describe.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/describe.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8MvB,CAAC"}