docs-hub-mcp 1.0.14

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 (96) hide show
  1. package/README.md +171 -0
  2. package/dhm.js +2 -0
  3. package/dist/cli/commands.d.ts +11 -0
  4. package/dist/cli/commands.d.ts.map +1 -0
  5. package/dist/cli/commands.js +112 -0
  6. package/dist/cli/commands.js.map +1 -0
  7. package/dist/cli/config.d.ts +120 -0
  8. package/dist/cli/config.d.ts.map +1 -0
  9. package/dist/cli/config.js +76 -0
  10. package/dist/cli/config.js.map +1 -0
  11. package/dist/index/builder.d.ts +25 -0
  12. package/dist/index/builder.d.ts.map +1 -0
  13. package/dist/index/builder.js +40 -0
  14. package/dist/index/builder.js.map +1 -0
  15. package/dist/index/parser.d.ts +20 -0
  16. package/dist/index/parser.d.ts.map +1 -0
  17. package/dist/index/parser.js +162 -0
  18. package/dist/index/parser.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +92 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/mcp/server.d.ts +3 -0
  24. package/dist/mcp/server.d.ts.map +1 -0
  25. package/dist/mcp/server.js +97 -0
  26. package/dist/mcp/server.js.map +1 -0
  27. package/dist/mcp/tools.d.ts +57 -0
  28. package/dist/mcp/tools.d.ts.map +1 -0
  29. package/dist/mcp/tools.js +70 -0
  30. package/dist/mcp/tools.js.map +1 -0
  31. package/dist/search/cache.d.ts +12 -0
  32. package/dist/search/cache.d.ts.map +1 -0
  33. package/dist/search/cache.js +36 -0
  34. package/dist/search/cache.js.map +1 -0
  35. package/dist/search/exact.d.ts +3 -0
  36. package/dist/search/exact.d.ts.map +1 -0
  37. package/dist/search/exact.js +56 -0
  38. package/dist/search/exact.js.map +1 -0
  39. package/dist/search/graph.d.ts +6 -0
  40. package/dist/search/graph.d.ts.map +1 -0
  41. package/dist/search/graph.js +137 -0
  42. package/dist/search/graph.js.map +1 -0
  43. package/dist/search/pipeline.d.ts +18 -0
  44. package/dist/search/pipeline.d.ts.map +1 -0
  45. package/dist/search/pipeline.js +99 -0
  46. package/dist/search/pipeline.js.map +1 -0
  47. package/dist/search/semantic.d.ts +4 -0
  48. package/dist/search/semantic.d.ts.map +1 -0
  49. package/dist/search/semantic.js +120 -0
  50. package/dist/search/semantic.js.map +1 -0
  51. package/dist/sync/base.d.ts +21 -0
  52. package/dist/sync/base.d.ts.map +1 -0
  53. package/dist/sync/base.js +8 -0
  54. package/dist/sync/base.js.map +1 -0
  55. package/dist/sync/confluence.d.ts +3 -0
  56. package/dist/sync/confluence.d.ts.map +1 -0
  57. package/dist/sync/confluence.js +111 -0
  58. package/dist/sync/confluence.js.map +1 -0
  59. package/dist/sync/git-wiki.d.ts +3 -0
  60. package/dist/sync/git-wiki.d.ts.map +1 -0
  61. package/dist/sync/git-wiki.js +103 -0
  62. package/dist/sync/git-wiki.js.map +1 -0
  63. package/dist/sync/google-docs.d.ts +3 -0
  64. package/dist/sync/google-docs.d.ts.map +1 -0
  65. package/dist/sync/google-docs.js +87 -0
  66. package/dist/sync/google-docs.js.map +1 -0
  67. package/dist/sync/notion.d.ts +3 -0
  68. package/dist/sync/notion.d.ts.map +1 -0
  69. package/dist/sync/notion.js +126 -0
  70. package/dist/sync/notion.js.map +1 -0
  71. package/dist/sync/slack.d.ts +3 -0
  72. package/dist/sync/slack.d.ts.map +1 -0
  73. package/dist/sync/slack.js +92 -0
  74. package/dist/sync/slack.js.map +1 -0
  75. package/dist/sync/state.d.ts +25 -0
  76. package/dist/sync/state.d.ts.map +1 -0
  77. package/dist/sync/state.js +80 -0
  78. package/dist/sync/state.js.map +1 -0
  79. package/dist/utils/fs.d.ts +8 -0
  80. package/dist/utils/fs.d.ts.map +1 -0
  81. package/dist/utils/fs.js +43 -0
  82. package/dist/utils/fs.js.map +1 -0
  83. package/dist/utils/git.d.ts +7 -0
  84. package/dist/utils/git.d.ts.map +1 -0
  85. package/dist/utils/git.js +39 -0
  86. package/dist/utils/git.js.map +1 -0
  87. package/dist/utils/logger.d.ts +16 -0
  88. package/dist/utils/logger.d.ts.map +1 -0
  89. package/dist/utils/logger.js +21 -0
  90. package/dist/utils/logger.js.map +1 -0
  91. package/dist/web/server.d.ts +2 -0
  92. package/dist/web/server.d.ts.map +1 -0
  93. package/dist/web/server.js +82 -0
  94. package/dist/web/server.js.map +1 -0
  95. package/dist/web/ui.html +210 -0
  96. package/package.json +38 -0
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # doc-hub-mcp
2
+
3
+ **MCP server for documentation hub** — sync knowledge from multiple sources into version-controlled `.md` files with 3-tier search, designed for AI agents.
4
+
5
+ ## Overview
6
+
7
+ AI agents need fast, reliable access to team documentation. But docs are scattered across Wiki, Slack, Google Docs, Notion, and Confluence. **doc-hub-mcp** solves this by:
8
+
9
+ 1. **Syncing** documentation from multiple sources into `.md` files
10
+ 2. **Indexing** with an auto-generated knowledge graph
11
+ 3. **Serving** via MCP with 3-tier search (Exact → Graph → Semantic)
12
+
13
+ ### Market Differentiator
14
+
15
+ | | codegraph | agentmemory | coral | **doc-hub-mcp** |
16
+ |---|---|---|---|---|
17
+ | **Target** | Code | Agent memory | APIs | **Documentation** |
18
+ | **Input** | Source code | Agent calls | SQL | **Wiki, Slack, Docs, Notion, Confluence** |
19
+ | **Format** | SQLite | Internal | Tables | **`.md` + git** |
20
+ | **Auto-sync** | File watch | Hook | Manual | **Scheduled / incremental** |
21
+ | **Search** | Symbol graph | Semantic hybrid | SQL | **3-tier (5ms → 20ms → 1s)** |
22
+
23
+ ## Features
24
+
25
+ - **5 sync adapters** — Git Wiki, Google Docs, Slack, Notion, Confluence → `.md`
26
+ - **3-tier search** — Exact (ripgrep, ~5ms) → Knowledge Graph (YAML, ~20ms) → AI Semantic (TF-IDF, ~25ms)
27
+ - **Incremental sync** — Only sync changes since last run, with per-source state tracking
28
+ - **Git versioned** — Auto-commit after each sync, full history and audit trail
29
+ - **MCP server** — 3 tools: `search_knowledge`, `read_document`, `get_document_structure`
30
+ - **Web UI** — Browser dashboard for search, browse, and sync management
31
+ - **LRU cache** — Repeat queries return in <1ms
32
+ - **Zero external dependencies** — No vector database (Pinecone/Weaviate/Chroma), no GPU required
33
+
34
+ ## Quick Start
35
+
36
+ ```bash
37
+ # Install globally
38
+ npm install -g doc-hub-mcp
39
+
40
+ # Initialize a new project
41
+ dhm init
42
+
43
+ # Edit config.json to add your sources, then sync
44
+ dhm sync
45
+
46
+ # Build the search index
47
+ dhm index
48
+
49
+ # Run a search
50
+ dhm search "how to deploy to production"
51
+
52
+ # Start the Web UI
53
+ dhm web
54
+
55
+ # Or start the MCP server for AI agents
56
+ dhm serve
57
+ ```
58
+
59
+ ## CLI Reference
60
+
61
+ ```bash
62
+ dhm init # Create config.json + knowledge-base/
63
+ dhm sync [--incremental] # Sync all sources (or incremental)
64
+ dhm index # Rebuild .dhm-index.yaml
65
+ dhm search "query" # Run 3-tier search
66
+ --tier 1|2|3 # Force tier
67
+ --max 10 # Max results
68
+ --json # JSON output
69
+ dhm serve # Start MCP server
70
+ dhm web # Start Web UI (http://localhost:3456)
71
+ dhm prewarm # Pre-warm cache
72
+ ```
73
+
74
+ ## Configuration
75
+
76
+ ```json
77
+ {
78
+ "knowledgeBase": "./knowledge-base",
79
+ "maxResults": 10,
80
+ "minResults": 3,
81
+ "cache": { "maxSize": 100, "ttl": 3600 },
82
+ "prewarm": { "queries": ["deploy", "api", "config"] },
83
+ "sources": [
84
+ { "type": "git-wiki", "name": "company-wiki", "enabled": true, "url": "https://github.com/company/wiki.git", "branch": "main" },
85
+ { "type": "google-docs", "name": "team-docs", "enabled": false, "credentialsFile": "./credentials.json", "folderId": "xxx" },
86
+ { "type": "slack", "name": "engineering-slack", "enabled": false },
87
+ { "type": "notion", "name": "product-docs", "enabled": false, "url": "your-database-id" },
88
+ { "type": "confluence", "name": "company-confluence", "enabled": false, "url": "https://company.atlassian.net/wiki", "folderId": "SPACEKEY" }
89
+ ]
90
+ }
91
+ ```
92
+
93
+ ## MCP Integration
94
+
95
+ Add to Claude Desktop or Cursor `mcp.json`:
96
+
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "doc-hub-mcp": {
101
+ "command": "npx",
102
+ "args": ["doc-hub-mcp", "serve"],
103
+ "cwd": "/path/to/your/doc-hub"
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### MCP Tools
110
+
111
+ | Tool | Description |
112
+ |---|---|
113
+ | `search_knowledge` | 3-tier search returning ranked results with snippets |
114
+ | `read_document` | Read full content of a document by relative path |
115
+ | `get_document_structure` | Browse directory tree, source list, and sync status |
116
+
117
+ ## Environment Variables
118
+
119
+ | Variable | Adapter | Required |
120
+ |---|---|---|
121
+ | `SLACK_BOT_TOKEN` | Slack | Yes |
122
+ | `NOTION_TOKEN` | Notion | Yes |
123
+ | `CONFLUENCE_URL` | Confluence | Yes |
124
+ | `CONFLUENCE_API_TOKEN` | Confluence | Yes |
125
+ | `GOOGLE_ACCESS_TOKEN` | Google Docs | Yes |
126
+ | `DHM_LOG_LEVEL` | All | No (default: info) |
127
+ | `DHM_PORT` | Web UI | No (default: 3456) |
128
+
129
+ ## Docker
130
+
131
+ ```bash
132
+ docker compose up -d
133
+ ```
134
+
135
+ ## Search Architecture
136
+
137
+ ```
138
+ Agent query
139
+
140
+ ├── Tier 1: Exact Match (ripgrep) ~5ms ← 80% of queries
141
+ │ ↓ miss
142
+ ├── Tier 2: Knowledge Graph (.dhm-index) ~20ms ← 15% of queries
143
+ │ ↓ still insufficient
144
+ └── Tier 3: AI Semantic (TF-IDF) ~25ms ← 5% of queries
145
+
146
+
147
+ Deduplicate + Rank (Tier1=1.0, Tier2=0.8, Tier3=0.5)
148
+ ```
149
+
150
+ ## Project Structure
151
+
152
+ ```
153
+ src/
154
+ ├── cli/ # CLI commands + config loader (zod-validated)
155
+ ├── mcp/ # MCP server + 3 tool implementations
156
+ ├── search/ # 3-tier engine: exact, graph, semantic, cache, pipeline
157
+ ├── index/ # YAML index builder + markdown parser
158
+ ├── sync/ # 5 adapters: git-wiki, google-docs, slack, notion, confluence
159
+ ├── web/ # Express server + browser UI
160
+ └── utils/ # FS, git, logger utilities
161
+ ```
162
+
163
+ ## Documentation
164
+
165
+ - [Quickstart Guide](docs/quickstart.md) — Set up and first sync in 5 minutes
166
+ - [Architecture Guide](docs/architecture.md) — Detailed design and data flow
167
+ - [Contributing Guide](docs/contributing.md) — Conventions, testing, PR process
168
+
169
+ ## License
170
+
171
+ MIT
package/dhm.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import './dist/index.js';
@@ -0,0 +1,11 @@
1
+ export declare function cmdInit(cwd: string): Promise<void>;
2
+ export declare function cmdServe(cwd: string): Promise<void>;
3
+ export declare function cmdSync(cwd: string, incremental?: boolean): Promise<void>;
4
+ export declare function cmdIndex(cwd: string): Promise<void>;
5
+ export declare function cmdSearch(cwd: string, query: string, options?: {
6
+ tier?: 1 | 2 | 3;
7
+ max?: number;
8
+ json?: boolean;
9
+ }): Promise<void>;
10
+ export declare function cmdPrewarm(cwd: string): Promise<void>;
11
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAuBA,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxD;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzD;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA+C7E;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzD;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBvI;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3D"}
@@ -0,0 +1,112 @@
1
+ import { logger } from '../utils/logger.js';
2
+ import { loadConfig, resolveKbPath, initConfig } from './config.js';
3
+ import { startServer } from '../mcp/server.js';
4
+ import { SearchPipeline } from '../search/pipeline.js';
5
+ import { gitWikiAdapter } from '../sync/git-wiki.js';
6
+ import { googleDocsAdapter } from '../sync/google-docs.js';
7
+ import { slackAdapter } from '../sync/slack.js';
8
+ import { notionAdapter } from '../sync/notion.js';
9
+ import { confluenceAdapter } from '../sync/confluence.js';
10
+ import { rebuildIndex } from '../index/builder.js';
11
+ import { clearGraphCache } from '../search/graph.js';
12
+ import { clearSemanticCache } from '../search/semantic.js';
13
+ import { autoCommit, hasChanges } from '../utils/git.js';
14
+ const ADAPTERS = {
15
+ 'git-wiki': gitWikiAdapter,
16
+ 'google-docs': googleDocsAdapter,
17
+ 'slack': slackAdapter,
18
+ 'notion': notionAdapter,
19
+ 'confluence': confluenceAdapter,
20
+ };
21
+ export async function cmdInit(cwd) {
22
+ initConfig(cwd);
23
+ logger.info('Run "dhm serve" to start the MCP server');
24
+ }
25
+ export async function cmdServe(cwd) {
26
+ const config = loadConfig(cwd);
27
+ const kbPath = resolveKbPath(config, cwd);
28
+ logger.info('Starting MCP server', { kbPath, sources: config.sources.length });
29
+ await startServer(config, kbPath);
30
+ }
31
+ export async function cmdSync(cwd, incremental = false) {
32
+ const config = loadConfig(cwd);
33
+ const kbPath = resolveKbPath(config, cwd);
34
+ const enabled = config.sources.filter(s => s.enabled !== false);
35
+ if (enabled.length === 0) {
36
+ logger.info('No enabled sources to sync');
37
+ return;
38
+ }
39
+ logger.info(incremental ? 'Incremental sync' : 'Full sync', { count: enabled.length });
40
+ const results = [];
41
+ for (const source of enabled) {
42
+ const adapter = ADAPTERS[source.type];
43
+ if (!adapter) {
44
+ logger.warn('No adapter found', { type: source.type, name: source.name });
45
+ continue;
46
+ }
47
+ logger.info('Syncing', { name: source.name, type: source.type, incremental });
48
+ const result = await adapter.sync(source, kbPath, cwd, incremental);
49
+ results.push(result);
50
+ logger.info('Sync done', {
51
+ name: result.sourceName,
52
+ written: result.filesWritten,
53
+ updated: result.filesUpdated,
54
+ deleted: result.filesDeleted,
55
+ errors: result.errors.length,
56
+ duration: Math.round(result.duration),
57
+ incremental: result.incremental,
58
+ });
59
+ }
60
+ const totalChanges = results.reduce((s, r) => s + r.filesWritten + r.filesUpdated + r.filesDeleted, 0);
61
+ if (totalChanges > 0) {
62
+ clearGraphCache();
63
+ clearSemanticCache();
64
+ rebuildIndex(config, kbPath);
65
+ if (await hasChanges(kbPath)) {
66
+ await autoCommit(kbPath, `sync${incremental ? ' (incremental)' : ''}: ${new Date().toISOString()}`);
67
+ }
68
+ }
69
+ else {
70
+ logger.info('No changes detected, skipping index rebuild');
71
+ }
72
+ logger.info('All syncs complete', { sources: results.length });
73
+ }
74
+ export async function cmdIndex(cwd) {
75
+ const config = loadConfig(cwd);
76
+ const kbPath = resolveKbPath(config, cwd);
77
+ clearGraphCache();
78
+ clearSemanticCache();
79
+ rebuildIndex(config, kbPath);
80
+ }
81
+ export async function cmdSearch(cwd, query, options) {
82
+ const config = loadConfig(cwd);
83
+ const kbPath = resolveKbPath(config, cwd);
84
+ const pipeline = new SearchPipeline(kbPath, config);
85
+ const response = await pipeline.search(query, {
86
+ maxResults: options?.max,
87
+ tier: options?.tier,
88
+ });
89
+ if (options?.json) {
90
+ console.log(JSON.stringify(response, null, 2));
91
+ }
92
+ else {
93
+ console.log(`\nSearch: "${query}"`);
94
+ console.log(`Time: ${response.totalTime.toFixed(1)}ms | Tier: ${response.tierUsed} | Results: ${response.results.length}\n`);
95
+ for (const r of response.results) {
96
+ console.log(` ${r.path}`);
97
+ console.log(` score: ${r.score.toFixed(2)} | match: ${r.matchType} | tier: ${r.tier}`);
98
+ if (r.snippet)
99
+ console.log(` ${r.snippet.split('\n').map(l => l.trim()).filter(Boolean).join('\n ')}`);
100
+ console.log();
101
+ }
102
+ }
103
+ }
104
+ export async function cmdPrewarm(cwd) {
105
+ const config = loadConfig(cwd);
106
+ const kbPath = resolveKbPath(config, cwd);
107
+ const pipeline = new SearchPipeline(kbPath, config);
108
+ logger.info('Pre-warming cache', { queries: config.prewarm.queries.length });
109
+ pipeline.prewarm(config.prewarm.queries);
110
+ logger.info('Pre-warm complete');
111
+ }
112
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ import { z } from 'zod';
2
+ declare const SourceConfigSchema: z.ZodObject<{
3
+ type: z.ZodEnum<["git-wiki", "google-docs", "slack", "notion", "confluence"]>;
4
+ name: z.ZodString;
5
+ enabled: z.ZodDefault<z.ZodBoolean>;
6
+ url: z.ZodOptional<z.ZodString>;
7
+ branch: z.ZodDefault<z.ZodString>;
8
+ credentialsFile: z.ZodOptional<z.ZodString>;
9
+ folderId: z.ZodOptional<z.ZodString>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ type: "git-wiki" | "google-docs" | "slack" | "notion" | "confluence";
12
+ name: string;
13
+ enabled: boolean;
14
+ branch: string;
15
+ url?: string | undefined;
16
+ credentialsFile?: string | undefined;
17
+ folderId?: string | undefined;
18
+ }, {
19
+ type: "git-wiki" | "google-docs" | "slack" | "notion" | "confluence";
20
+ name: string;
21
+ enabled?: boolean | undefined;
22
+ url?: string | undefined;
23
+ branch?: string | undefined;
24
+ credentialsFile?: string | undefined;
25
+ folderId?: string | undefined;
26
+ }>;
27
+ declare const AppConfigSchema: z.ZodObject<{
28
+ knowledgeBase: z.ZodDefault<z.ZodString>;
29
+ maxResults: z.ZodDefault<z.ZodNumber>;
30
+ minResults: z.ZodDefault<z.ZodNumber>;
31
+ cache: z.ZodDefault<z.ZodObject<{
32
+ maxSize: z.ZodDefault<z.ZodNumber>;
33
+ ttl: z.ZodDefault<z.ZodNumber>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ maxSize: number;
36
+ ttl: number;
37
+ }, {
38
+ maxSize?: number | undefined;
39
+ ttl?: number | undefined;
40
+ }>>;
41
+ prewarm: z.ZodDefault<z.ZodObject<{
42
+ queries: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
43
+ }, "strip", z.ZodTypeAny, {
44
+ queries: string[];
45
+ }, {
46
+ queries?: string[] | undefined;
47
+ }>>;
48
+ sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
49
+ type: z.ZodEnum<["git-wiki", "google-docs", "slack", "notion", "confluence"]>;
50
+ name: z.ZodString;
51
+ enabled: z.ZodDefault<z.ZodBoolean>;
52
+ url: z.ZodOptional<z.ZodString>;
53
+ branch: z.ZodDefault<z.ZodString>;
54
+ credentialsFile: z.ZodOptional<z.ZodString>;
55
+ folderId: z.ZodOptional<z.ZodString>;
56
+ }, "strip", z.ZodTypeAny, {
57
+ type: "git-wiki" | "google-docs" | "slack" | "notion" | "confluence";
58
+ name: string;
59
+ enabled: boolean;
60
+ branch: string;
61
+ url?: string | undefined;
62
+ credentialsFile?: string | undefined;
63
+ folderId?: string | undefined;
64
+ }, {
65
+ type: "git-wiki" | "google-docs" | "slack" | "notion" | "confluence";
66
+ name: string;
67
+ enabled?: boolean | undefined;
68
+ url?: string | undefined;
69
+ branch?: string | undefined;
70
+ credentialsFile?: string | undefined;
71
+ folderId?: string | undefined;
72
+ }>, "many">>;
73
+ }, "strip", z.ZodTypeAny, {
74
+ knowledgeBase: string;
75
+ maxResults: number;
76
+ minResults: number;
77
+ cache: {
78
+ maxSize: number;
79
+ ttl: number;
80
+ };
81
+ prewarm: {
82
+ queries: string[];
83
+ };
84
+ sources: {
85
+ type: "git-wiki" | "google-docs" | "slack" | "notion" | "confluence";
86
+ name: string;
87
+ enabled: boolean;
88
+ branch: string;
89
+ url?: string | undefined;
90
+ credentialsFile?: string | undefined;
91
+ folderId?: string | undefined;
92
+ }[];
93
+ }, {
94
+ knowledgeBase?: string | undefined;
95
+ maxResults?: number | undefined;
96
+ minResults?: number | undefined;
97
+ cache?: {
98
+ maxSize?: number | undefined;
99
+ ttl?: number | undefined;
100
+ } | undefined;
101
+ prewarm?: {
102
+ queries?: string[] | undefined;
103
+ } | undefined;
104
+ sources?: {
105
+ type: "git-wiki" | "google-docs" | "slack" | "notion" | "confluence";
106
+ name: string;
107
+ enabled?: boolean | undefined;
108
+ url?: string | undefined;
109
+ branch?: string | undefined;
110
+ credentialsFile?: string | undefined;
111
+ folderId?: string | undefined;
112
+ }[] | undefined;
113
+ }>;
114
+ export type AppConfig = z.infer<typeof AppConfigSchema>;
115
+ export type SourceConfig = z.infer<typeof SourceConfigSchema>;
116
+ export declare function loadConfig(cwd: string): AppConfig;
117
+ export declare function resolveKbPath(config: AppConfig, cwd: string): string;
118
+ export declare function initConfig(cwd: string): void;
119
+ export {};
120
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;EAQtB,CAAC;AAWH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOnB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAW9D,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAsBjD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU5C"}
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+ import { readFileSafe, writeFile, ensureDir, fileExists } from '../utils/fs.js';
3
+ import { resolve } from 'node:path';
4
+ import { logger } from '../utils/logger.js';
5
+ const SourceConfigSchema = z.object({
6
+ type: z.enum(['git-wiki', 'google-docs', 'slack', 'notion', 'confluence']),
7
+ name: z.string(),
8
+ enabled: z.boolean().default(true),
9
+ url: z.string().optional(),
10
+ branch: z.string().default('main'),
11
+ credentialsFile: z.string().optional(),
12
+ folderId: z.string().optional(),
13
+ });
14
+ const CacheConfigSchema = z.object({
15
+ maxSize: z.number().default(100),
16
+ ttl: z.number().default(3600),
17
+ });
18
+ const PrewarmConfigSchema = z.object({
19
+ queries: z.array(z.string()).default([]),
20
+ });
21
+ const AppConfigSchema = z.object({
22
+ knowledgeBase: z.string().default('./knowledge-base'),
23
+ maxResults: z.number().default(10),
24
+ minResults: z.number().default(3),
25
+ cache: CacheConfigSchema.default({}),
26
+ prewarm: PrewarmConfigSchema.default({}),
27
+ sources: z.array(SourceConfigSchema).default([]),
28
+ });
29
+ const DEFAULT_CONFIG = {
30
+ knowledgeBase: './knowledge-base',
31
+ maxResults: 10,
32
+ minResults: 3,
33
+ cache: { maxSize: 100, ttl: 3600 },
34
+ prewarm: { queries: [] },
35
+ sources: [],
36
+ };
37
+ export function loadConfig(cwd) {
38
+ const configPath = resolve(cwd, 'config.json');
39
+ if (!fileExists(configPath)) {
40
+ logger.warn('No config.json found, using defaults');
41
+ return { ...DEFAULT_CONFIG };
42
+ }
43
+ const raw = readFileSafe(configPath);
44
+ if (!raw)
45
+ return { ...DEFAULT_CONFIG };
46
+ try {
47
+ const parsed = JSON.parse(raw);
48
+ const result = AppConfigSchema.safeParse(parsed);
49
+ if (!result.success) {
50
+ logger.warn('Invalid config.json, using defaults', { errors: result.error.flatten() });
51
+ return { ...DEFAULT_CONFIG };
52
+ }
53
+ return result.data;
54
+ }
55
+ catch {
56
+ logger.warn('Failed to parse config.json, using defaults');
57
+ return { ...DEFAULT_CONFIG };
58
+ }
59
+ }
60
+ export function resolveKbPath(config, cwd) {
61
+ const kbPath = resolve(cwd, config.knowledgeBase);
62
+ ensureDir(kbPath);
63
+ return kbPath;
64
+ }
65
+ export function initConfig(cwd) {
66
+ const configPath = resolve(cwd, 'config.json');
67
+ if (fileExists(configPath)) {
68
+ logger.info('config.json already exists, skipping');
69
+ return;
70
+ }
71
+ writeFile(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));
72
+ const kbPath = resolve(cwd, DEFAULT_CONFIG.knowledgeBase);
73
+ ensureDir(kbPath);
74
+ logger.info('Initialized doc-hub-mcp', { configPath, kbPath });
75
+ }
76
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { AppConfig } from '../cli/config.js';
2
+ export interface KnowledgeGraphDocument {
3
+ path: string;
4
+ title: string;
5
+ tags: string[];
6
+ keywords: string[];
7
+ related: Array<{
8
+ path: string;
9
+ relation: string;
10
+ }>;
11
+ sections: Array<{
12
+ anchor: string;
13
+ title: string;
14
+ keywords: string[];
15
+ }>;
16
+ }
17
+ export interface KnowledgeGraph {
18
+ version: number;
19
+ generated: string;
20
+ documents: KnowledgeGraphDocument[];
21
+ }
22
+ export declare function buildGraph(kbPath: string): KnowledgeGraph;
23
+ export declare function writeGraphIndex(graph: KnowledgeGraph, kbPath: string): string;
24
+ export declare function rebuildIndex(config: AppConfig, kbPath: string): void;
25
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/index/builder.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,QAAQ,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,sBAAsB,EAAE,CAAC;CACrC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAiBzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAKpE"}
@@ -0,0 +1,40 @@
1
+ import { writeFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import * as yaml from 'js-yaml';
4
+ import { logger } from '../utils/logger.js';
5
+ import { parseAllDocuments } from './parser.js';
6
+ export function buildGraph(kbPath) {
7
+ const parsed = parseAllDocuments(kbPath);
8
+ const documents = parsed.map(doc => ({
9
+ path: doc.path,
10
+ title: doc.title,
11
+ tags: doc.tags,
12
+ keywords: doc.keywords,
13
+ related: doc.related,
14
+ sections: doc.sections,
15
+ }));
16
+ return {
17
+ version: 1,
18
+ generated: new Date().toISOString(),
19
+ documents,
20
+ };
21
+ }
22
+ export function writeGraphIndex(graph, kbPath) {
23
+ const indexPath = resolve(kbPath, '.dhm-index.yaml');
24
+ const yamlStr = yaml.dump(graph, {
25
+ indent: 2,
26
+ lineWidth: 120,
27
+ noRefs: true,
28
+ sortKeys: false,
29
+ });
30
+ writeFileSync(indexPath, yamlStr, 'utf-8');
31
+ logger.info('Graph index written', { path: indexPath, docs: graph.documents.length });
32
+ return indexPath;
33
+ }
34
+ export function rebuildIndex(config, kbPath) {
35
+ logger.info('Rebuilding index', { kbPath });
36
+ const graph = buildGraph(kbPath);
37
+ writeGraphIndex(graph, kbPath);
38
+ logger.info('Index rebuild complete', { documents: graph.documents.length });
39
+ }
40
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/index/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAuB,MAAM,aAAa,CAAC;AAkBrE,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAEzC,MAAM,SAAS,GAA6B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACvB,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,MAAc;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;QAC/B,MAAM,EAAE,CAAC;QACT,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IACH,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAiB,EAAE,MAAc;IAC5D,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface ParsedSection {
2
+ anchor: string;
3
+ title: string;
4
+ keywords: string[];
5
+ }
6
+ export interface ParsedDocument {
7
+ path: string;
8
+ title: string;
9
+ tags: string[];
10
+ keywords: string[];
11
+ related: ParsedRelation[];
12
+ sections: ParsedSection[];
13
+ }
14
+ export interface ParsedRelation {
15
+ path: string;
16
+ relation: string;
17
+ }
18
+ export declare function parseDocument(fullPath: string, kbPath: string): ParsedDocument | null;
19
+ export declare function parseAllDocuments(kbPath: string): ParsedDocument[];
20
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/index/parser.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAmJD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAoBrF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAclE"}