A Model Context Protocol (MCP) server for interacting with the Mochi spaced repetition platform API. Provides comprehensive access to cards, decks, and templates management through Claude and other MCP-compatible clients.
- Complete API Coverage: All Mochi API endpoints for cards, decks, templates, and attachments
- Card Management: Create, retrieve, update, delete flashcards with markdown content
- Deck Organization: Hierarchical deck structures with nested decks
- Template System: Define reusable card templates with custom fields
- Media Attachments: Upload and manage images, audio, video, and other files on cards
- Pagination Support: Efficiently handle large collections of cards and decks
- Formatting Guide Resource: Complete card formatting reference accessible via MCP resources
-
Clone or download this repository
git clone <repository-url> cd mochi-mcp
-
Install dependencies
uv sync # Installs from pyproject.toml -
Get your Mochi API key
- Open the Mochi app
- Go to Account Settings → API Key
- Copy your API key
-
Configure your API key
Copy the example environment file:
cp .env.example .env
Edit
.envand replaceyour_api_key_herewith your actual API key:MOCHI_API_KEY=your_actual_api_key_here
-
Configure your Claude client
- For Claude Desktop: See Claude Desktop Configuration
- For Claude Code: See Claude Code Configuration
This project uses uv for dependency management.
- Python 3.11+
- uv package manager (or pip)
# Clone the repository
git clone <repository-url>
cd mochi-mcp
# Install dependencies automatically
uv syncpip install mcp httpxMethod 1: Environment File (Recommended)
-
Copy the example file:
cp .env.example .env
-
Edit
.envand add your API key:MOCHI_API_KEY=your_actual_api_key_here
Method 2: Environment Variable
export MOCHI_API_KEY="your_api_key_here"Where to get your API key:
- Open the Mochi app
- Navigate to Account Settings
- Find the API Key section
- Copy your API key
Edit your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add this configuration:
{
"mcpServers": {
"mochi": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mochi-mcp",
"run",
"mochi_mcp_server.py"
],
"env": {
"MOCHI_API_KEY": "your_api_key_here"
}
}
}
}Important:
- Replace
/absolute/path/to/mochi-mcpwith the actual path (e.g.,/Users/yourname/mochi-mcp) - Replace
your_api_key_herewith your actual Mochi API key - Restart Claude Desktop after saving
Alternative: If you created a .env file, you can omit the env section and the server will read from .env automatically.
Edit your Claude Code configuration file:
- macOS/Linux:
~/.config/claude/config.json
Add this configuration to the mcpServers section:
{
"mcpServers": {
"mochi": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mochi-mcp",
"run",
"mochi_mcp_server.py"
],
"env": {
"MOCHI_API_KEY": "your_api_key_here"
}
}
}
}Important:
- Replace
/absolute/path/to/mochi-mcpwith the actual path (e.g.,/Users/yourname/Developer/mochi-mcp) - Replace
your_api_key_herewith your actual Mochi API key - Restart Claude Code or start a new session after saving
Alternative: If you created a .env file in the project directory, you can omit the env section:
{
"mcpServers": {
"mochi": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mochi-mcp",
"run",
"mochi_mcp_server.py"
]
}
}
}Verify it's working: After restarting Claude Code, you should see Mochi tools and resources available. Try:
- List tools: The Mochi tools (create_card, list_decks, etc.) should appear
- Access resources:
mochi://formatting-guideandmochi://examplesshould be available
Create a new flashcard in a deck.
Parameters:
content(required): Markdown content of the carddeck_id(required): Deck ID that the card belongs totemplate_id(optional): Template ID to use for structured cardsarchived(optional): Whether the card is archivedreview_reverse(optional): Review in reverse order (bottom to top)pos(optional): Relative position in deck (lexicographic sorting)manual_tags(optional): Array of tags to add (without#prefix)fields(optional): Template field values as{field_id: {id, value}}
Example:
{
"content": "# What is spaced repetition?\n\n---\n\nA learning technique that involves reviewing information at increasing intervals.",
"deck_id": "btmZUXWM",
"manual_tags": ["learning", "memory"]
}Cloze Deletion Support:
Mochi supports cloze deletions (fill-in-the-blank cards) using double curly braces:
-
Simple deletions (all hidden together):
"The Shiba Inu is a breed of {{hunting dog}} from {{Japan}}." -
Grouped deletions (separate review schedules):
"The {{1::Shiba Inu}} is a breed of {{2::hunting dog}} from {{2::Japan}}."This creates two separate cards: one hiding "Shiba Inu" and another hiding the other two terms.
Note: Mochi uses {{number::text}} syntax, NOT Anki's {{c1::text}} format.
Example with cloze:
{
"content": "# Core Abilities\n\nThe two core abilities:\n1. {{1::Ability to quickly master hard things}}\n2. {{2::Ability to produce at an elite level}}",
"deck_id": "qsD9fcfN"
}Multi-Sided Cards:
Create cards with multiple sides (beyond question/answer) by separating content with ---:
{
"content": "# Question\n\nWhat is photosynthesis?\n\n---\n\n# Simple Answer\n\nPlants convert light to energy\n\n---\n\n# Detailed Explanation\n\n6CO₂ + 6H₂O + light → C₆H₁₂O₆ + 6O₂",
"deck_id": "btmZUXWM"
}During review, sides reveal sequentially. You can have unlimited sides to progressively disclose information.
Retrieve a specific card by ID.
Parameters:
card_id(required): Card ID to retrieve
List cards with optional filtering and pagination.
Parameters:
deck_id(optional): Filter cards by deck IDlimit(optional): Number of cards per page (1-100, default 10)bookmark(optional): Pagination cursor from previous request
Example:
{
"deck_id": "btmZUXWM",
"limit": 20
}Update an existing card's properties.
Parameters:
card_id(required): Card ID to updatecontent(optional): Updated markdown contentdeck_id(optional): Move card to different deckarchived(optional): Archive/unarchive cardtrashed(optional): ISO 8601 timestamp to soft-delete card- Plus other parameters from
create_card
Example:
{
"card_id": "QQJ8ssvL",
"content": "# Updated Question\n\n---\n\nUpdated Answer",
"manual_tags": ["updated", "learning"]
}Permanently delete a card and its attachments.
Warning: This cannot be undone. For soft deletion, use update_card with trashed timestamp.
Parameters:
card_id(required): Card ID to delete
Create a new deck for organizing cards.
Parameters:
name(required): Name of the deckparent_id(optional): Parent deck ID for nestingsort(optional): Sort order numberarchived(optional): Whether deck is archivedsort_by(optional): Card sort method:none,lexicographically,created-at,updated-at,retention-rate-asc,interval-lengthcards_view(optional): Display view:list,grid,note,columnshow_sides(optional): Show all card sides on deck pagesort_by_direction(optional): Reverse sort order if truereview_reverse(optional): Review cards in reverse order
Example:
{
"name": "Spanish Vocabulary",
"sort_by": "created-at",
"cards_view": "list"
}Retrieve a specific deck by ID.
Parameters:
deck_id(required): Deck ID to retrieve
List all decks with pagination.
Parameters:
bookmark(optional): Pagination cursor from previous request
Update an existing deck's properties.
Parameters:
deck_id(required): Deck ID to update- Plus other parameters from
create_deck
Example:
{
"deck_id": "RMb5BZ67",
"name": "Spanish Vocabulary - Beginner",
"archived": false
}Permanently delete a deck.
Warning: This cannot be undone. Cards and child decks are NOT deleted.
Parameters:
deck_id(required): Deck ID to delete
Create a card template with field definitions.
Parameters:
name(required): Template name (1-64 characters)content(required): Markdown content with field placeholders like<< Field name >>fields(required): Field definitions as{field_id: {id, name, type, pos, options}}pos(optional): Relative position for sortingstyle(optional): Styling options like{text-alignment: "left"}options(optional): Template options like{show-sides-separately?: false}
Field Types:
text: Plain text inputboolean: True/false checkboxnumber: Numeric inputdraw: Drawing canvasai: AI-generated contentspeech: Text-to-speechimage: Image fieldtranslate: Translation fieldtranscription: Audio transcriptiondictionary: Dictionary lookuppinyin: Chinese pinyinfurigana: Japanese furigana
Example:
{
"name": "Vocabulary Card",
"content": "# << Word >>\n\n**Definition:** << Definition >>\n\n**Example:** << Example >>",
"fields": {
"word": {
"id": "word",
"name": "Word",
"type": "text",
"pos": "a"
},
"definition": {
"id": "definition",
"name": "Definition",
"type": "text",
"pos": "b",
"options": {
"multi-line?": true
}
},
"example": {
"id": "example",
"name": "Example",
"type": "text",
"pos": "c",
"options": {
"multi-line?": true
}
}
},
"style": {
"text-alignment": "left"
}
}Retrieve a template by ID (useful for examining structure).
Parameters:
template_id(required): Template ID to retrieve
List all templates with pagination.
Parameters:
bookmark(optional): Pagination cursor from previous request
Update an existing template's properties.
Parameters:
template_id(required): Template ID to updatename(optional): Updated template name (1-64 characters)content(optional): Updated markdown content with field placeholdersfields(optional): Updated field definitionspos(optional): Updated position for sortingstyle(optional): Updated styling optionsoptions(optional): Updated template options
Example:
{
"template_id": "XYZ789",
"name": "Advanced Vocabulary Card",
"content": "# << Word >>\n\n**Definition:** << Definition >>\n\n**Etymology:** << Etymology >>\n\n**Example:** << Example >>"
}Permanently delete a template.
Warning: This cannot be undone. Cards using this template will need to be reassigned or updated.
Parameters:
template_id(required): Template ID to delete
Upload a media file attachment to a card.
Parameters:
card_id(required): Card ID to attach file tofile_path(required): Absolute path to the file to uploadfilename(optional): Custom filename to use (defaults to file's basename)
Supported file types: Images (jpg, png, gif), audio (mp3, wav, m4a), video (mp4, mov), and other media formats
CRITICAL - Audio Filename Restrictions:
Audio and media files MUST follow strict filename rules or they will fail to play in Mochi:
- ✅ Valid:
audio.mp3,sound123.mp3,voice.m4a,music.wav - ❌ Invalid:
audio_file.mp3(underscore),my-sound.mp3(dash),my sound.mp3(space)
Rules:
- Filename must be 4-16 alphanumeric characters
- No underscores, dashes, or spaces allowed
- File extension must be valid (.mp3, .wav, .m4a, etc.)
Example:
{
"card_id": "ABC123",
"file_path": "/Users/username/Pictures/paris.jpg",
"filename": "eiffel.jpg"
}Audio example (correct):
{
"card_id": "ABC123",
"file_path": "/Users/username/audio/pronunciation_example.mp3",
"filename": "audio123.mp3"
}Delete an attachment from a card.
Parameters:
card_id(required): Card ID containing the attachmentfilename(required): Filename of the attachment to delete
Example:
{
"card_id": "ABC123",
"filename": "eiffel-tower.jpg"
}-
Create a deck:
Use create_deck with name "Spanish Verbs" -
Create a template:
Use create_template with vocabulary fields -
Add cards:
Use create_card with template_id and field values -
Organize cards:
Use update_card to adjust positions or move between decks
List all cards in a deck, then update each with new tags
1. Get an existing template structure
2. Create new template based on that structure
3. Create multiple cards using the new template
List operations return:
docs: Array of items (cards, decks, or templates)bookmark: Cursor for next page (if more items exist)
Use the bookmark in subsequent requests to fetch the next page.
Items use lexicographic string sorting for position (pos field):
- Between positions "6" and "7", you can insert "6V"
- This allows flexible reordering without renumbering
The server uses HTTP Basic Auth with your API key as the username and an empty password. This is handled automatically.
- Soft delete: Set
trashed?to current ISO 8601 timestamp - Hard delete: Use delete operations (cannot be undone)
The MCP server provides two comprehensive documentation resources:
Mochi Card Formatting Guide (mochi://formatting-guide)
- Complete card formatting syntax reference
- Cloze deletions, multi-sided cards, markdown extensions
- Template field types and interactive elements
- Multimedia integration (images, audio, video)
- Best practices and common patterns
Usage Examples & Workflows (mochi://examples)
- Practical conversation examples
- Batch operation workflows
- Deck organization strategies
- Safe deletion procedures
- Troubleshooting common issues
- Template modification patterns
Usage in Claude Code:
User: "How do I format cloze deletions in Mochi?"
Claude: [Reads mochi://formatting-guide resource]
"Mochi uses {{number::text}} syntax..."
User: "Help me organize 50 Spanish vocabulary cards"
Claude: [Reads mochi://examples resource]
"Here's a proven workflow for organizing vocabulary..."
Accessing via MCP:
- Resources are automatically discovered by MCP clients
- Use resource URIs to access specific documentation
- Provides complete context for card creation and management
The server returns detailed error messages including:
- HTTP status codes
- Validation errors with specific field feedback
- API error responses
Example error response:
{
"errors": {
"content": ":content field cannot be nil."
}
}mochi-mcp/
├── mochi_mcp_server.py # Main MCP server implementation
├── pyproject.toml # Project dependencies (uv)
├── uv.lock # Dependency lock file
├── .venv/ # Virtual environment (created by uv)
└── README.md # This file
# Using uv
uv run mochi_mcp_server.py
# Or activate virtual environment
source .venv/bin/activate
python mochi_mcp_server.pyTest the server using the MCP Inspector or Claude Desktop.
Contributions welcome! Areas for enhancement:
- Complete CRUD operations for all resources (cards, decks, templates, attachments)
- Bulk import/export operations
- Review statistics and analytics (if/when API supports it)
- Advanced search and filtering
- Webhook support for sync operations
MIT License - feel free to use and modify for your needs.
For issues with:
- This MCP server: Open an issue on GitHub
- Mochi API: Contact Mochi support
- MCP protocol: See MCP documentation
- Added template update and delete operations
- Enhanced documentation with critical technical details:
- Audio filename restrictions (prevents playback failures)
- Multi-sided card syntax
- Complete field type reference
- Created comprehensive MOCHI_FORMATTING_GUIDE.md
- Added MCP resource support:
mochi://formatting-guide- Complete card formatting referencemochi://examples- Practical workflows and troubleshooting
- Complete CRUD coverage for all API resources
- Initial release
- Complete coverage of Mochi API
- Support for cards, decks, and templates
- Pagination support
- Comprehensive documentation