anki-mcp-http 0.5.0 → 0.7.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/README.md +54 -8
- package/bin/ankimcp.js +11 -1
- package/dist/cli.js +23 -5
- package/dist/cli.js.map +1 -1
- package/dist/mcp/primitives/essential/index.d.ts +1 -0
- package/dist/mcp/primitives/essential/index.js +5 -1
- package/dist/mcp/primitives/essential/index.js.map +1 -1
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/content.md +195 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.d.ts +12 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js +87 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js.map +1 -0
- package/dist/mcp/utils/markdown.utils.d.ts +4 -0
- package/dist/mcp/utils/markdown.utils.js +56 -0
- package/dist/mcp/utils/markdown.utils.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -31,6 +31,13 @@ For comprehensive guides, real-world examples, and step-by-step tutorials on usi
|
|
|
31
31
|
- `updateNoteFields` - Update existing note fields (CSS-aware, supports HTML)
|
|
32
32
|
- `deleteNotes` - Delete notes and their cards
|
|
33
33
|
|
|
34
|
+
### Media Management
|
|
35
|
+
- `mediaActions` - Manage media files (audio/images)
|
|
36
|
+
- `storeMediaFile` - Upload media from base64 data, file paths, or URLs
|
|
37
|
+
- `retrieveMediaFile` - Download media as base64
|
|
38
|
+
- `getMediaFilesNames` - List media files with optional pattern filtering
|
|
39
|
+
- `deleteMediaFile` - Remove media files
|
|
40
|
+
|
|
34
41
|
### Model/Template Management
|
|
35
42
|
- `modelNames` - List note types
|
|
36
43
|
- `modelFieldNames` - Get fields for a note type
|
|
@@ -61,7 +68,42 @@ The easiest way to install this MCP server for Claude Desktop:
|
|
|
61
68
|
|
|
62
69
|
That's it! The bundle includes everything needed to run the server locally.
|
|
63
70
|
|
|
64
|
-
### Option 2:
|
|
71
|
+
### Option 2: NPM Package with STDIO (For Other MCP Clients)
|
|
72
|
+
|
|
73
|
+
Want to use Anki with MCP clients like **Cursor IDE**, **Cline**, or **Zed Editor**? Use the npm package with the `--stdio` flag:
|
|
74
|
+
|
|
75
|
+
**Supported Clients:**
|
|
76
|
+
- [Cursor IDE](https://www.cursor.com/) - AI-powered code editor
|
|
77
|
+
- [Cline](https://github.com/cline/cline) - VS Code extension for AI assistance
|
|
78
|
+
- [Zed Editor](https://zed.dev/) - Fast, modern code editor
|
|
79
|
+
- Other MCP clients that support STDIO transport
|
|
80
|
+
|
|
81
|
+
**Basic Configuration:**
|
|
82
|
+
|
|
83
|
+
Add this to your MCP client's configuration file:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"anki-mcp": {
|
|
89
|
+
"command": "npx",
|
|
90
|
+
"args": ["-y", "anki-mcp-http", "--stdio"],
|
|
91
|
+
"env": {
|
|
92
|
+
"ANKI_CONNECT_URL": "http://localhost:8765"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Configuration file locations:**
|
|
100
|
+
- **Cursor IDE**: `~/.cursor/mcp.json` (macOS/Linux) or `%USERPROFILE%\.cursor\mcp.json` (Windows)
|
|
101
|
+
- **Cline**: Accessible via settings UI in VS Code
|
|
102
|
+
- **Zed Editor**: Install as MCP extension through extension marketplace
|
|
103
|
+
|
|
104
|
+
For client-specific features and troubleshooting, consult your MCP client's documentation.
|
|
105
|
+
|
|
106
|
+
### Option 3: HTTP Mode (For Remote AI Assistants)
|
|
65
107
|
|
|
66
108
|
Want to use Anki with ChatGPT or Claude.ai in your browser? This mode lets you connect web-based AI tools to your local Anki.
|
|
67
109
|
|
|
@@ -93,15 +135,19 @@ npm run start:prod:http
|
|
|
93
135
|
ankimcp [options]
|
|
94
136
|
|
|
95
137
|
Options:
|
|
96
|
-
|
|
97
|
-
-
|
|
138
|
+
--stdio Run in STDIO mode (for MCP clients)
|
|
139
|
+
-p, --port <port> Port to listen on (HTTP mode, default: 3000)
|
|
140
|
+
-h, --host <host> Host to bind to (HTTP mode, default: 127.0.0.1)
|
|
98
141
|
-a, --anki-connect <url> AnkiConnect URL (default: http://localhost:8765)
|
|
99
142
|
--help Show help message
|
|
100
143
|
|
|
101
|
-
Examples:
|
|
102
|
-
ankimcp # Use all defaults
|
|
144
|
+
Examples - HTTP Mode:
|
|
145
|
+
ankimcp # Use all defaults (HTTP mode)
|
|
103
146
|
ankimcp --port 8080 # Custom port
|
|
104
147
|
ankimcp --host 0.0.0.0 # Listen on all network interfaces
|
|
148
|
+
|
|
149
|
+
Examples - STDIO Mode:
|
|
150
|
+
ankimcp --stdio # For use with npx in MCP clients
|
|
105
151
|
```
|
|
106
152
|
|
|
107
153
|
**Using with ngrok:**
|
|
@@ -119,7 +165,7 @@ ngrok http 3000
|
|
|
119
165
|
|
|
120
166
|
**Security note:** Anyone with your ngrok URL can access your Anki, so keep that URL private!
|
|
121
167
|
|
|
122
|
-
### Option
|
|
168
|
+
### Option 4: Manual Installation from Source (Local Mode)
|
|
123
169
|
|
|
124
170
|
For development or advanced usage:
|
|
125
171
|
|
|
@@ -299,7 +345,7 @@ This command will:
|
|
|
299
345
|
3. Build the TypeScript project
|
|
300
346
|
4. Package `dist/` and `node_modules/` into an `.mcpb` file
|
|
301
347
|
|
|
302
|
-
The output file will be named `anki-mcp-
|
|
348
|
+
The output file will be named based on the current version (e.g., `anki-mcp-http-0.5.0.mcpb`) and can be distributed for one-click installation.
|
|
303
349
|
|
|
304
350
|
#### What Gets Bundled
|
|
305
351
|
|
|
@@ -555,7 +601,7 @@ This project follows [Semantic Versioning](https://semver.org/) with a pre-1.0 d
|
|
|
555
601
|
- Will be released when the API is stable and tested
|
|
556
602
|
- Breaking changes will require major version bumps (2.0.0, etc.)
|
|
557
603
|
|
|
558
|
-
**Current Status**: `0.
|
|
604
|
+
**Current Status**: `0.6.0` - Active beta development. New features include the `twenty_rules` prompt for evidence-based flashcard creation, media file management, and improved prompt system. APIs may change based on feedback and testing.
|
|
559
605
|
|
|
560
606
|
## Similar Projects
|
|
561
607
|
|
package/bin/ankimcp.js
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// Check if --stdio flag is present
|
|
4
|
+
const isStdioMode = process.argv.includes('--stdio');
|
|
5
|
+
|
|
6
|
+
if (isStdioMode) {
|
|
7
|
+
// STDIO mode - for MCP clients like Cursor, Cline, Zed, etc.
|
|
8
|
+
require('../dist/main-stdio.js');
|
|
9
|
+
} else {
|
|
10
|
+
// HTTP mode (default) - for web-based AI assistants
|
|
11
|
+
require('../dist/main-http.js');
|
|
12
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -28,19 +28,37 @@ function parseCliArgs() {
|
|
|
28
28
|
const program = new commander_1.Command();
|
|
29
29
|
program
|
|
30
30
|
.name('ankimcp')
|
|
31
|
-
.description('AnkiMCP
|
|
31
|
+
.description('AnkiMCP Server - Model Context Protocol server for Anki')
|
|
32
32
|
.version(getVersion())
|
|
33
|
-
.option('
|
|
34
|
-
.option('-
|
|
33
|
+
.option('--stdio', 'Run in STDIO mode (for MCP clients like Cursor, Cline, Zed)')
|
|
34
|
+
.option('-p, --port <number>', 'Port to listen on (HTTP mode)', '3000')
|
|
35
|
+
.option('-h, --host <address>', 'Host to bind to (HTTP mode)', '127.0.0.1')
|
|
35
36
|
.option('-a, --anki-connect <url>', 'AnkiConnect URL', 'http://localhost:8765')
|
|
36
37
|
.addHelpText('after', `
|
|
37
|
-
|
|
38
|
+
Transport Modes:
|
|
39
|
+
HTTP Mode (default): For web-based AI assistants (ChatGPT, Claude.ai)
|
|
40
|
+
STDIO Mode: For desktop MCP clients (Cursor, Cline, Zed)
|
|
41
|
+
|
|
42
|
+
Examples - HTTP Mode:
|
|
38
43
|
$ ankimcp # Use defaults
|
|
39
44
|
$ ankimcp --port 8080 # Custom port
|
|
40
45
|
$ ankimcp --host 0.0.0.0 --port 3000 # Listen on all interfaces
|
|
41
46
|
$ ankimcp --anki-connect http://localhost:8765
|
|
42
47
|
|
|
43
|
-
|
|
48
|
+
Examples - STDIO Mode:
|
|
49
|
+
$ ankimcp --stdio # For use with npx in MCP clients
|
|
50
|
+
|
|
51
|
+
# MCP client configuration (Cursor, Cline, Zed, etc.):
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"anki-mcp": {
|
|
55
|
+
"command": "npx",
|
|
56
|
+
"args": ["-y", "anki-mcp-http", "--stdio"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Usage with ngrok (HTTP mode only):
|
|
44
62
|
1. Start ankimcp in one terminal
|
|
45
63
|
2. In another terminal: ngrok http 3000
|
|
46
64
|
3. Share the ngrok URL with your AI assistant
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;AAyBA,0CAEC;AAED,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;AAyBA,0CAEC;AAED,oCA4DC;AAED,oDA0BC;AArHD,yCAAoC;AACpC,2BAAkC;AAClC,+BAA4B;AAC5B,sEAA6C;AAQ7C,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CACf,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IACrD,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,cAAc,EAAE,CAAC,OAAO,CAAC;AAClC,CAAC;AAED,SAAgB,eAAe;IAC7B,IAAA,yBAAc,EAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AACrD,CAAC;AAED,SAAgB,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,OAAO,CAAC,UAAU,EAAE,CAAC;SACrB,MAAM,CACL,SAAS,EACT,6DAA6D,CAC9D;SACA,MAAM,CAAC,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,CAAC;SACtE,MAAM,CAAC,sBAAsB,EAAE,6BAA6B,EAAE,WAAW,CAAC;SAC1E,MAAM,CACL,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,CACxB;SACA,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BL,CACI,CAAC;IAEJ,OAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAc,CAAC;IAE3C,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC3C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAAC,OAAmB;IACtD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,wBAAwB,OAAO,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAE1F,OAAO,CAAC,GAAG,CAAC;;GAEX,WAAW;;;+BAGiB,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;wBACnC,OAAO,CAAC,WAAW;;;0BAGjB,OAAO,CAAC,IAAI;0BACZ,OAAO,CAAC,IAAI;0BACZ,OAAO,CAAC,WAAW;;;;uCAIN,OAAO,CAAC,IAAI;;;;CAIlD,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -21,6 +21,7 @@ export { UpdateNoteFieldsTool } from './tools/update-note-fields.tool';
|
|
|
21
21
|
export { DeleteNotesTool } from './tools/delete-notes.tool';
|
|
22
22
|
export { MediaActionsTool } from './tools/mediaActions';
|
|
23
23
|
export { ReviewSessionPrompt } from './prompts/review-session.prompt';
|
|
24
|
+
export { TwentyRulesPrompt } from './prompts/twenty-rules.prompt';
|
|
24
25
|
export { SystemInfoResource } from './resources/system-info.resource';
|
|
25
26
|
import { DynamicModule, Provider } from '@nestjs/common';
|
|
26
27
|
export interface McpPrimitivesAnkiEssentialModuleOptions {
|
|
@@ -21,7 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
};
|
|
22
22
|
var McpPrimitivesAnkiEssentialModule_1;
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.McpPrimitivesAnkiEssentialModule = exports.SystemInfoResource = exports.ReviewSessionPrompt = exports.MediaActionsTool = exports.DeleteNotesTool = exports.UpdateNoteFieldsTool = exports.NotesInfoTool = exports.FindNotesTool = exports.AddNoteTool = exports.UpdateModelStylingTool = exports.CreateModelTool = exports.ModelStylingTool = exports.ModelFieldNamesTool = exports.ModelNamesTool = exports.RateCardTool = exports.PresentCardTool = exports.GetDueCardsTool = exports.CreateDeckTool = exports.ListDecksTool = exports.SyncTool = exports.AnkiConnectError = exports.AnkiConnectClient = exports.ANKI_CONFIG = void 0;
|
|
24
|
+
exports.McpPrimitivesAnkiEssentialModule = exports.SystemInfoResource = exports.TwentyRulesPrompt = exports.ReviewSessionPrompt = exports.MediaActionsTool = exports.DeleteNotesTool = exports.UpdateNoteFieldsTool = exports.NotesInfoTool = exports.FindNotesTool = exports.AddNoteTool = exports.UpdateModelStylingTool = exports.CreateModelTool = exports.ModelStylingTool = exports.ModelFieldNamesTool = exports.ModelNamesTool = exports.RateCardTool = exports.PresentCardTool = exports.GetDueCardsTool = exports.CreateDeckTool = exports.ListDecksTool = exports.SyncTool = exports.AnkiConnectError = exports.AnkiConnectClient = exports.ANKI_CONFIG = void 0;
|
|
25
25
|
var anki_config_interface_1 = require("../../config/anki-config.interface");
|
|
26
26
|
Object.defineProperty(exports, "ANKI_CONFIG", { enumerable: true, get: function () { return anki_config_interface_1.ANKI_CONFIG; } });
|
|
27
27
|
__exportStar(require("../../types/anki.types"), exports);
|
|
@@ -65,6 +65,8 @@ var mediaActions_1 = require("./tools/mediaActions");
|
|
|
65
65
|
Object.defineProperty(exports, "MediaActionsTool", { enumerable: true, get: function () { return mediaActions_1.MediaActionsTool; } });
|
|
66
66
|
var review_session_prompt_1 = require("./prompts/review-session.prompt");
|
|
67
67
|
Object.defineProperty(exports, "ReviewSessionPrompt", { enumerable: true, get: function () { return review_session_prompt_1.ReviewSessionPrompt; } });
|
|
68
|
+
var twenty_rules_prompt_1 = require("./prompts/twenty-rules.prompt");
|
|
69
|
+
Object.defineProperty(exports, "TwentyRulesPrompt", { enumerable: true, get: function () { return twenty_rules_prompt_1.TwentyRulesPrompt; } });
|
|
68
70
|
var system_info_resource_1 = require("./resources/system-info.resource");
|
|
69
71
|
Object.defineProperty(exports, "SystemInfoResource", { enumerable: true, get: function () { return system_info_resource_1.SystemInfoResource; } });
|
|
70
72
|
const common_1 = require("@nestjs/common");
|
|
@@ -87,6 +89,7 @@ const update_note_fields_tool_2 = require("./tools/update-note-fields.tool");
|
|
|
87
89
|
const delete_notes_tool_2 = require("./tools/delete-notes.tool");
|
|
88
90
|
const mediaActions_2 = require("./tools/mediaActions");
|
|
89
91
|
const review_session_prompt_2 = require("./prompts/review-session.prompt");
|
|
92
|
+
const twenty_rules_prompt_2 = require("./prompts/twenty-rules.prompt");
|
|
90
93
|
const system_info_resource_2 = require("./resources/system-info.resource");
|
|
91
94
|
const MCP_PRIMITIVES = [
|
|
92
95
|
anki_connect_client_2.AnkiConnectClient,
|
|
@@ -108,6 +111,7 @@ const MCP_PRIMITIVES = [
|
|
|
108
111
|
delete_notes_tool_2.DeleteNotesTool,
|
|
109
112
|
mediaActions_2.MediaActionsTool,
|
|
110
113
|
review_session_prompt_2.ReviewSessionPrompt,
|
|
114
|
+
twenty_rules_prompt_2.TwentyRulesPrompt,
|
|
111
115
|
system_info_resource_2.SystemInfoResource,
|
|
112
116
|
];
|
|
113
117
|
let McpPrimitivesAnkiEssentialModule = McpPrimitivesAnkiEssentialModule_1 = class McpPrimitivesAnkiEssentialModule {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/primitives/essential/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,4EAAiE;AAAxD,oHAAA,WAAW,OAAA;AAIpB,yDAAuC;AAGvC,yDAAuC;AAGvC,yEAAwF;AAA/E,wHAAA,iBAAiB,OAAA;AAAE,uHAAA,gBAAgB,OAAA;AAG5C,+CAA6C;AAApC,qGAAA,QAAQ,OAAA;AACjB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,6DAA0D;AAAjD,kHAAA,cAAc,OAAA;AACvB,iEAA6D;AAApD,qHAAA,eAAe,OAAA;AACxB,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,yDAAsD;AAA7C,8GAAA,YAAY,OAAA;AACrB,6DAA0D;AAAjD,kHAAA,cAAc,OAAA;AACvB,yEAAqE;AAA5D,6HAAA,mBAAmB,OAAA;AAC5B,iEAA8D;AAArD,sHAAA,gBAAgB,OAAA;AACzB,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,+EAA2E;AAAlE,mIAAA,sBAAsB,OAAA;AAC/B,uDAAoD;AAA3C,4GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,2EAAuE;AAA9D,+HAAA,oBAAoB,OAAA;AAC7B,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,qDAAwD;AAA/C,gHAAA,gBAAgB,OAAA;AAGzB,yEAAsE;AAA7D,4HAAA,mBAAmB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/primitives/essential/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,4EAAiE;AAAxD,oHAAA,WAAW,OAAA;AAIpB,yDAAuC;AAGvC,yDAAuC;AAGvC,yEAAwF;AAA/E,wHAAA,iBAAiB,OAAA;AAAE,uHAAA,gBAAgB,OAAA;AAG5C,+CAA6C;AAApC,qGAAA,QAAQ,OAAA;AACjB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,6DAA0D;AAAjD,kHAAA,cAAc,OAAA;AACvB,iEAA6D;AAApD,qHAAA,eAAe,OAAA;AACxB,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,yDAAsD;AAA7C,8GAAA,YAAY,OAAA;AACrB,6DAA0D;AAAjD,kHAAA,cAAc,OAAA;AACvB,yEAAqE;AAA5D,6HAAA,mBAAmB,OAAA;AAC5B,iEAA8D;AAArD,sHAAA,gBAAgB,OAAA;AACzB,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,+EAA2E;AAAlE,mIAAA,sBAAsB,OAAA;AAC/B,uDAAoD;AAA3C,4GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,2EAAuE;AAA9D,+HAAA,oBAAoB,OAAA;AAC7B,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,qDAAwD;AAA/C,gHAAA,gBAAgB,OAAA;AAGzB,yEAAsE;AAA7D,4HAAA,mBAAmB,OAAA;AAC5B,qEAAkE;AAAzD,wHAAA,iBAAiB,OAAA;AAG1B,yEAAsE;AAA7D,0HAAA,kBAAkB,OAAA;AAG3B,2CAAiE;AACjE,2EAAsE;AACtE,iDAA6C;AAC7C,6DAAwD;AACxD,+DAA0D;AAC1D,mEAA6D;AAC7D,iEAA4D;AAC5D,2DAAsD;AACtD,+DAA0D;AAC1D,2EAAqE;AACrE,mEAA8D;AAC9D,iEAA4D;AAC5D,iFAA2E;AAC3E,yDAAoD;AACpD,6DAAwD;AACxD,6DAAwD;AACxD,6EAAuE;AACvE,iEAA4D;AAC5D,uDAAwD;AACxD,2EAAsE;AACtE,uEAAkE;AAClE,2EAAsE;AAEtE,MAAM,cAAc,GAAG;IAErB,uCAAiB;IAEjB,oBAAQ;IACR,+BAAa;IACb,iCAAc;IACd,oCAAe;IACf,mCAAe;IACf,6BAAY;IACZ,iCAAc;IACd,4CAAmB;IACnB,qCAAgB;IAChB,mCAAe;IACf,kDAAsB;IACtB,2BAAW;IACX,+BAAa;IACb,+BAAa;IACb,8CAAoB;IACpB,mCAAe;IACf,+BAAgB;IAEhB,2CAAmB;IACnB,uCAAiB;IAEjB,yCAAkB;CACnB,CAAC;AAOK,IAAM,gCAAgC,wCAAtC,MAAM,gCAAgC;IAC3C,MAAM,CAAC,OAAO,CAAC,OAAgD;QAC7D,OAAO;YACL,MAAM,EAAE,kCAAgC;YACxC,SAAS,EAAE;gBACT,OAAO,CAAC,kBAAkB;gBAC1B,GAAG,cAAc;aAClB;YACD,OAAO,EAAE,cAAc;SACxB,CAAC;IACJ,CAAC;CACF,CAAA;AAXY,4EAAgC;2CAAhC,gCAAgC;IAD5C,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,gCAAgC,CAW5C"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Description
|
|
2
|
+
|
|
3
|
+
Twenty rules of formulating knowledge for effective Anki flashcard creation based on Dr. Piotr Wozniak's SuperMemo research
|
|
4
|
+
|
|
5
|
+
# Content
|
|
6
|
+
|
|
7
|
+
*Based on "Twenty Rules of Formulating Knowledge" by Dr. Piotr Wozniak: https://www.supermemo.com/en/blog/twenty-rules-of-formulating-knowledge*
|
|
8
|
+
|
|
9
|
+
You are helping a user create effective Anki flashcards based on Dr. Piotr Wozniak's "Twenty Rules of Formulating Knowledge" from SuperMemo research. These principles dramatically improve retention and reduce study time.
|
|
10
|
+
|
|
11
|
+
## Core Principles
|
|
12
|
+
|
|
13
|
+
### 1. Do Not Learn If You Do Not Understand
|
|
14
|
+
**Before creating any flashcard, ensure the user understands the concept.**
|
|
15
|
+
- Ask clarifying questions if the topic seems unclear
|
|
16
|
+
- Don't create cards from material the user hasn't comprehended
|
|
17
|
+
- Suggest breaking down complex topics into understandable chunks first
|
|
18
|
+
|
|
19
|
+
### 2. Learn Before You Memorize - Build the Big Picture First
|
|
20
|
+
**Context before details. Overview before memorization.**
|
|
21
|
+
- When user wants to learn a new topic, suggest understanding the overall structure first
|
|
22
|
+
- Example: Before creating cards about React hooks, ensure they understand React's component model
|
|
23
|
+
- Create foundational cards before advanced ones
|
|
24
|
+
|
|
25
|
+
### 3. Build Upon the Basics
|
|
26
|
+
**Never skip fundamentals. Simple before complex.**
|
|
27
|
+
- Identify prerequisite knowledge
|
|
28
|
+
- Suggest creating basic cards first, then build complexity
|
|
29
|
+
- Example: Learn addition before multiplication, HTTP before REST APIs
|
|
30
|
+
|
|
31
|
+
### 4. Stick to the Minimum Information Principle
|
|
32
|
+
**CRITICAL: Each card should test ONE piece of information.**
|
|
33
|
+
- ❌ BAD: "What are the three main features of React and how do they work?"
|
|
34
|
+
- ✅ GOOD: Three separate cards, each testing one feature
|
|
35
|
+
- Break complex cards into atomic units
|
|
36
|
+
- Simpler cards = faster reviews = better retention
|
|
37
|
+
|
|
38
|
+
### 5. Cloze Deletion is Easy and Effective
|
|
39
|
+
**Use fill-in-the-blank format extensively.**
|
|
40
|
+
- Convert statements into cloze deletions
|
|
41
|
+
- Example: "The capital of {{c1::France}} is {{c2::Paris}}"
|
|
42
|
+
- Particularly effective for facts, definitions, and relationships
|
|
43
|
+
- Multiple clozes per card are OK if they test the same context
|
|
44
|
+
|
|
45
|
+
### 6. Use Imagery - Visual Memory is Powerful
|
|
46
|
+
**Add images whenever possible.**
|
|
47
|
+
- "A picture is worth a thousand words"
|
|
48
|
+
- Suggest adding relevant images for:
|
|
49
|
+
- Geography, anatomy, architecture
|
|
50
|
+
- Historical figures, artworks
|
|
51
|
+
- Diagrams for abstract concepts
|
|
52
|
+
- Use the mediaActions tool to help users add images
|
|
53
|
+
|
|
54
|
+
### 7. Use Mnemonic Techniques
|
|
55
|
+
**Memory aids make retention easier.**
|
|
56
|
+
- Suggest mnemonics for difficult items
|
|
57
|
+
- Use acronyms (e.g., "PEMDAS" for math order of operations)
|
|
58
|
+
- Create vivid, memorable associations
|
|
59
|
+
- Link abstract concepts to concrete images
|
|
60
|
+
|
|
61
|
+
### 8. Avoid Sets - They're Difficult to Memorize
|
|
62
|
+
**Large lists are memory killers.**
|
|
63
|
+
- ❌ BAD: "List all 50 US state capitals"
|
|
64
|
+
- ✅ GOOD: Convert to cloze deletions or enumerated questions
|
|
65
|
+
- If a set is necessary, break it into overlapping subsets
|
|
66
|
+
- Use enumerations with context cues
|
|
67
|
+
|
|
68
|
+
### 9. Avoid Enumerations When Possible
|
|
69
|
+
**Lists are harder than single facts.**
|
|
70
|
+
- Instead of "What are the 7 principles of X?", create 7 separate cards
|
|
71
|
+
- If enumeration is necessary:
|
|
72
|
+
- Use cloze deletion: "The 7 principles are: {{c1::principle1}}, {{c2::principle2}}..."
|
|
73
|
+
- Add context and memory aids
|
|
74
|
+
- Keep lists short (max 5-7 items)
|
|
75
|
+
|
|
76
|
+
### 10. Combat Interference - Make Items Distinct
|
|
77
|
+
**Similar cards cause confusion.**
|
|
78
|
+
- Avoid creating nearly identical cards
|
|
79
|
+
- Make distinctions explicit
|
|
80
|
+
- Add context to differentiate similar concepts
|
|
81
|
+
- Example for similar countries:
|
|
82
|
+
- ❌ "Capital of Guyana?" and "Capital of Suriname?" (too similar)
|
|
83
|
+
- ✅ Add distinguishing features: "Capital of Guyana (only English-speaking country in South America)?"
|
|
84
|
+
|
|
85
|
+
### 11. Optimize Wording - Keep It Simple and Clear
|
|
86
|
+
**Shorter, simpler wording = faster reviews.**
|
|
87
|
+
- Remove unnecessary words
|
|
88
|
+
- Use active voice
|
|
89
|
+
- Make questions unambiguous
|
|
90
|
+
- ❌ "In the context of programming, when considering the various paradigms, what would you say is the main characteristic that defines the functional approach?"
|
|
91
|
+
- ✅ "Functional programming's main characteristic?"
|
|
92
|
+
|
|
93
|
+
### 12. Refer to Other Memories - Build Connections
|
|
94
|
+
**Connect new knowledge to existing knowledge.**
|
|
95
|
+
- Reference previously learned concepts
|
|
96
|
+
- Build knowledge networks
|
|
97
|
+
- Example: "Like REST but for GraphQL: {{c1::single endpoint}}"
|
|
98
|
+
- Use analogies to familiar concepts
|
|
99
|
+
|
|
100
|
+
### 13. Personalize and Provide Examples
|
|
101
|
+
**Personal context dramatically improves retention.**
|
|
102
|
+
- Link to user's experiences
|
|
103
|
+
- Use examples from their projects, life, or interests
|
|
104
|
+
- ❌ Generic: "TypeScript interface definition?"
|
|
105
|
+
- ✅ Personal: "TypeScript interface (like the User type in your project)?"
|
|
106
|
+
|
|
107
|
+
### 14. Rely on Emotional States
|
|
108
|
+
**Emotion enhances memory.**
|
|
109
|
+
- Use vivid, emotionally charged examples when appropriate
|
|
110
|
+
- Link to memorable events or stories
|
|
111
|
+
- Make boring facts interesting with context
|
|
112
|
+
- Example: Instead of dry historical dates, add dramatic context
|
|
113
|
+
|
|
114
|
+
### 15. Context Cues Simplify Wording
|
|
115
|
+
**Categories and prefixes reduce cognitive load.**
|
|
116
|
+
- Add subject prefixes: "bio:", "hist:", "prog:"
|
|
117
|
+
- Use tags effectively
|
|
118
|
+
- Group related cards in decks
|
|
119
|
+
- Example: "js: Array method for filtering?" (context cue: "js:")
|
|
120
|
+
|
|
121
|
+
### 16. Redundancy Can Be Beneficial
|
|
122
|
+
**Some repetition from different angles helps.**
|
|
123
|
+
- Create multiple cards for critical concepts from different angles
|
|
124
|
+
- Test the same fact in different contexts
|
|
125
|
+
- Balance with "don't overdo it"
|
|
126
|
+
|
|
127
|
+
### 17. Provide Sources and References
|
|
128
|
+
**Context helps understanding and future reference.**
|
|
129
|
+
- Add source information in card metadata or extra field
|
|
130
|
+
- Link to documentation, books, or articles
|
|
131
|
+
- Helps when reviewing old cards
|
|
132
|
+
|
|
133
|
+
### 18. Prioritize - Learn What Matters Most
|
|
134
|
+
**Not everything deserves a flashcard.**
|
|
135
|
+
- Focus on applicable, useful knowledge
|
|
136
|
+
- Ask: "Will I actually need to recall this?"
|
|
137
|
+
- Quality over quantity
|
|
138
|
+
|
|
139
|
+
## Workflow for Creating Cards
|
|
140
|
+
|
|
141
|
+
1. **Understand First**: Verify user understands the concept
|
|
142
|
+
2. **Build Context**: Ensure foundational knowledge exists
|
|
143
|
+
3. **Apply Minimum Information**: Break into atomic facts
|
|
144
|
+
4. **Choose Format**: Prefer cloze deletion for facts, Q&A for concepts
|
|
145
|
+
5. **Optimize Wording**: Make it clear, concise, unambiguous
|
|
146
|
+
6. **Add Richness**: Images, mnemonics, personal connections
|
|
147
|
+
7. **Review**: Check for interference with existing cards
|
|
148
|
+
|
|
149
|
+
## When User Asks to Create Cards
|
|
150
|
+
|
|
151
|
+
1. Ask about their understanding of the topic
|
|
152
|
+
2. Suggest the number and type of cards (don't just create them)
|
|
153
|
+
3. Show examples of proposed cards
|
|
154
|
+
4. Wait for approval before creating
|
|
155
|
+
5. Apply these rules to make cards effective
|
|
156
|
+
6. Use addNote tool only after user confirms
|
|
157
|
+
|
|
158
|
+
## Example Transformations
|
|
159
|
+
|
|
160
|
+
### Example 1: Complex → Simple
|
|
161
|
+
❌ **Bad Card**:
|
|
162
|
+
Q: "What are the main differences between REST and GraphQL APIs and when would you use each?"
|
|
163
|
+
A: [Long paragraph explaining both]
|
|
164
|
+
|
|
165
|
+
✅ **Good Cards** (4 separate cards):
|
|
166
|
+
1. "REST uses {{c1::multiple endpoints}}, GraphQL uses {{c2::single endpoint}}"
|
|
167
|
+
2. "GraphQL advantage over REST: {{c1::client specifies exact data needed}}"
|
|
168
|
+
3. "REST advantage over GraphQL: {{c1::simpler caching}} and {{c2::better tooling support}}"
|
|
169
|
+
4. "Use GraphQL when: {{c1::client needs flexible queries}} and {{c2::reducing over-fetching matters}}"
|
|
170
|
+
|
|
171
|
+
### Example 2: Generic → Personal
|
|
172
|
+
❌ **Bad Card**:
|
|
173
|
+
Q: "What is a closure in JavaScript?"
|
|
174
|
+
A: "A function that has access to outer function variables"
|
|
175
|
+
|
|
176
|
+
✅ **Good Card**:
|
|
177
|
+
Q: "js: Closure definition (like in your React hooks code)?"
|
|
178
|
+
A: "Function that remembers variables from its outer scope even after outer function returns"
|
|
179
|
+
|
|
180
|
+
### Example 3: Adding Visual Memory
|
|
181
|
+
❌ **Text Only**:
|
|
182
|
+
Q: "Structure of the human heart?"
|
|
183
|
+
A: [Text description]
|
|
184
|
+
|
|
185
|
+
✅ **With Image**:
|
|
186
|
+
Q: [Image of heart with blank labels]
|
|
187
|
+
A: [Same image with labels visible]
|
|
188
|
+
(Use mediaActions to help user add the image)
|
|
189
|
+
|
|
190
|
+
## Remember
|
|
191
|
+
|
|
192
|
+
**Quality > Quantity**: Five well-formed cards beat twenty poorly made ones.
|
|
193
|
+
**Atomic Knowledge**: One fact per card, always.
|
|
194
|
+
**User Context**: Personalize everything you can.
|
|
195
|
+
**Understanding First**: Never create cards from material the user doesn't understand.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.TwentyRulesPrompt = void 0;
|
|
46
|
+
const common_1 = require("@nestjs/common");
|
|
47
|
+
const mcp_nest_1 = require("@rekog/mcp-nest");
|
|
48
|
+
const zod_1 = require("zod");
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
const markdown_utils_1 = require("../../../../utils/markdown.utils");
|
|
52
|
+
const PROMPT_SECTIONS = (() => {
|
|
53
|
+
const markdownPath = path.join(__dirname, 'content.md');
|
|
54
|
+
const markdown = fs.readFileSync(markdownPath, 'utf-8');
|
|
55
|
+
return (0, markdown_utils_1.parseMarkdownSections)(markdown);
|
|
56
|
+
})();
|
|
57
|
+
let TwentyRulesPrompt = class TwentyRulesPrompt {
|
|
58
|
+
getTwentyRulesPrompt() {
|
|
59
|
+
return {
|
|
60
|
+
description: PROMPT_SECTIONS.Description || 'Twenty rules of formulating knowledge for effective Anki flashcard creation',
|
|
61
|
+
messages: [
|
|
62
|
+
{
|
|
63
|
+
role: 'user',
|
|
64
|
+
content: {
|
|
65
|
+
type: 'text',
|
|
66
|
+
text: PROMPT_SECTIONS.Content || '',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
exports.TwentyRulesPrompt = TwentyRulesPrompt;
|
|
74
|
+
__decorate([
|
|
75
|
+
(0, mcp_nest_1.Prompt)({
|
|
76
|
+
name: 'twenty_rules',
|
|
77
|
+
description: PROMPT_SECTIONS.Description || 'Twenty rules of formulating knowledge for effective Anki flashcard creation',
|
|
78
|
+
parameters: zod_1.z.object({}),
|
|
79
|
+
}),
|
|
80
|
+
__metadata("design:type", Function),
|
|
81
|
+
__metadata("design:paramtypes", []),
|
|
82
|
+
__metadata("design:returntype", void 0)
|
|
83
|
+
], TwentyRulesPrompt.prototype, "getTwentyRulesPrompt", null);
|
|
84
|
+
exports.TwentyRulesPrompt = TwentyRulesPrompt = __decorate([
|
|
85
|
+
(0, common_1.Injectable)({ scope: common_1.Scope.REQUEST })
|
|
86
|
+
], TwentyRulesPrompt);
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/mcp/primitives/essential/prompts/twenty-rules.prompt/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAmD;AACnD,8CAAyC;AACzC,6BAAwB;AACxB,uCAAyB;AACzB,2CAA6B;AAC7B,qEAAmE;AAInE,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE;IAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACxD,OAAO,IAAA,sCAAqB,EAAC,QAAQ,CAAC,CAAC;AACzC,CAAC,CAAC,EAAE,CAAC;AAGE,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAM5B,oBAAoB;QAClB,OAAO;YACL,WAAW,EAAE,eAAe,CAAC,WAAW,IAAI,6EAA6E;YACzH,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,eAAe,CAAC,OAAO,IAAI,EAAE;qBACpC;iBACF;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AApBY,8CAAiB;AAM5B;IALC,IAAA,iBAAM,EAAC;QACN,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,eAAe,CAAC,WAAW,IAAI,6EAA6E;QACzH,UAAU,EAAE,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KACzB,CAAC;;;;6DAcD;4BAnBU,iBAAiB;IAD7B,IAAA,mBAAU,EAAC,EAAE,KAAK,EAAE,cAAK,CAAC,OAAO,EAAE,CAAC;GACxB,iBAAiB,CAoB7B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseMarkdownSections = parseMarkdownSections;
|
|
7
|
+
const unified_1 = require("unified");
|
|
8
|
+
const remark_parse_1 = __importDefault(require("remark-parse"));
|
|
9
|
+
const unist_util_visit_1 = require("unist-util-visit");
|
|
10
|
+
function nodeToString(node) {
|
|
11
|
+
if (node.type === 'text') {
|
|
12
|
+
return node.value;
|
|
13
|
+
}
|
|
14
|
+
if (node.type === 'inlineCode') {
|
|
15
|
+
return `\`${node.value}\``;
|
|
16
|
+
}
|
|
17
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
18
|
+
return node.children.map((child) => nodeToString(child)).join('');
|
|
19
|
+
}
|
|
20
|
+
if ('value' in node && typeof node.value === 'string') {
|
|
21
|
+
return node.value;
|
|
22
|
+
}
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
function extractHeadingText(node) {
|
|
26
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
27
|
+
return node.children.map((child) => nodeToString(child)).join('');
|
|
28
|
+
}
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
function parseMarkdownSections(markdown) {
|
|
32
|
+
const tree = (0, unified_1.unified)().use(remark_parse_1.default).parse(markdown);
|
|
33
|
+
const sections = {};
|
|
34
|
+
let currentHeading = null;
|
|
35
|
+
let currentContent = [];
|
|
36
|
+
(0, unist_util_visit_1.visit)(tree, (node) => {
|
|
37
|
+
if (node.type === 'heading' && node.depth === 1) {
|
|
38
|
+
if (currentHeading) {
|
|
39
|
+
sections[currentHeading] = currentContent.join('\n').trim();
|
|
40
|
+
}
|
|
41
|
+
currentHeading = extractHeadingText(node);
|
|
42
|
+
currentContent = [];
|
|
43
|
+
}
|
|
44
|
+
else if (currentHeading) {
|
|
45
|
+
const content = nodeToString(node);
|
|
46
|
+
if (content.trim()) {
|
|
47
|
+
currentContent.push(content.trim());
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
if (currentHeading) {
|
|
52
|
+
sections[currentHeading] = currentContent.join('\n').trim();
|
|
53
|
+
}
|
|
54
|
+
return sections;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=markdown.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.utils.js","sourceRoot":"","sources":["../../../src/mcp/utils/markdown.utils.ts"],"names":[],"mappings":";;;;;AAkEA,sDAgCC;AAlGD,qCAAkC;AAClC,gEAAuC;AACvC,uDAAyC;AAezC,SAAS,YAAY,CAAC,IAAiB;IACrC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC/B,OAAO,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;IAC7B,CAAC;IACD,IAAI,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAKD,SAAS,kBAAkB,CAAC,IAAiB;IAC3C,IAAI,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAyBD,SAAgB,qBAAqB,CAAC,QAAgB;IACpD,MAAM,IAAI,GAAG,IAAA,iBAAO,GAAE,CAAC,GAAG,CAAC,sBAAW,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAS,CAAC;IAChE,MAAM,QAAQ,GAAqB,EAAE,CAAC;IAEtC,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,cAAc,GAAa,EAAE,CAAC;IAElC,IAAA,wBAAK,EAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;QACnB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YAEhD,IAAI,cAAc,EAAE,CAAC;gBACnB,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9D,CAAC;YAGD,cAAc,GAAG,kBAAkB,CAAC,IAAmB,CAAC,CAAC;YACzD,cAAc,GAAG,EAAE,CAAC;QACtB,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAE1B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAmB,CAAC,CAAC;YAClD,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBACnB,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAGH,IAAI,cAAc,EAAE,CAAC;QACnB,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|