anki-mcp-http 0.7.1 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/LICENSE +5 -19
  2. package/README.md +152 -35
  3. package/bin/ankimcp.js +0 -0
  4. package/dist/anki-config.service.d.ts +2 -2
  5. package/dist/anki-config.service.js +4 -4
  6. package/dist/app.module.d.ts +1 -1
  7. package/dist/app.module.js +7 -7
  8. package/dist/app.module.js.map +1 -1
  9. package/dist/bootstrap.d.ts +1 -1
  10. package/dist/bootstrap.js +4 -4
  11. package/dist/cli.d.ts +2 -1
  12. package/dist/cli.js +41 -27
  13. package/dist/cli.js.map +1 -1
  14. package/dist/http/guards/origin-validation.guard.d.ts +1 -1
  15. package/dist/http/guards/origin-validation.guard.js +5 -5
  16. package/dist/main-http.js +16 -2
  17. package/dist/main-http.js.map +1 -1
  18. package/dist/main-stdio.js +2 -2
  19. package/dist/mcp/clients/__mocks__/anki-connect.client.js +1 -1
  20. package/dist/mcp/clients/anki-connect.client.d.ts +1 -1
  21. package/dist/mcp/clients/anki-connect.client.js +7 -7
  22. package/dist/mcp/config/anki-config.interface.js +1 -1
  23. package/dist/mcp/primitives/essential/index.d.ts +26 -26
  24. package/dist/mcp/primitives/essential/index.js +1 -4
  25. package/dist/mcp/primitives/essential/index.js.map +1 -1
  26. package/dist/mcp/primitives/essential/prompts/review-session.prompt.js +5 -5
  27. package/dist/mcp/primitives/essential/prompts/review-session.prompt.js.map +1 -1
  28. package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js +10 -8
  29. package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js.map +1 -1
  30. package/dist/mcp/primitives/essential/resources/system-info.resource.js +12 -12
  31. package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +3 -3
  32. package/dist/mcp/primitives/essential/tools/add-note.tool.js +27 -30
  33. package/dist/mcp/primitives/essential/tools/add-note.tool.js.map +1 -1
  34. package/dist/mcp/primitives/essential/tools/create-deck.tool.d.ts +2 -2
  35. package/dist/mcp/primitives/essential/tools/create-deck.tool.js +15 -15
  36. package/dist/mcp/primitives/essential/tools/create-deck.tool.js.map +1 -1
  37. package/dist/mcp/primitives/essential/tools/create-model.tool.d.ts +3 -3
  38. package/dist/mcp/primitives/essential/tools/create-model.tool.js +20 -18
  39. package/dist/mcp/primitives/essential/tools/create-model.tool.js.map +1 -1
  40. package/dist/mcp/primitives/essential/tools/delete-notes.tool.d.ts +2 -2
  41. package/dist/mcp/primitives/essential/tools/delete-notes.tool.js +22 -22
  42. package/dist/mcp/primitives/essential/tools/delete-notes.tool.js.map +1 -1
  43. package/dist/mcp/primitives/essential/tools/find-notes.tool.d.ts +2 -2
  44. package/dist/mcp/primitives/essential/tools/find-notes.tool.js +14 -14
  45. package/dist/mcp/primitives/essential/tools/find-notes.tool.js.map +1 -1
  46. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.d.ts +2 -2
  47. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js +17 -15
  48. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js.map +1 -1
  49. package/dist/mcp/primitives/essential/tools/list-decks.tool.d.ts +2 -2
  50. package/dist/mcp/primitives/essential/tools/list-decks.tool.js +10 -10
  51. package/dist/mcp/primitives/essential/tools/list-decks.tool.js.map +1 -1
  52. package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.d.ts +1 -1
  53. package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js +3 -3
  54. package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.d.ts +1 -1
  55. package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js +1 -1
  56. package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js.map +1 -1
  57. package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.d.ts +1 -1
  58. package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js +3 -3
  59. package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.d.ts +1 -1
  60. package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js +7 -7
  61. package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js.map +1 -1
  62. package/dist/mcp/primitives/essential/tools/mediaActions/index.d.ts +5 -5
  63. package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.d.ts +3 -3
  64. package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js +23 -17
  65. package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js.map +1 -1
  66. package/dist/mcp/primitives/essential/tools/model-field-names.tool.d.ts +2 -2
  67. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +20 -17
  68. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -1
  69. package/dist/mcp/primitives/essential/tools/model-names.tool.d.ts +3 -3
  70. package/dist/mcp/primitives/essential/tools/model-names.tool.js +13 -11
  71. package/dist/mcp/primitives/essential/tools/model-names.tool.js.map +1 -1
  72. package/dist/mcp/primitives/essential/tools/model-styling.tool.d.ts +2 -2
  73. package/dist/mcp/primitives/essential/tools/model-styling.tool.js +11 -11
  74. package/dist/mcp/primitives/essential/tools/model-styling.tool.js.map +1 -1
  75. package/dist/mcp/primitives/essential/tools/notes-info.tool.d.ts +2 -2
  76. package/dist/mcp/primitives/essential/tools/notes-info.tool.js +19 -19
  77. package/dist/mcp/primitives/essential/tools/notes-info.tool.js.map +1 -1
  78. package/dist/mcp/primitives/essential/tools/present-card.tool.d.ts +2 -2
  79. package/dist/mcp/primitives/essential/tools/present-card.tool.js +11 -11
  80. package/dist/mcp/primitives/essential/tools/present-card.tool.js.map +1 -1
  81. package/dist/mcp/primitives/essential/tools/rate-card.tool.d.ts +2 -2
  82. package/dist/mcp/primitives/essential/tools/rate-card.tool.js +19 -14
  83. package/dist/mcp/primitives/essential/tools/rate-card.tool.js.map +1 -1
  84. package/dist/mcp/primitives/essential/tools/sync.tool.d.ts +3 -3
  85. package/dist/mcp/primitives/essential/tools/sync.tool.js +8 -8
  86. package/dist/mcp/primitives/essential/tools/sync.tool.js.map +1 -1
  87. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.d.ts +2 -2
  88. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js +19 -19
  89. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js.map +1 -1
  90. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.d.ts +3 -3
  91. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js +32 -32
  92. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js.map +1 -1
  93. package/dist/mcp/primitives/gui/index.d.ts +17 -17
  94. package/dist/mcp/primitives/gui/index.js.map +1 -1
  95. package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.d.ts +2 -2
  96. package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js +22 -22
  97. package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js.map +1 -1
  98. package/dist/mcp/primitives/gui/tools/gui-browse.tool.d.ts +3 -3
  99. package/dist/mcp/primitives/gui/tools/gui-browse.tool.js +15 -14
  100. package/dist/mcp/primitives/gui/tools/gui-browse.tool.js.map +1 -1
  101. package/dist/mcp/primitives/gui/tools/gui-current-card.tool.d.ts +3 -3
  102. package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js +13 -13
  103. package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js.map +1 -1
  104. package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.d.ts +3 -3
  105. package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js +12 -12
  106. package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js.map +1 -1
  107. package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.d.ts +2 -2
  108. package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js +15 -12
  109. package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js.map +1 -1
  110. package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.d.ts +2 -2
  111. package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js +13 -12
  112. package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js.map +1 -1
  113. package/dist/mcp/primitives/gui/tools/gui-select-card.tool.d.ts +2 -2
  114. package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js +18 -15
  115. package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js.map +1 -1
  116. package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.d.ts +3 -3
  117. package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js +15 -14
  118. package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js.map +1 -1
  119. package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.d.ts +3 -3
  120. package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js +15 -15
  121. package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js.map +1 -1
  122. package/dist/mcp/primitives/gui/tools/gui-show-question.tool.d.ts +3 -3
  123. package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js +15 -15
  124. package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js.map +1 -1
  125. package/dist/mcp/primitives/gui/tools/gui-undo.tool.d.ts +3 -3
  126. package/dist/mcp/primitives/gui/tools/gui-undo.tool.js +15 -15
  127. package/dist/mcp/primitives/gui/tools/gui-undo.tool.js.map +1 -1
  128. package/dist/mcp/types/anki.types.d.ts +2 -2
  129. package/dist/mcp/utils/anki.utils.d.ts +3 -3
  130. package/dist/mcp/utils/anki.utils.js +42 -38
  131. package/dist/mcp/utils/anki.utils.js.map +1 -1
  132. package/dist/mcp/utils/markdown.utils.js +16 -12
  133. package/dist/mcp/utils/markdown.utils.js.map +1 -1
  134. package/dist/mcp/utils/mcpb-workarounds.js +2 -2
  135. package/dist/mcp/utils/mcpb-workarounds.js.map +1 -1
  136. package/dist/services/ngrok.service.d.ts +15 -0
  137. package/dist/services/ngrok.service.js +120 -0
  138. package/dist/services/ngrok.service.js.map +1 -0
  139. package/dist/test-fixtures/mock-data.d.ts +2 -2
  140. package/dist/test-fixtures/mock-data.js +46 -46
  141. package/dist/test-fixtures/mock-data.js.map +1 -1
  142. package/dist/tsconfig.build.tsbuildinfo +1 -1
  143. package/package.json +12 -7
package/LICENSE CHANGED
@@ -1,21 +1,7 @@
1
- MIT License
1
+ Anki MCP Server is licensed under the GNU Affero General Public License,
2
+ version 3 or later.
2
3
 
3
- Copyright (c) 2025 Anatoly Tarnavsky
4
+ Copyright (C) 2025 Anatoly Tarnavsky
4
5
 
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.
6
+ For the full text of the AGPL-3.0 license, see:
7
+ https://www.gnu.org/licenses/agpl-3.0.txt
package/README.md CHANGED
@@ -1,4 +1,13 @@
1
- # Anki MCP Desktop
1
+ # Anki MCP Server
2
+
3
+ [![Tests](https://github.com/ankimcp/anki-mcp-server/actions/workflows/test.yml/badge.svg)](https://github.com/ankimcp/anki-mcp-server/actions/workflows/test.yml)
4
+ [![npm version](https://badge.fury.io/js/@ankimcp%2Fanki-mcp-server.svg)](https://www.npmjs.com/package/@ankimcp/anki-mcp-server)
5
+
6
+ <div align="center">
7
+ <img src="./docs/images/ankimcp.png" alt="Anki + MCP Integration" width="600" />
8
+
9
+ <p><strong>Seamlessly integrate <a href="https://apps.ankiweb.net">Anki</a> with AI assistants through the <a href="https://modelcontextprotocol.io">Model Context Protocol</a></strong></p>
10
+ </div>
2
11
 
3
12
  **Beta** - This project is in active development. APIs and features may change.
4
13
 
@@ -38,6 +47,13 @@ For comprehensive guides, real-world examples, and step-by-step tutorials on usi
38
47
  - `getMediaFilesNames` - List media files with optional pattern filtering
39
48
  - `deleteMediaFile` - Remove media files
40
49
 
50
+ **💡 Best Practice for Images:**
51
+ - ✅ **Use file paths** (e.g., `/Users/you/image.png`) - Fast and efficient
52
+ - ✅ **Use URLs** (e.g., `https://example.com/image.jpg`) - Direct download
53
+ - ❌ **Avoid base64** - Extremely slow and token-inefficient
54
+
55
+ Just tell Claude where the image is, and it will handle the upload automatically using the most efficient method.
56
+
41
57
  ### Model/Template Management
42
58
  - `modelNames` - List note types
43
59
  - `modelFieldNames` - Get fields for a note type
@@ -59,7 +75,7 @@ This server works in two modes:
59
75
 
60
76
  The easiest way to install this MCP server for Claude Desktop:
61
77
 
62
- 1. Download the latest `.mcpb` bundle from the [Releases](https://github.com/anki-mcp-organization/anki-mcp-desktop/releases) page
78
+ 1. Download the latest `.mcpb` bundle from the [Releases](https://github.com/ankimcp/anki-mcp-server/releases) page
63
79
  2. In Claude Desktop, install the extension:
64
80
  - **Method 1**: Go to Settings → Extensions, then drag and drop the `.mcpb` file
65
81
  - **Method 2**: Go to Settings → Developer → Extensions → Install Extension, then select the `.mcpb` file
@@ -78,16 +94,38 @@ Want to use Anki with MCP clients like **Cursor IDE**, **Cline**, or **Zed Edito
78
94
  - [Zed Editor](https://zed.dev/) - Fast, modern code editor
79
95
  - Other MCP clients that support STDIO transport
80
96
 
81
- **Basic Configuration:**
97
+ **Configuration - Choose one method:**
82
98
 
83
- Add this to your MCP client's configuration file:
99
+ **Method 1: Using npx (recommended - no installation needed)**
84
100
 
85
101
  ```json
86
102
  {
87
103
  "mcpServers": {
88
104
  "anki-mcp": {
89
105
  "command": "npx",
90
- "args": ["-y", "anki-mcp-http", "--stdio"],
106
+ "args": ["-y", "@ankimcp/anki-mcp-server", "--stdio"],
107
+ "env": {
108
+ "ANKI_CONNECT_URL": "http://localhost:8765"
109
+ }
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ **Method 2: Using global installation**
116
+
117
+ First, install globally:
118
+ ```bash
119
+ npm install -g @ankimcp/anki-mcp-server
120
+ ```
121
+
122
+ Then configure:
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "anki-mcp": {
127
+ "command": "@ankimcp/anki-mcp-server",
128
+ "args": ["--stdio"],
91
129
  "env": {
92
130
  "ANKI_CONNECT_URL": "http://localhost:8765"
93
131
  }
@@ -109,21 +147,48 @@ Want to use Anki with ChatGPT or Claude.ai in your browser? This mode lets you c
109
147
 
110
148
  **How it works (simple explanation):**
111
149
  1. You run a small server on your computer (where Anki is installed)
112
- 2. You use [ngrok](https://ngrok.com) to create a public URL that forwards to your local server
113
- 3. You share that URL with ChatGPT or Claude.ai
150
+ 2. Use the built-in `--ngrok` flag to automatically create a public tunnel URL
151
+ 3. Share that URL with ChatGPT or Claude.ai
114
152
  4. Now the AI can talk to your Anki through the internet!
115
153
 
116
- **Setup:**
154
+ **New in v0.8.0:** Integrated ngrok support with the `--ngrok` flag - no need to run ngrok separately!
155
+
156
+ **Setup - Choose one method:**
157
+
158
+ **Method 1: Using npx (recommended - no installation needed)**
159
+
160
+ ```bash
161
+ # Quick start
162
+ npx @ankimcp/anki-mcp-server
163
+
164
+ # With ngrok tunnel (recommended for web-based AI)
165
+ npx @ankimcp/anki-mcp-server --ngrok
166
+
167
+ # With custom options
168
+ npx @ankimcp/anki-mcp-server --port 8080 --host 0.0.0.0
169
+ npx @ankimcp/anki-mcp-server --anki-connect http://localhost:8765
170
+ ```
171
+
172
+ **Method 2: Using global installation**
117
173
 
118
174
  ```bash
119
- # Quick start (using npx - no installation needed)
120
- npx anki-mcp-http
175
+ # Install once
176
+ npm install -g @ankimcp/anki-mcp-server
177
+
178
+ # Run the server
179
+ @ankimcp/anki-mcp-server
180
+
181
+ # With ngrok tunnel (recommended for web-based AI)
182
+ @ankimcp/anki-mcp-server --ngrok
121
183
 
122
184
  # With custom options
123
- npx anki-mcp-http --port 8080 --host 0.0.0.0
124
- npx anki-mcp-http --anki-connect http://localhost:8765
185
+ @ankimcp/anki-mcp-server --port 8080 --host 0.0.0.0
186
+ @ankimcp/anki-mcp-server --anki-connect http://localhost:8765
187
+ ```
188
+
189
+ **Method 3: Install from source (for development)**
125
190
 
126
- # Or install from source
191
+ ```bash
127
192
  npm install
128
193
  npm run build
129
194
  npm run start:prod:http
@@ -132,37 +197,66 @@ npm run start:prod:http
132
197
  **CLI Options:**
133
198
 
134
199
  ```bash
135
- ankimcp [options]
200
+ @ankimcp/anki-mcp-server [options]
136
201
 
137
202
  Options:
138
203
  --stdio Run in STDIO mode (for MCP clients)
139
204
  -p, --port <port> Port to listen on (HTTP mode, default: 3000)
140
205
  -h, --host <host> Host to bind to (HTTP mode, default: 127.0.0.1)
141
206
  -a, --anki-connect <url> AnkiConnect URL (default: http://localhost:8765)
207
+ --ngrok Start ngrok tunnel (requires global ngrok installation)
142
208
  --help Show help message
143
209
 
144
- Examples - HTTP Mode:
145
- ankimcp # Use all defaults (HTTP mode)
146
- ankimcp --port 8080 # Custom port
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
210
+ Usage with npx (no installation needed):
211
+ npx @ankimcp/anki-mcp-server # HTTP mode
212
+ npx @ankimcp/anki-mcp-server --port 8080 # Custom port
213
+ npx @ankimcp/anki-mcp-server --stdio # STDIO mode
214
+ npx @ankimcp/anki-mcp-server --ngrok # HTTP mode with ngrok tunnel
215
+
216
+ Usage with global installation:
217
+ npm install -g @ankimcp/anki-mcp-server # Install once
218
+ @ankimcp/anki-mcp-server # HTTP mode
219
+ @ankimcp/anki-mcp-server --port 8080 # Custom port
220
+ @ankimcp/anki-mcp-server --stdio # STDIO mode
221
+ @ankimcp/anki-mcp-server --ngrok # HTTP mode with ngrok tunnel
151
222
  ```
152
223
 
153
224
  **Using with ngrok:**
154
225
 
226
+ **Method 1: Integrated (Recommended - One Command)**
227
+
155
228
  ```bash
156
- # 1. Start ankimcp
157
- npx anki-mcp-http
229
+ # One-time setup (if you haven't already):
230
+ npm install -g ngrok
231
+ ngrok config add-authtoken <your-token> # Get token from https://dashboard.ngrok.com
232
+
233
+ # Start server with ngrok tunnel in one command:
234
+ @ankimcp/anki-mcp-server --ngrok
235
+
236
+ # The tunnel URL will be displayed in the startup banner
237
+ # Example output:
238
+ # 🌐 Ngrok tunnel: https://abc123.ngrok-free.app
239
+ ```
240
+
241
+ **Method 2: Manual (Two Terminals)**
158
242
 
159
- # 2. In another terminal, create a tunnel
243
+ ```bash
244
+ # Terminal 1: Start the server
245
+ @ankimcp/anki-mcp-server
246
+
247
+ # Terminal 2: Create tunnel
160
248
  ngrok http 3000
161
249
 
162
- # 3. Copy the ngrok URL (looks like: https://abc123.ngrok.io)
163
- # 4. Share this URL with your AI assistant
250
+ # Copy the ngrok URL (looks like: https://abc123.ngrok-free.app)
251
+ # Share this URL with your AI assistant
164
252
  ```
165
253
 
254
+ **Benefits of `--ngrok` flag:**
255
+ - ✅ One command instead of two terminals
256
+ - ✅ Automatic cleanup when you press Ctrl+C
257
+ - ✅ URL displayed directly in the startup banner
258
+ - ✅ Works with custom ports: `@ankimcp/anki-mcp-server --port 8080 --ngrok`
259
+
166
260
  **Security note:** Anyone with your ngrok URL can access your Anki, so keep that URL private!
167
261
 
168
262
  ### Option 4: Manual Installation from Source (Local Mode)
@@ -189,7 +283,7 @@ Add the following to your Claude Desktop config:
189
283
  "mcpServers": {
190
284
  "anki-mcp": {
191
285
  "command": "node",
192
- "args": ["/path/to/anki-mcp-desktop/dist/main-stdio.js"],
286
+ "args": ["/path/to/anki-mcp-server/dist/main-stdio.js"],
193
287
  "env": {
194
288
  "ANKI_CONNECT_URL": "http://localhost:8765"
195
289
  }
@@ -198,7 +292,7 @@ Add the following to your Claude Desktop config:
198
292
  }
199
293
  ```
200
294
 
201
- Replace `/path/to/anki-mcp-desktop` with your actual project path.
295
+ Replace `/path/to/anki-mcp-server` with your actual project path.
202
296
 
203
297
  ### Config File Locations
204
298
 
@@ -345,7 +439,7 @@ This command will:
345
439
  3. Build the TypeScript project
346
440
  4. Package `dist/` and `node_modules/` into an `.mcpb` file
347
441
 
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.
442
+ The output file will be named based on the current version (e.g., `@ankimcp/anki-mcp-server-0.5.0.mcpb`) and can be distributed for one-click installation.
349
443
 
350
444
  #### What Gets Bundled
351
445
 
@@ -458,7 +552,7 @@ Update your Claude Desktop config to enable debugging:
458
552
  "command": "node",
459
553
  "args": [
460
554
  "--inspect=9229",
461
- "/Users/anatoly/Developer/git/anki-mcp-organization/anki-mcp-desktop/dist/main-stdio.js"
555
+ "<path_to_project>/anki-mcp-server/dist/main-stdio.js"
462
556
  ],
463
557
  "env": {
464
558
  "ANKI_CONNECT_URL": "http://localhost:8765"
@@ -547,10 +641,10 @@ Test the npm package locally before publishing:
547
641
 
548
642
  ```bash
549
643
  # 1. Create local package
550
- npm run pack:local # Builds and creates anki-mcp-http-*.tgz
644
+ npm run pack:local # Builds and creates @ankimcp/anki-mcp-server-*.tgz
551
645
 
552
646
  # 2. Install globally from local package
553
- npm run install:local # Installs from ./anki-mcp-http-*.tgz
647
+ npm run install:local # Installs from ./@ankimcp/anki-mcp-server-*.tgz
554
648
 
555
649
  # 3. Test the command
556
650
  ankimcp # Runs HTTP server on port 3000
@@ -601,7 +695,7 @@ This project follows [Semantic Versioning](https://semver.org/) with a pre-1.0 d
601
695
  - Will be released when the API is stable and tested
602
696
  - Breaking changes will require major version bumps (2.0.0, etc.)
603
697
 
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.
698
+ **Current Status**: `0.8.0` - Active beta development. New features include integrated ngrok tunneling (`--ngrok` flag), the `twenty_rules` prompt for evidence-based flashcard creation, media file management, and improved prompt system. APIs may change based on feedback and testing.
605
699
 
606
700
  ## Similar Projects
607
701
 
@@ -616,7 +710,7 @@ If you're exploring Anki MCP integrations, here are other projects in this space
616
710
  - **Architecture**: Procedural code structure with all tools in one file
617
711
  - **Good for**: Simple use cases, minimal dependencies
618
712
 
619
- **Why this project (anki-mcp-desktop) differs:**
713
+ **Why this project differs:**
620
714
  - **Enterprise-grade architecture**: Built on NestJS with dependency injection
621
715
  - **Modular design**: Each tool is a separate class with clear separation of concerns
622
716
  - **Maintainability**: Easy to extend with new features without touching existing code
@@ -636,4 +730,27 @@ If you're exploring Anki MCP integrations, here are other projects in this space
636
730
  - [Building Desktop Extensions (Anthropic Blog)](https://www.anthropic.com/engineering/desktop-extensions)
637
731
  - [MCP Servers Repository](https://github.com/modelcontextprotocol/servers)
638
732
  - [NestJS Documentation](https://docs.nestjs.com)
639
- - [Anki Official Website](https://apps.ankiweb.net/)
733
+ - [Anki Official Website](https://apps.ankiweb.net/)
734
+
735
+ ## License & Attribution
736
+
737
+ This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).
738
+
739
+ ### Why AGPL-3.0?
740
+
741
+ This license was chosen to maintain compatibility with Anki's AGPL-3.0 license for potential future integration scenarios.
742
+
743
+ **What this means:**
744
+ - **Personal use**: Use the software freely
745
+ - **Running as a service for others**: You must provide source code access (AGPL Section 13)
746
+ - **Modifying and distributing**: Share your improvements under AGPL-3.0-or-later
747
+
748
+ For complete license terms, see the [LICENSE](LICENSE) file.
749
+
750
+ ### Third-Party Attributions
751
+
752
+ - **Anki®** is a registered trademark of Ankitects Pty Ltd. This project is an unofficial third-party tool and is not affiliated with, endorsed by, or sponsored by Ankitects Pty Ltd. The Anki logo is used under the alternative license for referencing Anki with a link to [https://apps.ankiweb.net](https://apps.ankiweb.net). For the official Anki application, visit [https://apps.ankiweb.net](https://apps.ankiweb.net).
753
+
754
+ - **Model Context Protocol (MCP)** is an open standard by Anthropic. The MCP logo is from the official [MCP documentation repository](https://github.com/modelcontextprotocol/docs) and is used under the MIT License. For more information about MCP, visit [https://modelcontextprotocol.io](https://modelcontextprotocol.io).
755
+
756
+ - This is an independent project that bridges Anki and MCP technologies. All trademarks, service marks, trade names, product names, and logos are the property of their respective owners.
package/bin/ankimcp.js CHANGED
File without changes
@@ -1,5 +1,5 @@
1
- import { ConfigService } from '@nestjs/config';
2
- import { IAnkiConfig } from './mcp/config/anki-config.interface';
1
+ import { ConfigService } from "@nestjs/config";
2
+ import { IAnkiConfig } from "./mcp/config/anki-config.interface";
3
3
  export declare class AnkiConfigService implements IAnkiConfig {
4
4
  private configService;
5
5
  constructor(configService: ConfigService);
@@ -19,18 +19,18 @@ let AnkiConfigService = class AnkiConfigService {
19
19
  this.configService = configService;
20
20
  }
21
21
  get ankiConnectUrl() {
22
- return this.configService.get('ANKI_CONNECT_URL', 'http://localhost:8765');
22
+ return this.configService.get("ANKI_CONNECT_URL", "http://localhost:8765");
23
23
  }
24
24
  get ankiConnectApiVersion() {
25
- const version = this.configService.get('ANKI_CONNECT_API_VERSION', '6');
25
+ const version = this.configService.get("ANKI_CONNECT_API_VERSION", "6");
26
26
  return parseInt(version, 10);
27
27
  }
28
28
  get ankiConnectApiKey() {
29
- const apiKey = this.configService.get('ANKI_CONNECT_API_KEY');
29
+ const apiKey = this.configService.get("ANKI_CONNECT_API_KEY");
30
30
  return (0, mcpb_workarounds_1.sanitizeMcpbConfigValue)(apiKey);
31
31
  }
32
32
  get ankiConnectTimeout() {
33
- const timeout = this.configService.get('ANKI_CONNECT_TIMEOUT', '5000');
33
+ const timeout = this.configService.get("ANKI_CONNECT_TIMEOUT", "5000");
34
34
  return parseInt(timeout, 10);
35
35
  }
36
36
  };
@@ -1,4 +1,4 @@
1
- import { DynamicModule } from '@nestjs/common';
1
+ import { DynamicModule } from "@nestjs/common";
2
2
  export declare class AppModule {
3
3
  static forStdio(): DynamicModule;
4
4
  static forHttp(): DynamicModule;
@@ -22,11 +22,11 @@ let AppModule = AppModule_1 = class AppModule {
22
22
  config_1.ConfigModule.forRoot({
23
23
  isGlobal: true,
24
24
  cache: true,
25
- envFilePath: ['.env.local', '.env'],
25
+ envFilePath: [".env.local", ".env"],
26
26
  }),
27
27
  mcp_nest_1.McpModule.forRoot({
28
- name: process.env.MCP_SERVER_NAME || 'anki-mcp-desktop',
29
- version: process.env.MCP_SERVER_VERSION || '1.0.0',
28
+ name: process.env.MCP_SERVER_NAME || "anki-mcp-server",
29
+ version: process.env.MCP_SERVER_VERSION || "1.0.0",
30
30
  transport: mcp_nest_1.McpTransportType.STDIO,
31
31
  }),
32
32
  essential_1.McpPrimitivesAnkiEssentialModule.forRoot({
@@ -52,13 +52,13 @@ let AppModule = AppModule_1 = class AppModule {
52
52
  config_1.ConfigModule.forRoot({
53
53
  isGlobal: true,
54
54
  cache: true,
55
- envFilePath: ['.env.local', '.env'],
55
+ envFilePath: [".env.local", ".env"],
56
56
  }),
57
57
  mcp_nest_1.McpModule.forRoot({
58
- name: process.env.MCP_SERVER_NAME || 'anki-mcp-desktop',
59
- version: process.env.MCP_SERVER_VERSION || '1.0.0',
58
+ name: process.env.MCP_SERVER_NAME || "anki-mcp-server",
59
+ version: process.env.MCP_SERVER_VERSION || "1.0.0",
60
60
  transport: mcp_nest_1.McpTransportType.STREAMABLE_HTTP,
61
- mcpEndpoint: '/',
61
+ mcpEndpoint: "/",
62
62
  }),
63
63
  essential_1.McpPrimitivesAnkiEssentialModule.forRoot({
64
64
  ankiConfigProvider: {
@@ -1 +1 @@
1
- {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,2CAA8C;AAC9C,8CAA8D;AAC9D,0DAGoC;AACpC,8CAAkE;AAClE,+DAA0D;AAGnD,IAAM,SAAS,iBAAf,MAAM,SAAS;IAIpB,MAAM,CAAC,QAAQ;QACb,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,OAAO,EAAE;gBAEP,qBAAY,CAAC,OAAO,CAAC;oBACnB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;iBACpC,CAAC;gBAGF,oBAAS,CAAC,OAAO,CAAC;oBAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,kBAAkB;oBACvD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO;oBAClD,SAAS,EAAE,2BAAgB,CAAC,KAAK;iBAClC,CAAC;gBAGF,4CAAgC,CAAC,OAAO,CAAC;oBACvC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;gBAGF,gCAA0B,CAAC,OAAO,CAAC;oBACjC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;aACH;YACD,SAAS,EAAE,CAAC,uCAAiB,CAAC;SAC/B,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,OAAO,EAAE;gBAEP,qBAAY,CAAC,OAAO,CAAC;oBACnB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;iBACpC,CAAC;gBAGF,oBAAS,CAAC,OAAO,CAAC;oBAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,kBAAkB;oBACvD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO;oBAClD,SAAS,EAAE,2BAAgB,CAAC,eAAe;oBAC3C,WAAW,EAAE,GAAG;iBACjB,CAAC;gBAGF,4CAAgC,CAAC,OAAO,CAAC;oBACvC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;gBAGF,gCAA0B,CAAC,OAAO,CAAC;oBACjC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;aACH;YACD,SAAS,EAAE,CAAC,uCAAiB,CAAC;SAC/B,CAAC;IACJ,CAAC;CACF,CAAA;AAnFY,8BAAS;oBAAT,SAAS;IADrB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,SAAS,CAmFrB"}
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,2CAA8C;AAC9C,8CAA8D;AAC9D,0DAGoC;AACpC,8CAAkE;AAClE,+DAA0D;AAGnD,IAAM,SAAS,iBAAf,MAAM,SAAS;IAIpB,MAAM,CAAC,QAAQ;QACb,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,OAAO,EAAE;gBAEP,qBAAY,CAAC,OAAO,CAAC;oBACnB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;iBACpC,CAAC;gBAGF,oBAAS,CAAC,OAAO,CAAC;oBAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,iBAAiB;oBACtD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO;oBAClD,SAAS,EAAE,2BAAgB,CAAC,KAAK;iBAClC,CAAC;gBAGF,4CAAgC,CAAC,OAAO,CAAC;oBACvC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;gBAGF,gCAA0B,CAAC,OAAO,CAAC;oBACjC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;aACH;YACD,SAAS,EAAE,CAAC,uCAAiB,CAAC;SAC/B,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,OAAO,EAAE;gBAEP,qBAAY,CAAC,OAAO,CAAC;oBACnB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;iBACpC,CAAC;gBAGF,oBAAS,CAAC,OAAO,CAAC;oBAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,iBAAiB;oBACtD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO;oBAClD,SAAS,EAAE,2BAAgB,CAAC,eAAe;oBAC3C,WAAW,EAAE,GAAG;iBACjB,CAAC;gBAGF,4CAAgC,CAAC,OAAO,CAAC;oBACvC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;gBAGF,gCAA0B,CAAC,OAAO,CAAC;oBACjC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;aACH;YACD,SAAS,EAAE,CAAC,uCAAiB,CAAC;SAC/B,CAAC;IACJ,CAAC;CACF,CAAA;AAnFY,8BAAS;oBAAT,SAAS;IADrB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,SAAS,CAmFrB"}
@@ -1,3 +1,3 @@
1
- import { LoggerService } from '@nestjs/common';
1
+ import { LoggerService } from "@nestjs/common";
2
2
  export declare function createPinoLogger(destination: 1 | 2): import("pino").Logger<never, boolean>;
3
3
  export declare function createLoggerService(pinoLogger: any): LoggerService;
package/dist/bootstrap.js CHANGED
@@ -5,14 +5,14 @@ exports.createLoggerService = createLoggerService;
5
5
  const pino_1 = require("pino");
6
6
  function createPinoLogger(destination) {
7
7
  return (0, pino_1.pino)({
8
- level: process.env.LOG_LEVEL || 'info',
8
+ level: process.env.LOG_LEVEL || "info",
9
9
  transport: {
10
- target: 'pino-pretty',
10
+ target: "pino-pretty",
11
11
  options: {
12
12
  destination,
13
13
  colorize: true,
14
- translateTime: 'HH:MM:ss Z',
15
- ignore: 'pid,hostname',
14
+ translateTime: "HH:MM:ss Z",
15
+ ignore: "pid,hostname",
16
16
  },
17
17
  },
18
18
  });
package/dist/cli.d.ts CHANGED
@@ -2,7 +2,8 @@ export interface CliOptions {
2
2
  port: number;
3
3
  host: string;
4
4
  ankiConnect: string;
5
+ ngrok: boolean;
5
6
  }
6
7
  export declare function checkForUpdates(): void;
7
8
  export declare function parseCliArgs(): CliOptions;
8
- export declare function displayStartupBanner(options: CliOptions): void;
9
+ export declare function displayStartupBanner(options: CliOptions, ngrokUrl?: string): void;
package/dist/cli.js CHANGED
@@ -12,10 +12,10 @@ const path_1 = require("path");
12
12
  const update_notifier_1 = __importDefault(require("update-notifier"));
13
13
  function getPackageJson() {
14
14
  try {
15
- return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../package.json'), 'utf-8'));
15
+ return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, "../package.json"), "utf-8"));
16
16
  }
17
17
  catch {
18
- return { version: '0.0.0', name: 'anki-mcp-http' };
18
+ return { version: "0.0.0", name: "anki-mcp-http" };
19
19
  }
20
20
  }
21
21
  function getVersion() {
@@ -27,26 +27,32 @@ function checkForUpdates() {
27
27
  function parseCliArgs() {
28
28
  const program = new commander_1.Command();
29
29
  program
30
- .name('ankimcp')
31
- .description('AnkiMCP Server - Model Context Protocol server for Anki')
30
+ .name("ankimcp")
31
+ .description("AnkiMCP Server - Model Context Protocol server for Anki")
32
32
  .version(getVersion())
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')
36
- .option('-a, --anki-connect <url>', 'AnkiConnect URL', 'http://localhost:8765')
37
- .addHelpText('after', `
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")
36
+ .option("-a, --anki-connect <url>", "AnkiConnect URL", "http://localhost:8765")
37
+ .option("--ngrok", "Start ngrok tunnel (requires global ngrok installation)")
38
+ .addHelpText("after", `
38
39
  Transport Modes:
39
40
  HTTP Mode (default): For web-based AI assistants (ChatGPT, Claude.ai)
40
41
  STDIO Mode: For desktop MCP clients (Cursor, Cline, Zed)
41
42
 
42
43
  Examples - HTTP Mode:
43
- $ ankimcp # Use defaults
44
- $ ankimcp --port 8080 # Custom port
45
- $ ankimcp --host 0.0.0.0 --port 3000 # Listen on all interfaces
46
- $ ankimcp --anki-connect http://localhost:8765
44
+ $ anki-mcp-http # Use defaults
45
+ $ anki-mcp-http --port 8080 # Custom port
46
+ $ anki-mcp-http --host 0.0.0.0 --port 3000 # Listen on all interfaces
47
+ $ anki-mcp-http --anki-connect http://localhost:8765
48
+
49
+ Examples - HTTP Mode with Ngrok:
50
+ $ anki-mcp-http --ngrok # Start with ngrok tunnel
51
+ $ anki-mcp-http --port 8080 --ngrok # Custom port + ngrok
52
+ $ anki-mcp-http --host 0.0.0.0 --ngrok # Public host + ngrok
47
53
 
48
54
  Examples - STDIO Mode:
49
- $ ankimcp --stdio # For use with npx in MCP clients
55
+ $ anki-mcp-http --stdio # For use with npx in MCP clients
50
56
 
51
57
  # MCP client configuration (Cursor, Cline, Zed, etc.):
52
58
  {
@@ -58,10 +64,11 @@ Examples - STDIO Mode:
58
64
  }
59
65
  }
60
66
 
61
- Usage with ngrok (HTTP mode only):
62
- 1. Start ankimcp in one terminal
63
- 2. In another terminal: ngrok http 3000
64
- 3. Share the ngrok URL with your AI assistant
67
+ Ngrok Setup (one-time):
68
+ 1. Install: npm install -g ngrok
69
+ 2. Get auth token from: https://dashboard.ngrok.com/get-started/your-authtoken
70
+ 3. Setup: ngrok config add-authtoken <your-token>
71
+ 4. Run: anki-mcp-http --ngrok
65
72
  `);
66
73
  program.parse();
67
74
  const options = program.opts();
@@ -69,32 +76,39 @@ Usage with ngrok (HTTP mode only):
69
76
  port: parseInt(options.port.toString(), 10),
70
77
  host: options.host,
71
78
  ankiConnect: options.ankiConnect,
79
+ ngrok: options.ngrok || false,
72
80
  };
73
81
  }
74
- function displayStartupBanner(options) {
82
+ function displayStartupBanner(options, ngrokUrl) {
75
83
  const version = getVersion();
76
84
  const title = `AnkiMCP HTTP Server v${version}`;
77
85
  const padding = Math.floor((64 - title.length) / 2);
78
- const paddedTitle = ' '.repeat(padding) + title + ' '.repeat(64 - padding - title.length);
86
+ const paddedTitle = " ".repeat(padding) + title + " ".repeat(64 - padding - title.length);
79
87
  console.log(`
80
88
  ╔════════════════════════════════════════════════════════════════╗
81
89
  ║${paddedTitle}║
82
90
  ╚════════════════════════════════════════════════════════════════╝
83
91
 
84
92
  🚀 Server running on: http://${options.host}:${options.port}
85
- 🔌 AnkiConnect URL: ${options.ankiConnect}
93
+ 🔌 AnkiConnect URL: ${options.ankiConnect}${ngrokUrl ? `\n🌐 Ngrok tunnel: ${ngrokUrl}` : ""}
86
94
 
87
95
  Configuration:
88
96
  • Port: ${options.port} (override: --port 8080)
89
97
  • Host: ${options.host} (override: --host 0.0.0.0)
90
98
  • AnkiConnect: ${options.ankiConnect}
91
- (override: --anki-connect http://localhost:8765)
92
-
99
+ (override: --anki-connect http://localhost:8765)${ngrokUrl ? `\n • Ngrok tunnel: ${ngrokUrl}\n • Ngrok dashboard: http://localhost:4040` : ""}
100
+ ${!ngrokUrl
101
+ ? `
93
102
  Usage with ngrok:
94
- 1. In another terminal: ngrok http ${options.port}
95
- 2. Share the ngrok URL with your AI assistant
96
-
97
- Run 'ankimcp --help' for more options.
103
+ 1. Install: npm install -g ngrok
104
+ 2. Setup: ngrok config add-authtoken <your-token>
105
+ 3. Run: anki-mcp-http --ngrok
106
+ `
107
+ : `
108
+ Share this URL with your AI assistant:
109
+ ${ngrokUrl}
110
+ `}
111
+ Run 'anki-mcp-http --help' for more options.
98
112
  `);
99
113
  }
100
114
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;AA0BA,0CAEC;AAED,oCAuEC;AAED,oDAsCC;AA7ID,yCAAoC;AACpC,2BAAkC;AAClC,+BAA4B;AAC5B,sEAA6C;AAS7C,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,MAAM,CACL,SAAS,EACT,yDAAyD,CAC1D;SACA,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCL,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;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK;KAC9B,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAClC,OAAmB,EACnB,QAAiB;IAEjB,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,GACf,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAExE,OAAO,CAAC,GAAG,CAAC;;GAEX,WAAW;;;+BAGiB,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;wBACnC,OAAO,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;;;0BAGzE,OAAO,CAAC,IAAI;0BACZ,OAAO,CAAC,IAAI;0BACZ,OAAO,CAAC,WAAW;0EAC6B,QAAQ,CAAC,CAAC,CAAC,6BAA6B,QAAQ,iDAAiD,CAAC,CAAC,CAAC,EAAE;EAE9K,CAAC,QAAQ;QACP,CAAC,CAAC;;;;;CAKL;QACG,CAAC,CAAC;;IAEF,QAAQ;CAEZ;;CAEC,CAAC,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { CanActivate, ExecutionContext } from '@nestjs/common';
1
+ import { CanActivate, ExecutionContext } from "@nestjs/common";
2
2
  export declare class OriginValidationGuard implements CanActivate {
3
3
  private readonly allowedOrigins;
4
4
  constructor();
@@ -14,9 +14,9 @@ const common_1 = require("@nestjs/common");
14
14
  let OriginValidationGuard = class OriginValidationGuard {
15
15
  allowedOrigins;
16
16
  constructor() {
17
- const defaultOrigins = 'http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*';
17
+ const defaultOrigins = "http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*";
18
18
  const originsEnv = process.env.ALLOWED_ORIGINS || defaultOrigins;
19
- this.allowedOrigins = originsEnv.split(',').map((o) => o.trim());
19
+ this.allowedOrigins = originsEnv.split(",").map((o) => o.trim());
20
20
  }
21
21
  canActivate(context) {
22
22
  const request = context.switchToHttp().getRequest();
@@ -34,10 +34,10 @@ let OriginValidationGuard = class OriginValidationGuard {
34
34
  if (origin === pattern) {
35
35
  return true;
36
36
  }
37
- if (pattern.includes('*')) {
37
+ if (pattern.includes("*")) {
38
38
  const regexPattern = pattern
39
- .replace(/\./g, '\\.')
40
- .replace(/\*/g, '.*');
39
+ .replace(/\./g, "\\.")
40
+ .replace(/\*/g, ".*");
41
41
  const regex = new RegExp(`^${regexPattern}$`);
42
42
  return regex.test(origin);
43
43
  }