🃏 MTG Wants - Cockatrice Deck Operations
A powerful Python CLI tool and library for performing arithmetic operations on Magic: The Gathering deck files in Cockatrice format (.cod). Perfect for deck management, inventory tracking, and wantslist generation for Cardmarket.
✨ Features
- 🔢 Deck Arithmetic: Add and subtract decks with
--addand--suboperations - 📦 Sideboard Support: Full support for sideboard management
- 🎯 Cardmarket Integration: Export formatted wantslists ready to paste into Cardmarket, automatically copied to clipboard
- 🔄 Sequential Operations: Chain multiple operations in exact order
- 📁 Cockatrice Compatible: Native support for Cockatrice .cod XML format
- 🐍 Python Library: Use as a CLI tool or import as a Python library
🎮 Use Cases
- Build a wantslist: Subtract your collection from a target deck to know what to buy
- Combine decks: Merge multiple decklists into one
- Track inventory: Keep your digital collection synchronized with physical cards
- Deck variations: Create deck variants by adding/removing specific cards
- Budget planning: Calculate exact cards needed for deck upgrades
📦 Installation
From PyPI (Coming Soon)
pip install mtgwants
From Source
git clone https://github.com/Firi0n/mtgwants.git
cd mtgwants
pip install -e .
📋 Requirements
- Python 3.10 or higher
- pyperclip (for clipboard support)
🚀 Quick Start
Basic Usage
# Save a single deck
mtgwants main.cod -o output.cod
# Create a wantslist: deck minus your collection
mtgwants deck.cod --sub collection.cod --print
# Combine multiple decks with sideboard
mtgwants deck1.cod --add deck2.cod --add deck3.cod --sideboard -o combined.cod
📖 Documentation
Command Line Interface
mtgwants MAIN_DECK [OPTIONS]
Required Arguments
MAIN_DECK: The primary deck file in Cockatrice .cod format
Deck Operations
| Option | Short | Description |
|---|---|---|
--add DECK.COD |
-a |
Add cards from deck file (repeatable) |
--sub DECK.COD |
-b |
Subtract cards from deck file (repeatable) |
Important: Operations are executed in the exact order you specify them on the command line. Order matters because subtraction doesn't produce negative quantities.
Other Options
| Option | Short | Description |
|---|---|---|
--sideboard |
-s |
Include sideboard from all decks |
--output FILE |
-o |
Save result to a .cod file |
--print |
-p |
Print cardlist to console (Cardmarket format) and copy it to clipboard |
--deck-name NAME |
-n |
Custom name for output deck (default: "Deck") |
--verbose |
-v |
Verbose output (use -vv for extra detail) |
Note: At least one of --output or --print must be specified.
📚 Examples
Example 1: Generate a Wantslist
You want to build a Commander deck but need to know which cards to buy:
mtgwants commander_deck.cod --sub my_collection.cod --sideboard --print
This outputs a formatted list and copies it directly to your clipboard, ready to paste into Cardmarket's wantslist.
Example 2: Combine Decklists
Merge several decklists into one master list:
mtgwants deck1.cod --add deck2.cod --add deck3.cod -o master_deck.cod
Example 3: Track Inventory
After buying cards, update your collection and recalculate what you still need:
mtgwants target_deck.cod --sub old_collection.cod --add new_cards.cod -o updated_needs.cod --print
Example 4: Short Form Syntax
Use abbreviated flags for quicker commands:
mtgwants main.cod -a extras.cod -b dupes.cod -o final.cod -p
Example 5: Order Matters
Operations are executed left-to-right in exact order:
# Add first, then subtract
mtgwants deck.cod --add new.cod --sub owned.cod -p
# Result: (deck + new) - owned
# Different order, different result
mtgwants deck.cod --sub owned.cod --add new.cod -p
# Result: (deck - owned) + new
Example 6: Debug with Verbose Output
See detailed information about each operation:
mtgwants main.cod -a extras.cod -b dupes.cod -o final.cod -vv
Output:
Loading main deck: main.cod
Main: 60 cards
Adding: extras.cod
Result main: 75 cards
Subtracting: dupes.cod
Result main: 60 cards
Saving to: final.cod
✓ Saved successfully
✓ Operations completed successfully
Final deck: 60 cards in main
🐍 Python Library Usage
Use mtgwants as a library in your Python projects:
from mtgwants import Card, Zone, Deck, CockatriceParser
# Create parser
parser = CockatriceParser(sideboard=True)
# Load decks
deck1 = parser.load("deck1.cod")
deck2 = parser.load("deck2.cod")
# Perform operations
combined = deck1 + deck2
needs = deck1 - deck2
# Access card data
for card, quantity in combined.main.items():
print(f"{quantity}x {card.name}")
# Save result
parser.save(combined, "output.cod", "My Combined Deck")
Core Classes
Card
Represents a Magic: The Gathering card identified by name.
card = Card("Lightning Bolt")
print(card.name) # "Lightning Bolt"
print(card.is_basic_land) # False
Zone
A multiset of cards with arithmetic operations (main deck, sideboard, etc.).
zone = Zone({Card("Lightning Bolt"): 4, Card("Counterspell"): 2})
print(len(zone)) # 6 (total cards)
print(zone.unique_cards) # 2 (different cards)
Deck
Complete deck with main zone and optional sideboard.
main = Zone({Card("Lightning Bolt"): 4})
side = Zone({Card("Counterspell"): 2})
deck = Deck(main, side)
print(deck.has_sideboard) # True
print(len(deck)) # 6 (main + sideboard)
# Get deck without basic lands
result = deck.nonland_deck
print(result.main_lands) # number of basic lands removed from main
print(result.side_lands) # number of basic lands removed from sideboard
print(result.deck) # filtered Deck
ZoneType
Enum for specifying which zone to operate on.
from mtgwants import ZoneType
deck.get_count(Card("Lightning Bolt"), zone=ZoneType.MAIN)
deck.items(zone=ZoneType.SIDEBOARD)
CockatriceParser
Parser for reading and writing .cod files.
parser = CockatriceParser(sideboard=True)
deck = parser.load("deck.cod")
parser.save(deck, "output.cod", "Deck Name")
🛠️ Technical Details
File Format
Cockatrice .cod files are XML files with the following structure:
<?xml version="1.0"?>
<cockatrice_deck version="1">
<deckname>My Deck</deckname>
<comments></comments>
<zone name="main">
<card number="4" name="Lightning Bolt"/>
<card number="2" name="Counterspell"/>
</zone>
<zone name="side">
<card number="3" name="Negate"/>
</zone>
</cockatrice_deck>
Cardmarket Export Format
The --print option generates output ready for Cardmarket's "Add a Deck List" feature, and automatically copies it to your clipboard:
4 Lightning Bolt
2 Counterspell
// Sideboard
3 Negate
Basic lands (Plains, Island, Swamp, Mountain, Forest, Wastes) are automatically excluded from the output.
After pasting into Cardmarket:
- Select all cards → Edit
- Set language, condition, and foil preferences
- Save your wantslist
Arithmetic Operations
Operations follow mathematical rules:
-
Addition: Combines card quantities
deck1 = Zone({Card("Bolt"): 2}) deck2 = Zone({Card("Bolt"): 2}) result = deck1 + deck2 # {Card("Bolt"): 4}
-
Subtraction: Removes cards (negatives become zero)
deck = Zone({Card("Bolt"): 4}) owned = Zone({Card("Bolt"): 2}) needs = deck - owned # {Card("Bolt"): 2}
-
Sequential Operations: Processed in exact command-line order (left to right)
mtgwants A.cod --add B.cod --sub C.cod --add D.cod # Equivalent to: (((A + B) - C) + D)
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🎯 Roadmap
- Cardmarket API integration (when/if they finally release it to private users)
💡 FAQ
Q: Why "mtgwants"?
A: The tool was originally designed to generate wantslists for Cardmarket by subtracting your collection from target decks.
Q: Does this work with other MTG software?
A: Currently only Cockatrice .cod format is supported. Other formats are planned.
Q: What about the Cardmarket API?
A: Cardmarket's API v3.0 for private users has been "coming soon" since 2021. Until then, use the --print option for manual import.
Q: Can I use this in my own Python project?
A: Absolutely! Import the library and use the Card, Zone, ZoneType, Deck, and CockatriceParser classes.
Q: The clipboard copy didn't work.
A: On some Linux systems you may need to install a clipboard backend: sudo apt install xclip or sudo apt install xsel.
🙏 Acknowledgments
- Cockatrice - Open source MTG client
- Cardmarket - European MTG marketplace
- The Magic: The Gathering community
📞 Contact
- GitHub: @Firi0n
- Project Link: https://github.com/Firi0n/mtgwants
⭐ If you find this tool useful, please consider giving it a star on GitHub!
Metadata
Release files for mtgwants 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mtgwants-0.1.1.tar.gz | 16.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mtgwants-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.6 kB
Release files / mtgwants-0.1.1.tar.gz
| Download URL | mtgwants-0.1.1.tar.gz |
|---|---|
| Size | 16.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c396b5807f5fc69196dd2dfd29b3acf06bdc48c81ffdbfc151ed6a9551d0ffbf
|
|
BLAKE2b-256 checksum How to use checksums |
316bb6e4e87b545a722e6f4b793fc81f95a2589ca85948c82caa4159926f8ea4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.20
|
Release files / mtgwants-0.1.1-py3-none-any.whl
| Download URL | mtgwants-0.1.1-py3-none-any.whl |
|---|---|
| Size | 14.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
67181ec02a4414962ab4a7f36dc7c72ced4e3f12b9861ec80f917f54805296d6
|
|
BLAKE2b-256 checksum How to use checksums |
f99f4cb4515c040a79a54bff916bc675187cf78478a6b6c50496c10f92aa02e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.20
|