CM-62578: Expose Cycode API v4 through CLI commands#435
CM-62578: Expose Cycode API v4 through CLI commands#435MaorDavidzon wants to merge 11 commits intomainfrom
Conversation
Integrate the standalone cycode-mcp server into the CLI, adding both CLI commands and MCP tools for the Cycode API v4. - Dynamic CLI commands generated from OpenAPI spec (cached 24h) - 138 read-only API tools added to MCP server (143 total with scan tools) - Typed CLI flags for all query parameters - Switched from mcp to fastmcp>=2.14.0 for from_openapi() support - All new commands marked as [EXPERIMENT] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integrate the standalone cycode-mcp server into the CLI, adding both CLI commands and MCP tools for the Cycode API v4. - Dynamic CLI commands generated from OpenAPI spec (cached 24h) - 138 read-only API tools added to MCP server (143 total with scan tools) - Typed CLI flags for all query parameters - Switched from mcp to fastmcp 2.14.6 for from_openapi() support - All new commands marked as [EXPERIMENT] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ehq/cycode-cli into CM-62578/expose-api-v4-cli-and-mcp # Conflicts: # poetry.lock # pyproject.toml
Revert MCP command to original, remove fastmcp/httpx deps, remove async_auth_client. MCP server enhancement will be a separate PR. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace custom _get_access_token with CycodeTokenBasedClient (same pattern as scan/report commands) - URL-encode path parameters to prevent path traversal - Remove redundant cached token fallback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use auth client for spec fetch (retries, headers, SSL handling) - Rename _resolve_credentials to public resolve_credentials - Replace SystemExit(1) with click.Abort for proper framework cleanup - Document monkey-patch of typer.main.get_group - Remove unused requests import from openapi_spec Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Spec fetch during CLI startup now has a 3-second timeout to avoid blocking the regular flow. If it times out, a background thread continues fetching so the cache is warm for the next run. When cached, there is no network call at all. Also fixes ruff format issue. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Derive CLI command names from URL path structure instead of parsing
English summaries. Rules:
- Strip common prefix shared by endpoints in the tag
- Remove path param segments ({id})
- Nothing left: 'list' (collection) or 'view' (single resource)
- Otherwise: use remaining path segments as the name
- Fix redundancy: 'cycode groups groups' -> 'cycode groups list'
- Duplicates (deprecated endpoints) get -v2 suffix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Atomic cache write (temp file + rename) prevents corrupt cache if process is killed mid-write - Skip endpoints marked deprecated:true in OpenAPI spec - Remove dead snake_case redundancy check - Add 25 unit tests for pure functions (path naming, prefix detection, spec parsing, deprecated flag handling) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Alpine 3.21 repo rotated musl-dev from r9 to r11, breaking the build with "unable to select packages". Other pinned packages (gcc, libffi-dev, git) are still at the same revision. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
I think we should put all the commands under an api namespace so like cycode api violations right now its really cluttering up the main commands and means we can have naming collisions. This is similar to what github is doing for their CLI. Also if we do this it means when we run unrelated tasks we wont have pull the swagger file, we should try and do this as when CLI is run in CI/CD it will never be hitting cache.
Here is an example of where you get some annoying logging in a command due to the call for openAPI being made in the background.
poetry run cycode status
[04/13/26 10:34:02] WARNING [API Command] Could not load OpenAPI spec: Cycode credentials not found. Run `cycode auth` first, or set CYCODE_CLIENT_ID and CYCODE_CLIENT_SECRET environment variables. api_command.py:128
Program: cycode
Version: 0.0.0
Os: Darwin
Arch: arm64
Python version: 3.13.7
Installation id: xxxx
App url: https://app.cycode.com
Api url: https://api.cycode.com
Is authenticated: False
User id: None
Tenant id: None
Supported modules:
Secret scanning: False
Sca scanning: False
Iac scanning: False
Sast scanning: False
Ai large language model: False
....
Lastly we will need to add documentation to the Readme for these new commands. Having it under the api namespace will make this a bit easier I think in explaining generally what it does since its dynamic
|
Great feedback, thank you — all three points are valid. You're right about the concrete issues:
On namespacing, going with I looked at how other CLIs handle this. Since we can't easily bundle the spec (it's tenant-aware and changes more frequently than CLI releases), namespacing is the right call. Plan:
|
Summary
app.cycode.comand cached locally for 24h[EXPERIMENT]Examples
Projects
cycode projects list --page-size 10 --query "Frontend" cycode projects view 29303 cycode projects collisions --project-id 123 cycode projects collisions-count --project-id 123 cycode projects assets --project-id 123Violations
Workflows
Members
Compliance
Audit logs
Scans & statistics
Other resources
Discovery
Architecture
app.cycode.com/v4/api-docs/cycode-api-swagger.jsonwith a 3s timeoutlistfor collections,viewfor single resources/violations/count→countCycodeTokenBasedClient(same as all other CLI commands)Test plan
cycode projects list --page-size 2returns project datacycode violations list --severity Critical --status Openreturns filtered violationscycode projects view <ID>returns single project (path param)cycode violations count --severity Highreturns countcycode workflows listreturns workflowscycode members rolesreturns rolescycode --helpshows API command groups with [EXPERIMENT] labelJira: CM-62578
🤖 Generated with Claude Code