anki-connect-server 0.1.0__tar.gz

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 (23) hide show
  1. anki_connect_server-0.1.0/PKG-INFO +375 -0
  2. anki_connect_server-0.1.0/README.md +361 -0
  3. anki_connect_server-0.1.0/pyproject.toml +40 -0
  4. anki_connect_server-0.1.0/setup.cfg +4 -0
  5. anki_connect_server-0.1.0/src/anki_connect_server/__init__.py +1 -0
  6. anki_connect_server-0.1.0/src/anki_connect_server/anki_wrapper.py +485 -0
  7. anki_connect_server-0.1.0/src/anki_connect_server/api.py +58 -0
  8. anki_connect_server-0.1.0/src/anki_connect_server/config.py +27 -0
  9. anki_connect_server-0.1.0/src/anki_connect_server/handlers.py +368 -0
  10. anki_connect_server-0.1.0/src/anki_connect_server/mcp_server.py +256 -0
  11. anki_connect_server-0.1.0/src/anki_connect_server/wrapper.py +23 -0
  12. anki_connect_server-0.1.0/src/anki_connect_server.egg-info/PKG-INFO +375 -0
  13. anki_connect_server-0.1.0/src/anki_connect_server.egg-info/SOURCES.txt +21 -0
  14. anki_connect_server-0.1.0/src/anki_connect_server.egg-info/dependency_links.txt +1 -0
  15. anki_connect_server-0.1.0/src/anki_connect_server.egg-info/entry_points.txt +3 -0
  16. anki_connect_server-0.1.0/src/anki_connect_server.egg-info/requires.txt +7 -0
  17. anki_connect_server-0.1.0/src/anki_connect_server.egg-info/top_level.txt +1 -0
  18. anki_connect_server-0.1.0/tests/test_api.py +316 -0
  19. anki_connect_server-0.1.0/tests/test_config.py +71 -0
  20. anki_connect_server-0.1.0/tests/test_handlers.py +417 -0
  21. anki_connect_server-0.1.0/tests/test_integration.py +122 -0
  22. anki_connect_server-0.1.0/tests/test_mcp_server.py +218 -0
  23. anki_connect_server-0.1.0/tests/test_sync_server.py +189 -0
@@ -0,0 +1,375 @@
1
+ Metadata-Version: 2.4
2
+ Name: anki-connect-server
3
+ Version: 0.1.0
4
+ Summary: Headless AnkiConnect-compatible REST API server with AnkiWeb sync
5
+ Requires-Python: >=3.12
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: fastapi>=0.100.0
8
+ Requires-Dist: uvicorn[standard]>=0.23.0
9
+ Requires-Dist: anki>=24.6
10
+ Requires-Dist: python-multipart>=0.0.6
11
+ Requires-Dist: pydantic>=2.0
12
+ Requires-Dist: pydantic-settings>=2.0
13
+ Requires-Dist: fastmcp>=3.1.0
14
+
15
+ # AnkiConnect Server
16
+
17
+ [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
18
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
19
+ [![FastAPI](https://img.shields.io/badge/FastAPI-0.100+-green.svg)](https://fastapi.tiangolo.com/)
20
+
21
+ Headless AnkiConnect-compatible REST API server with AnkiWeb sync support and MCP server integration.
22
+
23
+ ## ❓ Problem & Solution
24
+
25
+ **Problem:** Traditional AnkiConnect requires the Anki desktop app running, works only on localhost, and can't be deployed to servers.
26
+
27
+ **Solution:** This headless server provides direct collection access without Anki desktop, supports remote deployment, and includes automatic AnkiWeb sync.
28
+
29
+
30
+ ## ✨ Features
31
+
32
+ - **Server Deployment** - Run on VPS, Raspberry Pi, or cloud without GUI
33
+ - **AI Integration** - MCP server for AI assistant access to your cards
34
+ - **Full AnkiConnect API Compatibility** - Version 6 API with all standard actions
35
+ - **Headless Operation** - No Qt/GUI required, perfect for servers and containers
36
+ - **AnkiWeb Sync** - Automatic synchronization with AnkiWeb (optional)
37
+ - **Custom Sync Server** - Support for self-hosted Anki sync servers
38
+ - **MCP Server** - Model Context Protocol integration for AI assistants
39
+
40
+ ## 📋 Table of Contents
41
+
42
+ - [Requirements](#-requirements)
43
+ - [Installation](#-installation)
44
+ - [Configuration](#-configuration)
45
+ - [Usage](#-usage)
46
+ - [API Reference](#-api-reference)
47
+ - [MCP Server](#-mcp-server)
48
+ - [Docker](#-docker)
49
+
50
+ ## 🔧 Requirements
51
+
52
+ - Python 3.12+
53
+ - [uv](https://github.com/astral-sh/uv) package manager
54
+ - Anki collection file (`.anki21`)
55
+
56
+ ## 📦 Installation
57
+
58
+ ### Quick Install
59
+
60
+ ```bash
61
+ # Clone the repository
62
+ git clone https://github.com/glechic/anki-connect-server.git
63
+ cd anki-connect-server
64
+
65
+ # Install with uv
66
+ uv pip install -e .
67
+ ```
68
+
69
+ ### From PyPI (coming soon)
70
+
71
+ ```bash
72
+ pip install anki-connect-server
73
+ ```
74
+
75
+ ## ⚙️ Configuration
76
+
77
+ Set environment variables before running the server:
78
+
79
+ | Variable | Required | Default | Description |
80
+ |----------|----------|---------|-------------|
81
+ | `ANKI_COLLECTION_PATH` | **Yes** | - | Path to your `.anki21` collection file |
82
+ | `ANKICONNECT_PORT` | No | `8765` | Server port |
83
+ | `ANKICONNECT_BIND` | No | `127.0.0.1` | Bind address (use `0.0.0.0` for external access) |
84
+ | `ANKICONNECT_ANKIWEB_USER` | No | - | AnkiWeb username (required for sync) |
85
+ | `ANKICONNECT_ANKIWEB_PASS` | No | - | AnkiWeb password (required for sync) |
86
+ | `ANKIWEB_URL` | No | - | Custom sync server URL (optional) |
87
+ | `ANKICONNECT_FULL_UPLOAD` | No | `false` | Allow full upload on sync conflict |
88
+
89
+ ### Example `.env` File
90
+
91
+ ```bash
92
+ # Required: Path to your Anki collection
93
+ ANKI_COLLECTION_PATH=/path/to/collection.anki21
94
+
95
+ # Optional: Server configuration
96
+ ANKICONNECT_PORT=8765
97
+ ANKICONNECT_BIND=127.0.0.1
98
+
99
+ # Optional: AnkiWeb sync credentials
100
+ ANKICONNECT_ANKIWEB_USER=your@email.com
101
+ ANKICONNECT_ANKIWEB_PASS=your_password
102
+
103
+ # Optional: Custom sync server
104
+ # ANKIWEB_URL=https://your-sync-server.com
105
+ ```
106
+
107
+ > ⚠️ **Security Warning**: Store credentials securely. Never commit `.env` files to version control.
108
+
109
+ ## 🚀 Usage
110
+
111
+ ### Development Server
112
+
113
+ ```bash
114
+ uv run uvicorn anki_connect_server.api:app --reload --port 8765
115
+ ```
116
+
117
+ ### Production Server
118
+
119
+ ```bash
120
+ uv run uvicorn anki_connect_server.api:app --host 0.0.0.0 --port 8765
121
+ ```
122
+
123
+ ### Using the CLI
124
+
125
+ ```bash
126
+ # Start the API server
127
+ uv run server
128
+
129
+ # Start the MCP server
130
+ uv run mcp-server
131
+ ```
132
+
133
+ ## 📚 API Reference
134
+
135
+ The server exposes a single POST endpoint at `/api` that accepts AnkiConnect-style JSON requests.
136
+
137
+ ### Request Format
138
+
139
+ ```json
140
+ {
141
+ "action": "actionName",
142
+ "version": 6,
143
+ "params": {
144
+ "param1": "value1",
145
+ "param2": "value2"
146
+ }
147
+ }
148
+ ```
149
+
150
+ ### Response Format
151
+
152
+ ```json
153
+ {
154
+ "result": <action_result>,
155
+ "error": null
156
+ }
157
+ ```
158
+
159
+ On error:
160
+
161
+ ```json
162
+ {
163
+ "result": null,
164
+ "error": "Error message"
165
+ }
166
+ ```
167
+
168
+ ### Examples
169
+
170
+ #### Get Deck Names
171
+
172
+ ```bash
173
+ curl -X POST http://localhost:8765/api \
174
+ -H "Content-Type: application/json" \
175
+ -d '{"action": "deckNames", "version": 6}'
176
+ ```
177
+
178
+ #### Create a Deck
179
+
180
+ ```bash
181
+ curl -X POST http://localhost:8765/api \
182
+ -H "Content-Type: application/json" \
183
+ -d '{"action": "createDeck", "version": 6, "params": {"deck": "My New Deck"}}'
184
+ ```
185
+
186
+ #### Add a Note
187
+
188
+ ```bash
189
+ curl -X POST http://localhost:8765/api \
190
+ -H "Content-Type: application/json" \
191
+ -d '{
192
+ "action": "addNote",
193
+ "version": 6,
194
+ "params": {
195
+ "note": {
196
+ "deckName": "Default",
197
+ "modelName": "Basic",
198
+ "fields": {
199
+ "Front": "Hello",
200
+ "Back": "World"
201
+ },
202
+ "tags": ["api"]
203
+ }
204
+ }
205
+ }'
206
+ ```
207
+
208
+ #### Sync with AnkiWeb
209
+
210
+ ```bash
211
+ curl -X POST http://localhost:8765/api \
212
+ -H "Content-Type: application/json" \
213
+ -d '{"action": "sync", "version": 6}'
214
+ ```
215
+
216
+ #### Batch Multiple Actions
217
+
218
+ ```bash
219
+ curl -X POST http://localhost:8765/api \
220
+ -H "Content-Type: application/json" \
221
+ -d '{
222
+ "action": "multi",
223
+ "version": 6,
224
+ "params": {
225
+ "actions": [
226
+ {"action": "deckNames", "params": {}},
227
+ {"action": "modelNames", "params": {}}
228
+ ]
229
+ }
230
+ }'
231
+ ```
232
+
233
+ ### Supported Actions
234
+
235
+ #### Misc
236
+ - `version` - Get API version
237
+ - `sync` - Sync with AnkiWeb
238
+ - `syncStatus` - Get sync status
239
+ - `syncMedia` - Sync media only
240
+ - `multi` - Execute multiple actions
241
+ - `importPackage` - Import `.apkg` file
242
+ - `exportPackage` - Export deck to `.apkg`
243
+
244
+ #### Decks
245
+ - `deckNames` - Get all deck names
246
+ - `deckNamesAndIds` - Get deck names with IDs
247
+ - `createDeck` - Create a new deck
248
+ - `deleteDecks` - Delete decks
249
+ - `changeDeck` - Move cards to different deck
250
+ - `getDecks` - Get decks for cards
251
+ - `getDeckConfig` - Get deck configuration
252
+ - `saveDeckConfig` - Save deck configuration
253
+ - `setDeckConfigId` - Assign config to decks
254
+ - `cloneDeckConfigId` - Clone deck config
255
+ - `removeDeckConfigId` - Remove deck config
256
+
257
+ #### Models
258
+ - `modelNames` - Get all model names
259
+ - `modelNamesAndIds` - Get model names with IDs
260
+ - `modelFieldNames` - Get field names for model
261
+ - `modelFieldsOnTemplates` - Get fields used in templates
262
+ - `createModel` - Create a new note model
263
+ - `modelTemplates` - Get card templates
264
+ - `modelStyling` - Get CSS styling
265
+ - `updateModelTemplates` - Update templates
266
+ - `updateModelStyling` - Update CSS
267
+
268
+ #### Notes
269
+ - `addNote` - Add a single note
270
+ - `addNotes` - Add multiple notes
271
+ - `canAddNotes` - Check if notes can be added
272
+ - `updateNoteFields` - Update note fields
273
+ - `findNotes` - Search for notes
274
+ - `notesInfo` - Get note details
275
+ - `deleteNotes` - Delete notes
276
+ - `addTags` - Add tags to notes
277
+ - `removeTags` - Remove tags from notes
278
+ - `getTags` - Get all tags
279
+
280
+ #### Cards
281
+ - `findCards` - Search for cards
282
+ - `cardsToNotes` - Get note IDs from card IDs
283
+ - `cardsInfo` - Get card details
284
+ - `suspend` - Suspend cards
285
+ - `unsuspend` - Unsuspend cards
286
+ - `areSuspended` - Check if cards are suspended
287
+ - `areDue` - Check if cards are due
288
+ - `getIntervals` - Get card intervals
289
+
290
+ #### Media
291
+ - `getMediaDirPath` - Get media directory path
292
+ - `storeMediaFile` - Store a media file (base64)
293
+ - `retrieveMediaFile` - Retrieve a media file
294
+ - `deleteMediaFile` - Delete a media file
295
+
296
+ ## 🤖 MCP Server
297
+
298
+ The server includes a Model Context Protocol (MCP) integration for AI assistants.
299
+
300
+ ### Starting the MCP Server
301
+
302
+ ```bash
303
+ uv run mcp-server
304
+ ```
305
+
306
+ ### Available MCP Tools
307
+
308
+ - `get_deck_names` - Get all deck names
309
+ - `get_deck_names_and_ids` - Get decks with IDs
310
+ - `create_deck` - Create a new deck
311
+ - `delete_decks` - Delete decks
312
+ - `get_model_names` - Get all model names
313
+ - `get_model_field_names` - Get fields for a model
314
+ - `add_note` - Add a new note
315
+ - `find_notes` - Search for notes
316
+ - `get_notes_info` - Get note details
317
+ - `delete_notes` - Delete notes
318
+ - `find_cards` - Search for cards
319
+ - `get_cards_info` - Get card details
320
+ - `suspend_cards` / `unsuspend_cards` - Manage card suspension
321
+ - `are_suspended` / `are_due` - Check card status
322
+ - `get_card_intervals` - Get card intervals
323
+ - `get_all_tags` - Get all tags
324
+ - `add_tags` / `remove_tags` - Manage tags
325
+ - `get_media_dir_path` - Get media directory
326
+ - `store_media_file` / `retrieve_media_file` / `delete_media_file` - Media operations
327
+ - `change_deck` - Move cards between decks
328
+ - `cards_to_notes` - Convert card IDs to note IDs
329
+ - `get_deck_config` - Get deck configuration
330
+ - `get_model_templates` / `get_model_styling` - Model customization
331
+ - `get_api_version` - Get API version
332
+ - `import_package` / `export_package` - Import/export decks
333
+ - `sync` / `sync_media` / `get_sync_status` - Sync operations
334
+
335
+ ## 🐳 Docker
336
+
337
+ ### Building the Image
338
+
339
+ ```bash
340
+ docker build -t anki-connect-server .
341
+ ```
342
+
343
+ ### Running the Container
344
+
345
+ ```bash
346
+ docker run -d \
347
+ -p 8765:8765 \
348
+ -v /path/to/collection.anki21:/data/collection.anki21 \
349
+ -e ANKI_COLLECTION_PATH=/data/collection.anki21 \
350
+ -e ANKICONNECT_ANKIWEB_USER=your@email.com \
351
+ -e ANKICONNECT_ANKIWEB_PASS=your_password \
352
+ --name anki-connect-server \
353
+ anki-connect-server
354
+ ```
355
+
356
+ ### Docker Compose
357
+
358
+ ```yaml
359
+ version: '3.8'
360
+
361
+ services:
362
+ anki-connect-server:
363
+ build: .
364
+ ports:
365
+ - "8765:8765"
366
+ volumes:
367
+ - ./collection.anki21:/data/collection.anki21
368
+ environment:
369
+ - ANKI_COLLECTION_PATH=/data/collection.anki21
370
+ - ANKICONNECT_ANKIWEB_USER=${ANKIWEB_USER}
371
+ - ANKICONNECT_ANKIWEB_PASS=${ANKIWEB_PASS}
372
+ restart: unless-stopped
373
+ ```
374
+
375
+