mne-docs-mcp 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.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +140 -0
  3. package/dist/cache/manager.d.ts +41 -0
  4. package/dist/cache/manager.d.ts.map +1 -0
  5. package/dist/cache/manager.js +123 -0
  6. package/dist/cache/manager.js.map +1 -0
  7. package/dist/config.d.ts +75 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +120 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/forum/client.d.ts +9 -0
  12. package/dist/forum/client.d.ts.map +1 -0
  13. package/dist/forum/client.js +48 -0
  14. package/dist/forum/client.js.map +1 -0
  15. package/dist/github/client.d.ts +33 -0
  16. package/dist/github/client.d.ts.map +1 -0
  17. package/dist/github/client.js +198 -0
  18. package/dist/github/client.js.map +1 -0
  19. package/dist/github/types.d.ts +238 -0
  20. package/dist/github/types.d.ts.map +1 -0
  21. package/dist/github/types.js +2 -0
  22. package/dist/github/types.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +96 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/parser/bridge.d.ts +46 -0
  28. package/dist/parser/bridge.d.ts.map +1 -0
  29. package/dist/parser/bridge.js +225 -0
  30. package/dist/parser/bridge.js.map +1 -0
  31. package/dist/parser/types.d.ts +36 -0
  32. package/dist/parser/types.d.ts.map +1 -0
  33. package/dist/parser/types.js +2 -0
  34. package/dist/parser/types.js.map +1 -0
  35. package/dist/server.d.ts +4 -0
  36. package/dist/server.d.ts.map +1 -0
  37. package/dist/server.js +218 -0
  38. package/dist/server.js.map +1 -0
  39. package/dist/tools/findMneSymbol.d.ts +22 -0
  40. package/dist/tools/findMneSymbol.d.ts.map +1 -0
  41. package/dist/tools/findMneSymbol.js +74 -0
  42. package/dist/tools/findMneSymbol.js.map +1 -0
  43. package/dist/tools/getMneChangelog.d.ts +31 -0
  44. package/dist/tools/getMneChangelog.d.ts.map +1 -0
  45. package/dist/tools/getMneChangelog.js +233 -0
  46. package/dist/tools/getMneChangelog.js.map +1 -0
  47. package/dist/tools/getMneDoc.d.ts +19 -0
  48. package/dist/tools/getMneDoc.d.ts.map +1 -0
  49. package/dist/tools/getMneDoc.js +248 -0
  50. package/dist/tools/getMneDoc.js.map +1 -0
  51. package/dist/tools/getMneExample.d.ts +31 -0
  52. package/dist/tools/getMneExample.d.ts.map +1 -0
  53. package/dist/tools/getMneExample.js +212 -0
  54. package/dist/tools/getMneExample.js.map +1 -0
  55. package/dist/tools/getMneFile.d.ts +3 -0
  56. package/dist/tools/getMneFile.d.ts.map +1 -0
  57. package/dist/tools/getMneFile.js +60 -0
  58. package/dist/tools/getMneFile.js.map +1 -0
  59. package/dist/tools/getMneForumTopic.d.ts +33 -0
  60. package/dist/tools/getMneForumTopic.d.ts.map +1 -0
  61. package/dist/tools/getMneForumTopic.js +136 -0
  62. package/dist/tools/getMneForumTopic.js.map +1 -0
  63. package/dist/tools/getMneIssue.d.ts +7 -0
  64. package/dist/tools/getMneIssue.d.ts.map +1 -0
  65. package/dist/tools/getMneIssue.js +22 -0
  66. package/dist/tools/getMneIssue.js.map +1 -0
  67. package/dist/tools/getMneIssueComments.d.ts +10 -0
  68. package/dist/tools/getMneIssueComments.d.ts.map +1 -0
  69. package/dist/tools/getMneIssueComments.js +26 -0
  70. package/dist/tools/getMneIssueComments.js.map +1 -0
  71. package/dist/tools/getRelatedSymbols.d.ts +26 -0
  72. package/dist/tools/getRelatedSymbols.d.ts.map +1 -0
  73. package/dist/tools/getRelatedSymbols.js +120 -0
  74. package/dist/tools/getRelatedSymbols.js.map +1 -0
  75. package/dist/tools/getSymbolReferences.d.ts +11 -0
  76. package/dist/tools/getSymbolReferences.d.ts.map +1 -0
  77. package/dist/tools/getSymbolReferences.js +251 -0
  78. package/dist/tools/getSymbolReferences.js.map +1 -0
  79. package/dist/tools/listMneVersions.d.ts +8 -0
  80. package/dist/tools/listMneVersions.d.ts.map +1 -0
  81. package/dist/tools/listMneVersions.js +32 -0
  82. package/dist/tools/listMneVersions.js.map +1 -0
  83. package/dist/tools/lookupMneError.d.ts +59 -0
  84. package/dist/tools/lookupMneError.d.ts.map +1 -0
  85. package/dist/tools/lookupMneError.js +280 -0
  86. package/dist/tools/lookupMneError.js.map +1 -0
  87. package/dist/tools/searchMneDocs.d.ts +3 -0
  88. package/dist/tools/searchMneDocs.d.ts.map +1 -0
  89. package/dist/tools/searchMneDocs.js +58 -0
  90. package/dist/tools/searchMneDocs.js.map +1 -0
  91. package/dist/tools/searchMneForum.d.ts +9 -0
  92. package/dist/tools/searchMneForum.d.ts.map +1 -0
  93. package/dist/tools/searchMneForum.js +29 -0
  94. package/dist/tools/searchMneForum.js.map +1 -0
  95. package/dist/tools/searchMneIssues.d.ts +8 -0
  96. package/dist/tools/searchMneIssues.d.ts.map +1 -0
  97. package/dist/tools/searchMneIssues.js +23 -0
  98. package/dist/tools/searchMneIssues.js.map +1 -0
  99. package/dist/types.d.ts +140 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +35 -0
  102. package/dist/types.js.map +1 -0
  103. package/dist/utils/docstring.d.ts +26 -0
  104. package/dist/utils/docstring.d.ts.map +1 -0
  105. package/dist/utils/docstring.js +261 -0
  106. package/dist/utils/docstring.js.map +1 -0
  107. package/dist/utils/logger.d.ts +19 -0
  108. package/dist/utils/logger.d.ts.map +1 -0
  109. package/dist/utils/logger.js +73 -0
  110. package/dist/utils/logger.js.map +1 -0
  111. package/dist/utils/metrics.d.ts +38 -0
  112. package/dist/utils/metrics.d.ts.map +1 -0
  113. package/dist/utils/metrics.js +57 -0
  114. package/dist/utils/metrics.js.map +1 -0
  115. package/dist/version.d.ts +2 -0
  116. package/dist/version.d.ts.map +1 -0
  117. package/dist/version.js +18 -0
  118. package/dist/version.js.map +1 -0
  119. package/package.json +71 -0
  120. package/python/ast_extractor.py +422 -0
  121. package/python/parser.py +68 -0
  122. package/python/requirements.txt +2 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 weiyongxu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # MNE Docs MCP Server
2
+
3
+ MCP server providing access to MNE-Python documentation, source code, GitHub issues, and community forum across the MNE ecosystem.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Clone and install
9
+ git clone https://github.com/weiyongxu/mne-docs-mcp.git
10
+ cd mne-docs-mcp
11
+ npm install
12
+
13
+ # Set GitHub token (required)
14
+ export MNE_GITHUB_TOKEN=ghp_your_token_here
15
+
16
+ # Start server
17
+ npm start
18
+ ```
19
+
20
+ Server runs on `http://localhost:8000`. Verify with `curl http://localhost:8000/health`.
21
+
22
+ ## MCP Client Integration
23
+
24
+ ### Claude Desktop / Kiro / Claude Code
25
+
26
+ Add to your MCP config (`claude_desktop_config.json`, `.kiro/settings/mcp.json`, or `~/.claude/settings.json`):
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "mne-docs": {
32
+ "command": "node",
33
+ "args": ["/path/to/mne-docs-mcp/dist/index.js"],
34
+ "env": {
35
+ "MNE_GITHUB_TOKEN": "ghp_your_token_here",
36
+ "MNE_TRANSPORT": "stdio"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ > **Windows:** Add `"MNE_PYTHON_PATH": "python"` to env.
44
+
45
+ ### HTTP Mode
46
+
47
+ ```bash
48
+ MNE_TRANSPORT=http npm start
49
+ # Connect to http://localhost:8000/mcp
50
+ ```
51
+
52
+ ### Docker
53
+
54
+ ```bash
55
+ docker run -p 8000:8000 -e MNE_GITHUB_TOKEN=ghp_your_token mne-docs-mcp
56
+ ```
57
+
58
+ ### Docker Compose
59
+
60
+ ```bash
61
+ # Set your token
62
+ export MNE_GITHUB_TOKEN=ghp_your_token_here
63
+
64
+ # Start
65
+ docker-compose up -d
66
+
67
+ # View logs
68
+ docker-compose logs -f
69
+ ```
70
+
71
+ ## Tools
72
+
73
+ | Tool | Description |
74
+ |------|-------------|
75
+ | `list_mne_versions` | List available MNE releases |
76
+ | `get_mne_file` | Fetch source code |
77
+ | `get_mne_doc` | Get symbol documentation |
78
+ | `find_mne_symbol` | Search for symbols |
79
+ | `search_mne_docs` | Unified code/docs search |
80
+ | `search_mne_issues` | Search GitHub issues |
81
+ | `get_mne_issue` | Get issue details |
82
+ | `get_mne_issue_comments` | Get issue comments |
83
+ | `search_mne_forum` | Search community forum |
84
+ | `get_mne_forum_topic` | Get full forum discussion |
85
+ | `get_symbol_references` | Get callees/callers |
86
+ | `get_related_symbols` | Find related functions |
87
+ | `get_mne_changelog` | Get version changes |
88
+ | `get_mne_example` | Get tutorial code |
89
+ | `lookup_mne_error` | Diagnose MNE errors |
90
+
91
+ All tools support a `package` parameter to query across the MNE ecosystem: `mne-python` (default), `mne-bids-pipeline`, `mne-bids`, `mne-connectivity`, `mne-nirs`, `mne-rsa`, `mne-icalabel`, `mne-realtime`, `mne-lsl`, `mne-gui-addons`.
92
+
93
+ ## Configuration
94
+
95
+ | Variable | Description | Default |
96
+ |----------|-------------|---------|
97
+ | `MNE_GITHUB_TOKEN` | GitHub PAT (required) | - |
98
+ | `MNE_PORT` | Server port | `8000` |
99
+ | `MNE_TRANSPORT` | `http` or `stdio` | `http` |
100
+ | `MNE_PYTHON_PATH` | Python executable | `python3` |
101
+ | `MNE_LOG_LEVEL` | `debug`/`info`/`warn`/`error` | `info` |
102
+
103
+ See `.env.example` for all options including cache TTLs and timeouts.
104
+
105
+ ## Architecture
106
+
107
+ ```
108
+ ┌─────────────────────────────────────────────────────────┐
109
+ │ TypeScript Server (Node.js) │
110
+ │ ├─ MCP Tools (McpServer API, SDK v1.18+) │
111
+ │ ├─ GitHub Client (rate limiting, caching) │
112
+ │ └─ Python Parser Bridge ──┐ │
113
+ └────────────────────────────┼────────────────────────────┘
114
+
115
+ ┌─────────────────┐
116
+ │ Python Parser │
117
+ │ (AST, stdlib) │
118
+ └─────────────────┘
119
+ ```
120
+
121
+ Built with the official [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk).
122
+
123
+ ## Development
124
+
125
+ ```bash
126
+ npm run dev # Watch mode
127
+ npm run build # Compile TypeScript
128
+ npm test # Run tests
129
+ npm run lint # ESLint
130
+ ```
131
+
132
+ ## Troubleshooting
133
+
134
+ - **Rate limits:** Ensure `MNE_GITHUB_TOKEN` is set
135
+ - **Parser fails:** Check Python 3 is installed; Windows users set `MNE_PYTHON_PATH=python`
136
+ - **Test setup:** Run `npx tsx examples/mcp-client.ts` to verify
137
+
138
+ ## License
139
+
140
+ MIT
@@ -0,0 +1,41 @@
1
+ import { Config } from '../config.js';
2
+ import { MneVersion, ParsedSymbol, SearchResult, ForumSearchItem } from '../types.js';
3
+ export interface CacheEntry<T> {
4
+ data: T;
5
+ expiresAt: number;
6
+ lastAccessed: number;
7
+ }
8
+ export interface CacheStats {
9
+ entries: number;
10
+ hits: number;
11
+ misses: number;
12
+ hitRate: number;
13
+ }
14
+ export declare class CacheManager {
15
+ private config;
16
+ private logger;
17
+ private versionTtlMs;
18
+ private versions;
19
+ private fileCache;
20
+ private symbolCache;
21
+ private searchCache;
22
+ private forumCache;
23
+ constructor(config: Config);
24
+ getVersions(): MneVersion[] | null;
25
+ setVersions(versions: MneVersion[]): void;
26
+ getFile(version: string, path: string): string | null;
27
+ setFile(version: string, path: string, content: string): void;
28
+ getSymbol(version: string, symbol: string): ParsedSymbol | null;
29
+ setSymbol(version: string, symbol: string, data: ParsedSymbol): void;
30
+ getSearch(version: string, query: string): SearchResult | null;
31
+ setSearch(version: string, query: string, data: SearchResult): void;
32
+ getForumSearch(query: string): ForumSearchItem[] | null;
33
+ setForumSearch(query: string, results: ForumSearchItem[]): void;
34
+ private getEntry;
35
+ private setEntry;
36
+ private recordHitMiss;
37
+ private pruneIfNeeded;
38
+ getStats(): CacheStats;
39
+ clear(): void;
40
+ }
41
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAItF,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,UAAU,CAAyD;gBAE/D,MAAM,EAAE,MAAM;IAM1B,WAAW,IAAI,UAAU,EAAE,GAAG,IAAI;IAWlC,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IASzC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIrD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK7D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAI/D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAKpE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAI9D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAKnE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,GAAG,IAAI;IAIvD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAK/D,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa;IAYrB,QAAQ,IAAI,UAAU;IAUtB,KAAK,IAAI,IAAI;CAOhB"}
@@ -0,0 +1,123 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ import { metrics } from '../utils/metrics.js';
3
+ export class CacheManager {
4
+ config;
5
+ logger = getLogger();
6
+ versionTtlMs;
7
+ versions = null;
8
+ fileCache = new Map();
9
+ symbolCache = new Map();
10
+ searchCache = new Map();
11
+ forumCache = new Map();
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.versionTtlMs = config.versionCacheTtlMinutes * 60 * 1000;
15
+ }
16
+ // Versions
17
+ getVersions() {
18
+ if (!this.versions || Date.now() > this.versions.expiresAt) {
19
+ this.versions = null;
20
+ this.recordHitMiss(false);
21
+ return null;
22
+ }
23
+ this.versions.lastAccessed = Date.now();
24
+ this.recordHitMiss(true);
25
+ return this.versions.data;
26
+ }
27
+ setVersions(versions) {
28
+ this.versions = {
29
+ data: versions,
30
+ expiresAt: Date.now() + this.versionTtlMs,
31
+ lastAccessed: Date.now(),
32
+ };
33
+ }
34
+ // Files
35
+ getFile(version, path) {
36
+ return this.getEntry(this.fileCache, `file:${version}:${path}`);
37
+ }
38
+ setFile(version, path, content) {
39
+ this.setEntry(this.fileCache, `file:${version}:${path}`, content, this.config.fileCacheTtlMinutes);
40
+ }
41
+ // Symbols
42
+ getSymbol(version, symbol) {
43
+ return this.getEntry(this.symbolCache, `symbol:${version}:${symbol}`);
44
+ }
45
+ setSymbol(version, symbol, data) {
46
+ this.setEntry(this.symbolCache, `symbol:${version}:${symbol}`, data, this.config.symbolCacheTtlMinutes);
47
+ }
48
+ // Search
49
+ getSearch(version, query) {
50
+ return this.getEntry(this.searchCache, `search:${version}:${query}`);
51
+ }
52
+ setSearch(version, query, data) {
53
+ this.setEntry(this.searchCache, `search:${version}:${query}`, data, this.config.fileCacheTtlMinutes);
54
+ }
55
+ // Forum
56
+ getForumSearch(query) {
57
+ return this.getEntry(this.forumCache, `forum:${query}`);
58
+ }
59
+ setForumSearch(query, results) {
60
+ this.setEntry(this.forumCache, `forum:${query}`, results, 30);
61
+ }
62
+ // Generic helpers
63
+ getEntry(cache, key) {
64
+ const entry = cache.get(key);
65
+ if (!entry) {
66
+ this.recordHitMiss(false);
67
+ return null;
68
+ }
69
+ if (Date.now() > entry.expiresAt) {
70
+ cache.delete(key);
71
+ this.recordHitMiss(false);
72
+ return null;
73
+ }
74
+ entry.lastAccessed = Date.now();
75
+ this.recordHitMiss(true);
76
+ return entry.data;
77
+ }
78
+ setEntry(cache, key, data, ttlMinutes) {
79
+ cache.set(key, {
80
+ data,
81
+ expiresAt: Date.now() + ttlMinutes * 60 * 1000,
82
+ lastAccessed: Date.now(),
83
+ });
84
+ this.pruneIfNeeded();
85
+ }
86
+ recordHitMiss(hit) {
87
+ if (hit) {
88
+ metrics.recordCacheHit();
89
+ }
90
+ else {
91
+ metrics.recordCacheMiss();
92
+ }
93
+ }
94
+ pruneIfNeeded() {
95
+ const total = this.fileCache.size + this.symbolCache.size + this.searchCache.size + this.forumCache.size;
96
+ if (total > this.config.maxCacheEntries) {
97
+ this.logger.debug('Pruning cache', { totalEntries: total });
98
+ [this.fileCache, this.symbolCache, this.searchCache, this.forumCache].forEach(cache => {
99
+ for (const [key, entry] of cache.entries()) {
100
+ if (Date.now() > entry.expiresAt)
101
+ cache.delete(key);
102
+ }
103
+ });
104
+ }
105
+ }
106
+ getStats() {
107
+ const m = metrics.getMetrics();
108
+ return {
109
+ entries: this.fileCache.size + this.symbolCache.size + this.searchCache.size + this.forumCache.size,
110
+ hits: m.cache.hits,
111
+ misses: m.cache.misses,
112
+ hitRate: m.cache.hitRate,
113
+ };
114
+ }
115
+ clear() {
116
+ this.versions = null;
117
+ this.fileCache.clear();
118
+ this.symbolCache.clear();
119
+ this.searchCache.clear();
120
+ this.forumCache.clear();
121
+ }
122
+ }
123
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * MNE Package metadata for multi-package support.
4
+ * Each package has its own GitHub repo, source path, and documentation URL.
5
+ */
6
+ export interface MnePackageInfo {
7
+ repo: string;
8
+ sourcePath: string;
9
+ docsUrl: string;
10
+ }
11
+ /**
12
+ * Registry of supported MNE ecosystem packages.
13
+ */
14
+ export declare const MNE_PACKAGES: Record<string, MnePackageInfo>;
15
+ export declare const MNE_PACKAGE_NAMES: string[];
16
+ export declare const DEFAULT_PACKAGE = "mne-python";
17
+ /**
18
+ * Get package info by name, with fallback to default.
19
+ */
20
+ export declare function getPackageInfo(packageName?: string): MnePackageInfo;
21
+ export declare const ConfigSchema: z.ZodObject<{
22
+ port: z.ZodDefault<z.ZodNumber>;
23
+ transport: z.ZodDefault<z.ZodEnum<["http", "stdio"]>>;
24
+ githubToken: z.ZodString;
25
+ githubApiBase: z.ZodDefault<z.ZodString>;
26
+ defaultPackage: z.ZodDefault<z.ZodString>;
27
+ githubTimeout: z.ZodDefault<z.ZodNumber>;
28
+ forumBaseUrl: z.ZodDefault<z.ZodString>;
29
+ forumTimeout: z.ZodDefault<z.ZodNumber>;
30
+ versionCacheTtlMinutes: z.ZodDefault<z.ZodNumber>;
31
+ symbolCacheTtlMinutes: z.ZodDefault<z.ZodNumber>;
32
+ fileCacheTtlMinutes: z.ZodDefault<z.ZodNumber>;
33
+ maxCacheEntries: z.ZodDefault<z.ZodNumber>;
34
+ pythonPath: z.ZodDefault<z.ZodString>;
35
+ parserTimeout: z.ZodDefault<z.ZodNumber>;
36
+ logLevel: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error"]>>;
37
+ logJson: z.ZodDefault<z.ZodBoolean>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ port: number;
40
+ transport: "http" | "stdio";
41
+ githubToken: string;
42
+ githubApiBase: string;
43
+ defaultPackage: string;
44
+ githubTimeout: number;
45
+ forumBaseUrl: string;
46
+ forumTimeout: number;
47
+ versionCacheTtlMinutes: number;
48
+ symbolCacheTtlMinutes: number;
49
+ fileCacheTtlMinutes: number;
50
+ maxCacheEntries: number;
51
+ pythonPath: string;
52
+ parserTimeout: number;
53
+ logLevel: "debug" | "info" | "warn" | "error";
54
+ logJson: boolean;
55
+ }, {
56
+ githubToken: string;
57
+ port?: number | undefined;
58
+ transport?: "http" | "stdio" | undefined;
59
+ githubApiBase?: string | undefined;
60
+ defaultPackage?: string | undefined;
61
+ githubTimeout?: number | undefined;
62
+ forumBaseUrl?: string | undefined;
63
+ forumTimeout?: number | undefined;
64
+ versionCacheTtlMinutes?: number | undefined;
65
+ symbolCacheTtlMinutes?: number | undefined;
66
+ fileCacheTtlMinutes?: number | undefined;
67
+ maxCacheEntries?: number | undefined;
68
+ pythonPath?: string | undefined;
69
+ parserTimeout?: number | undefined;
70
+ logLevel?: "debug" | "info" | "warn" | "error" | undefined;
71
+ logJson?: boolean | undefined;
72
+ }>;
73
+ export type Config = z.infer<typeof ConfigSchema>;
74
+ export declare function loadConfig(): Config;
75
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAmDvD,CAAC;AAEF,eAAO,MAAM,iBAAiB,UAA4B,CAAC;AAC3D,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,cAAc,CAOnE;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,wBAAgB,UAAU,IAAI,MAAM,CAkCnC"}
package/dist/config.js ADDED
@@ -0,0 +1,120 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Registry of supported MNE ecosystem packages.
4
+ */
5
+ export const MNE_PACKAGES = {
6
+ 'mne-python': {
7
+ repo: 'mne-tools/mne-python',
8
+ sourcePath: 'mne/',
9
+ docsUrl: 'https://mne.tools/stable/',
10
+ },
11
+ 'mne-bids-pipeline': {
12
+ repo: 'mne-tools/mne-bids-pipeline',
13
+ sourcePath: 'mne_bids_pipeline/',
14
+ docsUrl: 'https://mne.tools/mne-bids-pipeline/stable/',
15
+ },
16
+ 'mne-bids': {
17
+ repo: 'mne-tools/mne-bids',
18
+ sourcePath: 'mne_bids/',
19
+ docsUrl: 'https://mne.tools/mne-bids/stable/',
20
+ },
21
+ 'mne-connectivity': {
22
+ repo: 'mne-tools/mne-connectivity',
23
+ sourcePath: 'mne_connectivity/',
24
+ docsUrl: 'https://mne.tools/mne-connectivity/stable/',
25
+ },
26
+ 'mne-nirs': {
27
+ repo: 'mne-tools/mne-nirs',
28
+ sourcePath: 'mne_nirs/',
29
+ docsUrl: 'https://mne.tools/mne-nirs/stable/',
30
+ },
31
+ 'mne-rsa': {
32
+ repo: 'mne-tools/mne-rsa',
33
+ sourcePath: 'mne_rsa/',
34
+ docsUrl: 'https://mne.tools/mne-rsa/stable/',
35
+ },
36
+ 'mne-icalabel': {
37
+ repo: 'mne-tools/mne-icalabel',
38
+ sourcePath: 'mne_icalabel/',
39
+ docsUrl: 'https://mne.tools/mne-icalabel/stable/',
40
+ },
41
+ 'mne-realtime': {
42
+ repo: 'mne-tools/mne-realtime',
43
+ sourcePath: 'mne_realtime/',
44
+ docsUrl: 'https://mne.tools/mne-realtime/',
45
+ },
46
+ 'mne-lsl': {
47
+ repo: 'mne-tools/mne-lsl',
48
+ sourcePath: 'mne_lsl/',
49
+ docsUrl: 'https://mne.tools/mne-lsl/stable/',
50
+ },
51
+ 'mne-gui-addons': {
52
+ repo: 'mne-tools/mne-gui-addons',
53
+ sourcePath: 'mne_gui_addons/',
54
+ docsUrl: 'https://mne.tools/mne-gui-addons/',
55
+ },
56
+ };
57
+ export const MNE_PACKAGE_NAMES = Object.keys(MNE_PACKAGES);
58
+ export const DEFAULT_PACKAGE = 'mne-python';
59
+ /**
60
+ * Get package info by name, with fallback to default.
61
+ */
62
+ export function getPackageInfo(packageName) {
63
+ const name = packageName || DEFAULT_PACKAGE;
64
+ const info = MNE_PACKAGES[name];
65
+ if (!info) {
66
+ throw new Error(`Unknown MNE package: ${name}. Supported: ${MNE_PACKAGE_NAMES.join(', ')}`);
67
+ }
68
+ return info;
69
+ }
70
+ export const ConfigSchema = z.object({
71
+ port: z.coerce.number().default(8000),
72
+ transport: z.enum(['http', 'stdio']).default('http'),
73
+ githubToken: z.string().min(1),
74
+ githubApiBase: z.string().default('https://api.github.com'),
75
+ defaultPackage: z.string().default(DEFAULT_PACKAGE),
76
+ githubTimeout: z.coerce.number().default(15000),
77
+ forumBaseUrl: z.string().default('https://mne.discourse.group'),
78
+ forumTimeout: z.coerce.number().default(15000),
79
+ versionCacheTtlMinutes: z.coerce.number().default(60),
80
+ symbolCacheTtlMinutes: z.coerce.number().default(30),
81
+ fileCacheTtlMinutes: z.coerce.number().default(15),
82
+ maxCacheEntries: z.coerce.number().default(1000),
83
+ pythonPath: z.string().default('python3'),
84
+ parserTimeout: z.coerce.number().default(10000),
85
+ logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
86
+ logJson: z.coerce.boolean().default(false),
87
+ });
88
+ export function loadConfig() {
89
+ const config = {
90
+ port: process.env.MNE_PORT,
91
+ transport: process.env.MNE_TRANSPORT,
92
+ githubToken: process.env.MNE_GITHUB_TOKEN,
93
+ githubApiBase: process.env.MNE_GITHUB_API_BASE,
94
+ defaultPackage: process.env.MNE_DEFAULT_PACKAGE,
95
+ githubTimeout: process.env.MNE_GITHUB_TIMEOUT,
96
+ forumBaseUrl: process.env.MNE_FORUM_BASE_URL,
97
+ forumTimeout: process.env.MNE_FORUM_TIMEOUT,
98
+ versionCacheTtlMinutes: process.env.MNE_CACHE_TTL_MINUTES, // Using generic TTL for version if not specific
99
+ symbolCacheTtlMinutes: process.env.MNE_SYMBOL_CACHE_TTL_MINUTES,
100
+ fileCacheTtlMinutes: process.env.MNE_FILE_CACHE_TTL_MINUTES,
101
+ maxCacheEntries: process.env.MNE_MAX_CACHE_ENTRIES,
102
+ pythonPath: process.env.MNE_PYTHON_PATH,
103
+ parserTimeout: process.env.MNE_PARSER_TIMEOUT,
104
+ logLevel: process.env.MNE_LOG_LEVEL,
105
+ logJson: process.env.MNE_LOG_JSON,
106
+ };
107
+ // Filter undefined values to allow Zod defaults to work
108
+ const cleanConfig = Object.fromEntries(Object.entries(config).filter(([_, v]) => v !== undefined));
109
+ try {
110
+ return ConfigSchema.parse(cleanConfig);
111
+ }
112
+ catch (error) {
113
+ if (error instanceof z.ZodError) {
114
+ const issues = error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join('\n');
115
+ throw new Error(`Configuration validation failed:\n${issues}\n\nMake sure MNE_GITHUB_TOKEN is set.`);
116
+ }
117
+ throw error;
118
+ }
119
+ }
120
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { ForumSearchItem } from '../types.js';
2
+ export declare class ForumClient {
3
+ readonly baseUrl: string;
4
+ readonly timeout: number;
5
+ private logger;
6
+ constructor(baseUrl: string, timeout: number);
7
+ search(query: string, limit?: number): Promise<ForumSearchItem[]>;
8
+ }
9
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/forum/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgE9C,qBAAa,WAAW;IACpB,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,MAAM,CAAe;gBAEjB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAKtC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CA0C7E"}
@@ -0,0 +1,48 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ export class ForumClient {
3
+ baseUrl;
4
+ timeout;
5
+ logger = getLogger();
6
+ constructor(baseUrl, timeout) {
7
+ this.baseUrl = baseUrl;
8
+ this.timeout = timeout;
9
+ }
10
+ async search(query, limit = 5) {
11
+ const url = `${this.baseUrl}/search.json?q=${encodeURIComponent(query)}`;
12
+ try {
13
+ const response = await fetch(url, {
14
+ headers: { 'Accept': 'application/json' },
15
+ signal: AbortSignal.timeout(this.timeout),
16
+ });
17
+ if (!response.ok) {
18
+ this.logger.error('Forum search failed', { status: response.status });
19
+ return [];
20
+ }
21
+ const data = await response.json();
22
+ // Discourse returns topics and posts separately
23
+ // Posts contain the blurb/excerpt, topics contain metadata
24
+ const topics = data.topics || [];
25
+ const posts = data.posts || [];
26
+ // Create a map of topic_id -> first post blurb
27
+ const postBlurbs = new Map();
28
+ for (const post of posts) {
29
+ if (post.topic_id && post.blurb && !postBlurbs.has(post.topic_id)) {
30
+ postBlurbs.set(post.topic_id, post.blurb);
31
+ }
32
+ }
33
+ return topics.slice(0, limit).map((t) => ({
34
+ source: 'forum',
35
+ title: t.fancy_title || t.title,
36
+ url: `${this.baseUrl}/t/${t.slug}/${t.id}`,
37
+ blurb: postBlurbs.get(t.id) || t.excerpt || t.blurb || '',
38
+ postsCount: t.posts_count,
39
+ createdAt: t.created_at,
40
+ }));
41
+ }
42
+ catch (error) {
43
+ this.logger.error('Forum search error', { error });
44
+ return [];
45
+ }
46
+ }
47
+ }
48
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/forum/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA+D/C,MAAM,OAAO,WAAW;IACJ,OAAO,CAAS;IAChB,OAAO,CAAS;IACxB,MAAM,GAAG,SAAS,EAAE,CAAC;IAE7B,YAAY,OAAe,EAAE,OAAe;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,QAAgB,CAAC;QACzC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAEzE,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC9B,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE;gBACzC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;aAC5C,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBACtE,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;YAE9D,gDAAgD;YAChD,2DAA2D;YAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAE/B,+CAA+C;YAC/C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,CAAC;YACL,CAAC;YAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtC,MAAM,EAAE,OAAgB;gBACxB,KAAK,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,KAAK;gBAC/B,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE;gBAC1C,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE;gBACzD,UAAU,EAAE,CAAC,CAAC,WAAW;gBACzB,SAAS,EAAE,CAAC,CAAC,UAAU;aAC1B,CAAC,CAAC,CAAC;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACnD,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,33 @@
1
+ import { Config } from '../config.js';
2
+ import { MneVersion, GithubIssueItem } from '../types.js';
3
+ import { GitHubSearchCodeResult, GitHubIssueDetail, GitHubIssueComment, RateLimitInfo } from './types.js';
4
+ export declare class GitHubClient {
5
+ readonly config: Config;
6
+ private logger;
7
+ private rateLimitInfo;
8
+ constructor(config: Config);
9
+ private getRepo;
10
+ getRateLimitInfo(): RateLimitInfo | null;
11
+ private updateRateLimit;
12
+ private handleRateLimit;
13
+ private request;
14
+ fetchVersions(limit?: number, packageName?: string): Promise<MneVersion[]>;
15
+ getLatestVersion(packageName?: string): Promise<string>;
16
+ fetchFile(path: string, version?: string, packageName?: string): Promise<string | null>;
17
+ fileExists(path: string, version?: string, packageName?: string): Promise<boolean>;
18
+ searchCode(query: string, options?: {
19
+ path?: string;
20
+ perPage?: number;
21
+ version?: string;
22
+ packageName?: string;
23
+ }): Promise<GitHubSearchCodeResult>;
24
+ searchIssues(query: string, options?: {
25
+ state?: 'open' | 'closed' | 'all';
26
+ labels?: string[];
27
+ perPage?: number;
28
+ packageName?: string;
29
+ }): Promise<GithubIssueItem[]>;
30
+ getIssue(issueNumber: number, packageName?: string): Promise<GitHubIssueDetail | null>;
31
+ getIssueComments(issueNumber: number, packageName?: string): Promise<GitHubIssueComment[]>;
32
+ }
33
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/github/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACgB,sBAAsB,EACpB,iBAAiB,EACtC,kBAAkB,EAAa,aAAa,EAC/C,MAAM,YAAY,CAAC;AAIpB,qBAAa,YAAY;IACrB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAA8B;gBAEvC,MAAM,EAAE,MAAM;IAI1B,OAAO,CAAC,OAAO;IAIf,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC,OAAO,CAAC,eAAe;YAkBT,eAAe;YAaf,OAAO;IAoCf,aAAa,CAAC,KAAK,GAAE,MAAW,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAU9E,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMvD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAyBvF,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlF,UAAU,CACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAC1F,OAAO,CAAC,sBAAsB,CAAC;IAS5B,YAAY,CACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/G,OAAO,CAAC,eAAe,EAAE,CAAC;IA2BvB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAyBtF,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAkBnG"}