@ceed/docs-mcp 1.0.0-next.2 → 1.0.0

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/dist/server.js CHANGED
@@ -1,14 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { pathToFileURL } from 'node:url';
3
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
4
  import { z } from 'zod';
6
5
  import { createRagSearcher } from './rag/search.js';
7
6
  import { DOCS_MCP_VERSION } from './version.js';
8
- const pingSchema = z.object({
9
- message: z.string().optional(),
10
- });
11
- const pingInputSchema = pingSchema.shape;
12
7
  const searchSchema = z.object({
13
8
  packageName: z.enum(['@ceed/ads', '@ceed/cds']).describe('Package to search (@ceed/ads or @ceed/cds).'),
14
9
  query: z.string().min(1, 'Query text is required.'),
@@ -36,21 +31,6 @@ export const createDocsMcpServer = () => {
36
31
  version: DOCS_MCP_VERSION,
37
32
  });
38
33
  const ragSearcher = createRagSearcher();
39
- server.registerTool('ping', {
40
- title: 'Ping',
41
- description: 'Return a simple response to verify the MCP server is healthy.',
42
- inputSchema: pingInputSchema,
43
- }, async (rawInput) => {
44
- const { message } = pingSchema.parse(rawInput);
45
- return {
46
- content: [
47
- {
48
- type: 'text',
49
- text: message ?? 'pong',
50
- },
51
- ],
52
- };
53
- });
54
34
  server.registerTool('search', {
55
35
  title: 'Search documentation',
56
36
  description: 'Look up documentation chunks that best match the given query.',
@@ -124,17 +104,8 @@ export const startDocsMcpServer = async () => {
124
104
  const transport = new StdioServerTransport();
125
105
  await server.connect(transport);
126
106
  };
127
- const invokedFromCli = () => {
128
- const entry = process.argv[1];
129
- if (!entry) {
130
- return false;
131
- }
132
- return import.meta.url === pathToFileURL(entry).href;
133
- };
134
- if (invokedFromCli()) {
135
- startDocsMcpServer().catch((error) => {
136
- console.error('Failed to start @ceed/docs-mcp server:', error);
137
- process.exitCode = 1;
138
- });
139
- }
107
+ startDocsMcpServer().catch((error) => {
108
+ console.error('Failed to start @ceed/docs-mcp server:', error);
109
+ process.exitCode = 1;
110
+ });
140
111
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { pathToFileURL } from 'node:url';\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\n\nimport { createRagSearcher } from './rag/search.js';\nimport type { SearchResult } from './rag/types.js';\nimport { DOCS_MCP_VERSION } from './version.js';\n\nconst pingSchema = z.object({\n message: z.string().optional(),\n});\n\nconst pingInputSchema = pingSchema.shape;\n\nconst searchSchema = z.object({\n packageName: z.enum(['@ceed/ads', '@ceed/cds']).describe('Package to search (@ceed/ads or @ceed/cds).'),\n query: z.string().min(1, 'Query text is required.'),\n topK: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Number of matches to return per page (default: 5, max: 100).'),\n page: z.number().int().min(1).optional().describe('Results page to fetch (default: 1).'),\n});\n\nconst searchInputSchema = searchSchema.shape;\n\nconst formatSearchResult = (rank: number, result: SearchResult) => {\n const lines = [`#${rank + 1} (score: ${result.score.toFixed(3)})`, `source: ${result.metadata.source}`];\n\n if (result.metadata.heading) {\n lines.splice(1, 0, `heading: ${result.metadata.heading}`);\n }\n\n lines.push('', result.text.trim());\n\n return lines.join('\\n');\n};\n\nexport const createDocsMcpServer = () => {\n const server = new McpServer({\n name: '@ceed/docs-mcp',\n version: DOCS_MCP_VERSION,\n });\n\n const ragSearcher = createRagSearcher();\n\n server.registerTool(\n 'ping',\n {\n title: 'Ping',\n description: 'Return a simple response to verify the MCP server is healthy.',\n inputSchema: pingInputSchema,\n },\n async (rawInput) => {\n const { message } = pingSchema.parse(rawInput);\n\n return {\n content: [\n {\n type: 'text',\n text: message ?? 'pong',\n },\n ],\n };\n },\n );\n\n server.registerTool(\n 'search',\n {\n title: 'Search documentation',\n description: 'Look up documentation chunks that best match the given query.',\n inputSchema: searchInputSchema,\n },\n async (rawInput) => {\n const { packageName, query, topK, page } = searchSchema.parse(rawInput);\n const packageKey = packageName.split('/').pop() ?? undefined;\n\n try {\n const pageData = await ragSearcher.search(query, topK, packageKey, page);\n const { results, total, page: currentPage, pageSize, hasMore } = pageData;\n\n if (results.length === 0) {\n if (total === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No matching documentation found.',\n },\n ],\n };\n }\n\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n return {\n content: [\n {\n type: 'text',\n text: `No results on page ${currentPage}. Try a page value between 1 and ${totalPages}.`,\n },\n ],\n };\n }\n\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const startIndex = (currentPage - 1) * pageSize;\n const headerLines = [\n `Total matches: ${total}`,\n `Page ${currentPage} of ${totalPages} (page size ${pageSize})`,\n ];\n\n if (hasMore) {\n headerLines.push('More results available. Increase the page value to continue.');\n }\n\n const formatted = results\n .map((result, index) => formatSearchResult(startIndex + index, result))\n .join('\\n\\n---\\n\\n');\n\n const text = `${headerLines.join('\\n')}\\n\\n${formatted}`;\n\n return {\n content: [\n {\n type: 'text',\n text,\n },\n ],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown search error';\n\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Failed to search documentation index: ${message}`,\n },\n ],\n };\n }\n },\n );\n\n return server;\n};\n\nexport const startDocsMcpServer = async () => {\n const server = createDocsMcpServer();\n const transport = new StdioServerTransport();\n\n await server.connect(transport);\n};\n\nconst invokedFromCli = () => {\n const entry = process.argv[1];\n\n if (!entry) {\n return false;\n }\n\n return import.meta.url === pathToFileURL(entry).href;\n};\n\nif (invokedFromCli()) {\n startDocsMcpServer().catch((error) => {\n console.error('Failed to start @ceed/docs-mcp server:', error);\n process.exitCode = 1;\n });\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\n\nimport { createRagSearcher } from './rag/search.js';\nimport type { SearchResult } from './rag/types.js';\nimport { DOCS_MCP_VERSION } from './version.js';\n\nconst searchSchema = z.object({\n packageName: z.enum(['@ceed/ads', '@ceed/cds']).describe('Package to search (@ceed/ads or @ceed/cds).'),\n query: z.string().min(1, 'Query text is required.'),\n topK: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Number of matches to return per page (default: 5, max: 100).'),\n page: z.number().int().min(1).optional().describe('Results page to fetch (default: 1).'),\n});\n\nconst searchInputSchema = searchSchema.shape;\n\nconst formatSearchResult = (rank: number, result: SearchResult) => {\n const lines = [`#${rank + 1} (score: ${result.score.toFixed(3)})`, `source: ${result.metadata.source}`];\n\n if (result.metadata.heading) {\n lines.splice(1, 0, `heading: ${result.metadata.heading}`);\n }\n\n lines.push('', result.text.trim());\n\n return lines.join('\\n');\n};\n\nexport const createDocsMcpServer = () => {\n const server = new McpServer({\n name: '@ceed/docs-mcp',\n version: DOCS_MCP_VERSION,\n });\n\n const ragSearcher = createRagSearcher();\n\n server.registerTool(\n 'search',\n {\n title: 'Search documentation',\n description: 'Look up documentation chunks that best match the given query.',\n inputSchema: searchInputSchema,\n },\n async (rawInput) => {\n const { packageName, query, topK, page } = searchSchema.parse(rawInput);\n const packageKey = packageName.split('/').pop() ?? undefined;\n\n try {\n const pageData = await ragSearcher.search(query, topK, packageKey, page);\n const { results, total, page: currentPage, pageSize, hasMore } = pageData;\n\n if (results.length === 0) {\n if (total === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No matching documentation found.',\n },\n ],\n };\n }\n\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n return {\n content: [\n {\n type: 'text',\n text: `No results on page ${currentPage}. Try a page value between 1 and ${totalPages}.`,\n },\n ],\n };\n }\n\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const startIndex = (currentPage - 1) * pageSize;\n const headerLines = [\n `Total matches: ${total}`,\n `Page ${currentPage} of ${totalPages} (page size ${pageSize})`,\n ];\n\n if (hasMore) {\n headerLines.push('More results available. Increase the page value to continue.');\n }\n\n const formatted = results\n .map((result, index) => formatSearchResult(startIndex + index, result))\n .join('\\n\\n---\\n\\n');\n\n const text = `${headerLines.join('\\n')}\\n\\n${formatted}`;\n\n return {\n content: [\n {\n type: 'text',\n text,\n },\n ],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown search error';\n\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Failed to search documentation index: ${message}`,\n },\n ],\n };\n }\n },\n );\n\n return server;\n};\n\nexport const startDocsMcpServer = async () => {\n const server = createDocsMcpServer();\n const transport = new StdioServerTransport();\n\n await server.connect(transport);\n};\n\nstartDocsMcpServer().catch((error) => {\n console.error('Failed to start @ceed/docs-mcp server:', error);\n process.exitCode = 1;\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceed/docs-mcp",
3
- "version": "1.0.0-next.2",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -53,6 +53,5 @@
53
53
  "type": "git",
54
54
  "url": "git+ssh://git@github.com/Ecube-Labs/hds.git"
55
55
  },
56
- "packageManager": "yarn@4.1.0",
57
- "stableVersion": "0.1.0"
56
+ "packageManager": "yarn@4.1.0"
58
57
  }
package/rag-index.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "model": "Xenova/all-MiniLM-L6-v2",
3
3
  "dimension": 384,
4
- "createdAt": "2025-09-18T08:17:27.100Z",
4
+ "createdAt": "2025-09-18T09:25:59.572Z",
5
5
  "chunks": [
6
6
  {
7
7
  "id": "ads/Overview.md:chunk-0000",