feat: add Steam Workshop integration#28
Conversation
Add new steam_workshop.py endpoint module with 3 tools: - search_workshop_items: Search Workshop mods by game with text/tag filtering - get_workshop_item_details: Get detailed Workshop item information - get_workshop_collection: Get items from a Workshop collection Features: - Text search and tag filtering support - Sort by popular, trending, recent, or rating - JSON and text output formats - Graceful handling of games without Workshop support - Comprehensive error handling Also includes: - 20 unit tests with mocked API responses - README updated (32 → 35 tools) - CHANGELOG entry added 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes based on ml-python-mcp-expert review: Must-fix: - Filter None values from tag list comprehensions - Add logging import and log failed batch fetches instead of silent pass - Fix timezone-naive datetime to use UTC Should-fix: - Add input validation for workshop_id and collection_id - Standardize JSON error responses (remove extra fields) - Update endpoint description with 50-item limit note Tests: - Add tests for timestamp UTC formatting - Add tests for negative timestamps - Add input validation tests for empty/whitespace IDs - Add test for tag filtering with missing keys 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code Review Fixes AppliedBased on review by ml-python-mcp-expert agent, the following issues have been addressed: Must-Fix (4 items)
Should-Fix (4 items)
New Tests Added
All 242 tests pass ✅ |
The Steam API can return numeric fields as strings (e.g., "1000" instead of 1000). This caused TypeError: '<' not supported between 'str' and 'int'. Fixes: - Add _safe_int() helper for int coercion with default fallback - Add _safe_float() helper for float coercion with default fallback - Update _format_file_size() to handle string/None inputs - Update _format_timestamp() to handle string/None inputs - Apply _safe_int/_safe_float to all numeric API fields: - subscriptions, favorited, views, file_size - vote_data.score, votes_up, votes_down - result, file_type comparisons - time_created, time_updated Tests: - Add TestStringTypeCoercion class with 7 tests - Tests cover string values in search, details, and collection endpoints - Tests for _safe_int, _safe_float, and format functions with string input 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Type Safety Fixes AppliedFixed the Root CauseThe Steam API can return numeric fields as strings (e.g., SolutionAdded type coercion helpers and applied them throughout:
Fields Updated
New Tests Added (7 tests)
All 249 tests pass ✅ |
|
It is able to sort through individual workshop items correctly and all the user to filter however they want. However, the collections feature is flawed, the user currently needs to know the id of the collection in question, there is no way for the user to be able to just get the top 5 most popular collections. The collection endpoint needs to have sorting and filtering similar to that of the "search workshop items" tool. In its current state, its not very user-friendly |
Users previously needed to know collection IDs upfront. The new search_workshop_collections tool lets users browse and discover collections with the same sorting/filtering options as search_workshop_items: - Sort by popular, trending, recent, or rating - Text search support - Returns collection name, item count, subscriber count Also updated get_workshop_collection description to reference the new discovery tool. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Brings search_workshop_collections to feature parity with search_workshop_items - both now support: - app_id (required) - search_query (text search) - tags (array of Workshop tags to filter by) - sort_by (popular/trend/recent/rating) - max_results 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Was using filetype=2 (Artwork) instead of filetype=1 (Collections). Per Steamworks API docs, EPublishedFileInfoMatchingFileType values: - 0 = Items (regular mods) - 1 = Collections - 2 = Art - 3 = Videos 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
Adds Steam Workshop integration with 3 new tools for discovering, searching, and exploring mods and community content.
Changes
src/steam_mcp/endpoints/steam_workshop.pysearch_workshop_items- Search Workshop mods by game with text/tag filtering and sortingget_workshop_item_details- Get detailed Workshop item info (description, subscribers, dependencies)get_workshop_collection- Get items from a Workshop collectiontests/test_steam_workshop.pyFeatures
supports_json=TrueTesting
Checklist from Issue
steam_workshop.pyendpoint module with auto-discoverysearch_workshop_itemssupports text search, tag filtering, and sortingget_workshop_item_detailsreturns comprehensive item informationget_workshop_collectionreturns collection contentsCloses #5
🤖 Generated with Claude Code