Apiv2 cmlapi methods#16
Merged
Merged
Conversation
Migrate 6 high-priority functions (delete/stop/restart/update/create_application, get_runtimes) from hand-rolled requests to cmlapi.CMLServiceApi. Add shared setup_client() to http_helpers.py. Fixes silent failures on delete, wrong URL patterns for stop/restart, and incorrect field names in get_runtimes. - Reduces ~676 lines of boilerplate to ~246 lines of typed SDK calls - Errors now properly surfaced via ApiException instead of silent success - upload_folder.py updated to reuse shared setup_client - Test assertions updated to accept cmlapi as valid HTTP transport
…m cmlapi cmlapi SDK returns datetime objects in responses which break JSON serialization in the MCP transport layer. Add serialize_result() to http_helpers that round-trips through json.dumps(default=str). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hand-rolled requests calls with cmlapi.CMLServiceApi methods across all function files. Adds setup_client() and serialize_result() to http_helpers.py as shared infrastructure. Key changes: - All tools now use typed SDK calls instead of manual URL construction - serialize_result() handles datetime serialization from SDK responses - create_registered_model uses CreateRegisteredModelRequest + Tag objects - list_project_files passes path as required positional arg - stdio_server.py: fix 4 tools returning dicts instead of JSON strings - Tests updated to mock cmlapi instead of requests - README updated with architecture note and cmlapi prerequisite - .gitignore: add .mcp.json (contains local credentials) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace TOOL_IMPLEMENTATIONS lambda dict with proper @mcp.tool() decorated functions so all tools appear in FastMCP tools/list. Previously only 58 of 104 tools were discoverable. Also fixes: - create_registered_model: handle both dict and plain string tags - test assertions updated for CreateRegisteredModelRequest object - list_project_files test: path is positional arg Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move cmlapi imports behind try/except (ApiException falls back to Exception) and inside function bodies (setup_client, create_registered_model). This allows the package to import and tests to collect without cmlapi installed — required for GitHub Actions CI where cmlapi is unavailable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When cmlapi is unavailable, ApiException = Exception was too broad — it caught ModuleNotFoundError from setup_client() and then crashed accessing e.status. Fix: define a placeholder ApiException class that only matches itself, so real errors fall through to except Exception. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
requestscalls to the officialcmlapiPython SDK usingCMLServiceApisetup_client()andserialize_result()helpers inhttp_helpers.py-7,320lines,+2,245lines across 103 filesWhy
The previous implementation manually constructed URLs, headers, payloads, and error handling in every function. Most tool functions had roughly 80–130 lines of repeated request-handling logic.
This caused several issues:
delete_applicationreturning success without actually deleting the application/stopvs:stopand/restartvs:restartMoving to the official SDK makes the implementation smaller, more consistent, and less prone to endpoint or payload drift.
What changed
All tool functions now use the common SDK flow:
Added shared SDK helpers in
http_helpers.py:setup_client(host, api_key)serialize_result(result)create_registered_modelnow uses typed SDK objects:CreateRegisteredModelRequestTagRaw dictionaries do not serialize correctly for this endpoint.
upload_fileremainsrequests-based because multipartPUTupload is not supported by the SDK.stdio_server.pyfixes:json.dumps(...)Tests updated to mock
cmlapiinstead ofrequests.README updated with:
Test plan
All unit tests pass:
Syntax check completed on all 107 function files.
MCP live testing against Workbench completed for tools, including:
Known limitations
list_experiment_runsdoes not support thesortparameter. The API returns400, which appears to be an upstream limitation.create_experiment_runvia API creates metadata only. Model artifacts still require MLflow running inside a CML session or job.403for non-admin users. This is expected behavior.