@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
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @fileoverview Shared types for the catalog service — CatalogRecord, CatalogTool,
3
+ * FleetPayload (v2 with baked embeddings), InstallSnippet, ClientId,
4
+ * and the service interface.
5
+ * @module services/catalog/types
6
+ */
7
+ /** Supported MCP client identifiers for install snippets. */
8
+ export type ClientId = 'claude-desktop' | 'claude-code' | 'cursor' | 'cline';
9
+ /** Catalog category for a fleet server. */
10
+ export type CatalogCategory = 'research' | 'government' | 'public-data' | 'utility';
11
+ /** Single tool entry inside a CatalogRecord. */
12
+ export interface CatalogTool {
13
+ /** Human-readable description. */
14
+ description: string;
15
+ /**
16
+ * L2-normalized, Matryoshka-truncated embedding vector.
17
+ * Length matches FleetPayload.embeddingDims.
18
+ */
19
+ embedding: number[];
20
+ /** Fully-qualified name: snake_case (e.g. "earthquake_search"). */
21
+ name: string;
22
+ }
23
+ /** Per-client install snippet. */
24
+ export interface InstallSnippet {
25
+ /** MCP client identifier. */
26
+ client: ClientId;
27
+ /** Human-readable label for the install method. */
28
+ label: string;
29
+ /**
30
+ * The install payload. Shape varies by client:
31
+ * - claude-desktop: JSON fragment for mcpServers block
32
+ * - claude-code: CLI command string
33
+ * - cursor: JSON fragment for .cursor/mcp.json mcpServers block
34
+ * - cline: JSON fragment for Cline's MCP settings
35
+ */
36
+ payload: string;
37
+ }
38
+ /** One fleet server record, mirroring the fleet.json servers[] entry. */
39
+ export interface CatalogRecord {
40
+ /**
41
+ * Auth requirement for the hosted deployment.
42
+ * Open string for forward-compatibility — currently always "none".
43
+ */
44
+ auth: string;
45
+ /** Thematic grouping for filter facets. */
46
+ category: CatalogCategory;
47
+ /** One-line description of what this server does. */
48
+ description: string;
49
+ /** Human label (e.g. "arXiv"). */
50
+ displayName: string;
51
+ /**
52
+ * L2-normalized, Matryoshka-truncated embedding vector of
53
+ * `${displayName}\n${description}`. Length matches FleetPayload.embeddingDims.
54
+ */
55
+ embedding: number[];
56
+ /** HTTP SSE endpoint — always present; the catalog covers hosted servers only. */
57
+ endpoint: string;
58
+ /** GitHub repository URL. */
59
+ github: string;
60
+ /** Package name without scope (e.g. "arxiv-mcp-server"). */
61
+ name: string;
62
+ /** npm package name (scoped, e.g. "@cyanheads/arxiv-mcp-server"). */
63
+ npm: string;
64
+ /** Tool entries for this server, each with its own embedding. */
65
+ tools: CatalogTool[];
66
+ /** Published version captured at fleet-generation time (e.g. "1.2.7"). */
67
+ version: string;
68
+ }
69
+ /** Top-level payload returned from the remote fleet.json URL. */
70
+ export interface FleetPayload {
71
+ /** Dimensionality of every embedding in the payload. */
72
+ embeddingDims: number;
73
+ /** Hugging Face model id used to produce the embeddings. */
74
+ embeddingModel: string;
75
+ /**
76
+ * Prefix that must be prepended to query text before embedding at runtime.
77
+ * Documents are embedded without this prefix; only queries get it.
78
+ */
79
+ embeddingQueryPrefix: string;
80
+ /** ISO 8601 UTC timestamp when the payload was generated. */
81
+ generatedAt: string;
82
+ /** Fleet server records. */
83
+ servers: CatalogRecord[];
84
+ /** Schema version. Currently "2". */
85
+ version: '2';
86
+ }
87
+ /** Result row returned from catalog searches. */
88
+ export interface CatalogSearchResult {
89
+ /** Brief description for display. */
90
+ brief: string;
91
+ /** Catalog category for the owning server. */
92
+ category: CatalogCategory;
93
+ /** Tool or server name, depending on scope. */
94
+ name: string;
95
+ /** Cosine similarity in [0, 1]. Higher is better. */
96
+ score: number;
97
+ /** Server that owns this result. */
98
+ server: string;
99
+ }
100
+ /** Service interface. */
101
+ export interface ICatalogService {
102
+ /** Look up a server by exact name. Returns null if not found. */
103
+ getServer(name: string): CatalogRecord | null;
104
+ /** Look up a tool by exact name. Returns null if not found. */
105
+ getTool(name: string): (CatalogTool & {
106
+ serverRecord: CatalogRecord;
107
+ }) | null;
108
+ /**
109
+ * Fetch fleet.json, validate, build the vector index, and load the embedding model.
110
+ * Starts the background refresh timer if configured.
111
+ */
112
+ initialize(): Promise<void>;
113
+ /** List all category strings present in the catalog. */
114
+ listCategories(): CatalogCategory[];
115
+ /**
116
+ * Semantic search. Embeds the query, computes cosine similarity against
117
+ * every catalog entry within the requested scope, filters by category and
118
+ * by the configured similarity floor, sorts descending, and returns the
119
+ * top `limit` (or every match when `limit` is omitted).
120
+ */
121
+ search(params: {
122
+ query: string;
123
+ scope: 'tools' | 'servers';
124
+ category?: CatalogCategory;
125
+ limit?: number;
126
+ }): Promise<CatalogSearchResult[]>;
127
+ /** Catalog summary for diagnostics. */
128
+ stats(): {
129
+ toolCount: number;
130
+ serverCount: number;
131
+ initializedAt: string;
132
+ embeddingModel: string;
133
+ };
134
+ }
135
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/catalog/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Shared types for the catalog service — CatalogRecord, CatalogTool,
3
+ * FleetPayload (v2 with baked embeddings), InstallSnippet, ClientId,
4
+ * and the service interface.
5
+ * @module services/catalog/types
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/catalog/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "@cyanheads/cyanheads-mcp-server",
3
+ "mcpName": "io.github.cyanheads/cyanheads-mcp-server",
4
+ "version": "0.1.1",
5
+ "description": "Fleet discovery server for the cyanheads MCP ecosystem — semantic search for tools and install snippets.",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "cyanheads-mcp-server": "dist/index.js"
11
+ },
12
+ "files": [
13
+ "changelog/",
14
+ "dist/",
15
+ "README.md",
16
+ "LICENSE",
17
+ "CLAUDE.md",
18
+ "AGENTS.md",
19
+ "Dockerfile",
20
+ "server.json"
21
+ ],
22
+ "author": "cyanheads <casey@caseyjhand.com> (https://github.com/cyanheads/cyanheads-mcp-server#readme)",
23
+ "homepage": "https://github.com/cyanheads/cyanheads-mcp-server#readme",
24
+ "bugs": {
25
+ "url": "https://github.com/cyanheads/cyanheads-mcp-server/issues"
26
+ },
27
+ "scripts": {
28
+ "build": "tsx scripts/build.ts",
29
+ "rebuild": "tsx scripts/clean.ts && tsx scripts/build.ts",
30
+ "clean": "tsx scripts/clean.ts",
31
+ "devcheck": "tsx scripts/devcheck.ts",
32
+ "audit:refresh": "rm -f bun.lock && bun install && bun audit",
33
+ "tree": "tsx scripts/tree.ts",
34
+ "list-skills": "tsx scripts/list-skills.ts",
35
+ "format": "biome check --write --unsafe .",
36
+ "lint:mcp": "tsx scripts/lint-mcp.ts",
37
+ "changelog:build": "tsx scripts/build-changelog.ts",
38
+ "changelog:check": "tsx scripts/build-changelog.ts --check",
39
+ "test": "vitest run",
40
+ "start": "node dist/index.js",
41
+ "start:stdio": "MCP_TRANSPORT_TYPE=stdio node dist/index.js",
42
+ "start:http": "MCP_TRANSPORT_TYPE=http node dist/index.js"
43
+ },
44
+ "keywords": [
45
+ "mcp",
46
+ "mcp-server",
47
+ "model-context-protocol",
48
+ "mcp-discovery",
49
+ "mcp-fleet",
50
+ "semantic-search",
51
+ "cyanheads",
52
+ "typescript",
53
+ "bun"
54
+ ],
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/cyanheads/cyanheads-mcp-server.git"
58
+ },
59
+ "license": "Apache-2.0",
60
+ "engines": {
61
+ "bun": ">=1.3.0",
62
+ "node": ">=24.0.0"
63
+ },
64
+ "publishConfig": {
65
+ "access": "public"
66
+ },
67
+ "dependencies": {
68
+ "@cyanheads/mcp-ts-core": "^0.9.11",
69
+ "@huggingface/transformers": "4.2.0",
70
+ "pino-pretty": "^13.1.3",
71
+ "zod": "^4.4.3"
72
+ },
73
+ "devDependencies": {
74
+ "@biomejs/biome": "^2.4.7",
75
+ "@types/node": "^25.6.0",
76
+ "depcheck": "^1.4.7",
77
+ "ignore": "^7.0.5",
78
+ "tsc-alias": "^1.8.16",
79
+ "tsx": "^4.19.0",
80
+ "typescript": "^5.9.3",
81
+ "vitest": "^4.1.0"
82
+ }
83
+ }
package/server.json ADDED
@@ -0,0 +1,141 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.cyanheads/cyanheads-mcp-server",
4
+ "description": "Fleet discovery server for the cyanheads MCP ecosystem — semantic search for tools and install snippets.",
5
+ "repository": {
6
+ "url": "https://github.com/cyanheads/cyanheads-mcp-server",
7
+ "source": "github"
8
+ },
9
+ "version": "0.1.1",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "registryBaseUrl": "https://registry.npmjs.org",
14
+ "identifier": "@cyanheads/cyanheads-mcp-server",
15
+ "runtimeHint": "node",
16
+ "version": "0.1.1",
17
+ "packageArguments": [
18
+ { "type": "positional", "value": "run" },
19
+ { "type": "positional", "value": "start:stdio" }
20
+ ],
21
+ "environmentVariables": [
22
+ {
23
+ "name": "MCP_LOG_LEVEL",
24
+ "description": "Minimum log level: debug, info, notice, warning, error.",
25
+ "format": "string",
26
+ "isRequired": false,
27
+ "default": "info"
28
+ },
29
+ {
30
+ "name": "CATALOG_URL",
31
+ "description": "Remote fleet.json endpoint (schema v2 with baked embeddings).",
32
+ "format": "string",
33
+ "isRequired": false,
34
+ "default": "https://caseyjhand.com/fleet.json"
35
+ },
36
+ {
37
+ "name": "CATALOG_REFRESH_SECONDS",
38
+ "description": "Background poll interval for fleet.json refresh. 0 disables.",
39
+ "format": "string",
40
+ "isRequired": false,
41
+ "default": "3600"
42
+ },
43
+ {
44
+ "name": "EMBEDDING_MODEL_ID",
45
+ "description": "Hugging Face model id for query embedding. Must match fleet.json.embeddingModel.",
46
+ "format": "string",
47
+ "isRequired": false,
48
+ "default": "Snowflake/snowflake-arctic-embed-m-v1.5"
49
+ },
50
+ {
51
+ "name": "SIMILARITY_FLOOR",
52
+ "description": "Cosine similarity cutoff for cyanheads_search results (0-1).",
53
+ "format": "string",
54
+ "isRequired": false,
55
+ "default": "0.3"
56
+ }
57
+ ],
58
+ "transport": { "type": "stdio" }
59
+ },
60
+ {
61
+ "registryType": "npm",
62
+ "registryBaseUrl": "https://registry.npmjs.org",
63
+ "identifier": "@cyanheads/cyanheads-mcp-server",
64
+ "runtimeHint": "node",
65
+ "version": "0.1.1",
66
+ "packageArguments": [
67
+ { "type": "positional", "value": "run" },
68
+ { "type": "positional", "value": "start:http" }
69
+ ],
70
+ "environmentVariables": [
71
+ {
72
+ "name": "MCP_HTTP_HOST",
73
+ "description": "Hostname for the HTTP server.",
74
+ "format": "string",
75
+ "isRequired": false,
76
+ "default": "127.0.0.1"
77
+ },
78
+ {
79
+ "name": "MCP_HTTP_PORT",
80
+ "description": "Port to run the HTTP server on.",
81
+ "format": "string",
82
+ "isRequired": false,
83
+ "default": "3010"
84
+ },
85
+ {
86
+ "name": "MCP_HTTP_ENDPOINT_PATH",
87
+ "description": "Endpoint path for the MCP server.",
88
+ "format": "string",
89
+ "isRequired": false,
90
+ "default": "/mcp"
91
+ },
92
+ {
93
+ "name": "MCP_AUTH_MODE",
94
+ "description": "Authentication mode: none, jwt, or oauth.",
95
+ "format": "string",
96
+ "isRequired": false,
97
+ "default": "none"
98
+ },
99
+ {
100
+ "name": "MCP_LOG_LEVEL",
101
+ "description": "Minimum log level: debug, info, notice, warning, error.",
102
+ "format": "string",
103
+ "isRequired": false,
104
+ "default": "info"
105
+ },
106
+ {
107
+ "name": "CATALOG_URL",
108
+ "description": "Remote fleet.json endpoint (schema v2 with baked embeddings).",
109
+ "format": "string",
110
+ "isRequired": false,
111
+ "default": "https://caseyjhand.com/fleet.json"
112
+ },
113
+ {
114
+ "name": "CATALOG_REFRESH_SECONDS",
115
+ "description": "Background poll interval for fleet.json refresh. 0 disables.",
116
+ "format": "string",
117
+ "isRequired": false,
118
+ "default": "3600"
119
+ },
120
+ {
121
+ "name": "EMBEDDING_MODEL_ID",
122
+ "description": "Hugging Face model id for query embedding. Must match fleet.json.embeddingModel.",
123
+ "format": "string",
124
+ "isRequired": false,
125
+ "default": "Snowflake/snowflake-arctic-embed-m-v1.5"
126
+ },
127
+ {
128
+ "name": "SIMILARITY_FLOOR",
129
+ "description": "Cosine similarity cutoff for cyanheads_search results (0-1).",
130
+ "format": "string",
131
+ "isRequired": false,
132
+ "default": "0.3"
133
+ }
134
+ ],
135
+ "transport": {
136
+ "type": "streamable-http",
137
+ "url": "http://localhost:3010/mcp"
138
+ }
139
+ }
140
+ ]
141
+ }