Skip to content

feat: add bounded App Store Connect Code Mode - #29

Closed
keithah wants to merge 1 commit into
zelentsov-dev:mainfrom
keithah:codex/add-bounded-code-mode
Closed

keithah wants to merge 1 commit into
zelentsov-dev:mainfrom
keithah:codex/add-bounded-code-mode

Conversation

@keithah

@keithah keithah commented Sep 19, 2026 •

Copy link
Copy Markdown

Summary

  • add opt-in --code-mode exposing three bounded catalog and execution tools for MCP clients that cannot load all 502 domain tools
  • route bridged calls through the existing dispatcher and preserve read-only/mutation policy gates
  • update documentation, changelog, contributor guidance, and stdio smoke coverage

Verification

  • swift test — 1,870 tests in 139 suites passed
  • swift build -c release passed
  • default release-binary MCP stdio smoke — 502 tools passed
  • Code Mode release-binary MCP stdio smoke — 3 tools and structured error behavior passed
  • git diff --check passed

@zelentsov-dev

Copy link
Copy Markdown
Owner

Thanks for taking the time to put this together, @keithah!

After reviewing the proposal and implementation, we're going to pass on adding a JavaScript Code Mode gateway (--code-mode) to asc-mcp for a few architectural and technical reasons:

  1. Client-side MCP permission boundaries and ToolAnnotations:
    asc-mcp publishes explicit per-tool ToolAnnotations (readOnlyHint, destructiveHint) and relies on MCP clients enforcing per-tool approval policies (such as auto-allowing read tools while prompting the user before high-risk mutations like app_versions_submit_for_review, app_versions_release, pricing updates, or resource deletion). Routing both read queries and production mutations through a single asc_code_execute tool hides the underlying domain tool identity from the MCP client's permission layer.
  2. Existing catalog-scoping mechanisms:
    Modern MCP clients (Claude Code, Cursor, Codex, etc.) now support native deferred/lazy tool loading on the client side, and for hosts with strict active-tool caps, --workers remains our supported, zero-overhead way to scope the exposed catalog while preserving per-tool schemas, annotations, and manifest contract verification.
  3. Implementation issues in CodeMode.swift:
    • Bridge.callToolBlock() spawns an unstructured Task and blocks the calling Swift Concurrency cooperative thread with DispatchSemaphore.wait(timeout:) while awaiting actor-isolated WorkerManager execution, which risks cooperative pool starvation/deadlock and races on ExecutionResultBox if the semaphore times out before the Task finishes.
    • CodeModeRuntime.timeout (30s) is never wired to JSContext, so synchronous evaluateScript has no execution bound on non-terminating scripts.
    • Truncating the serialized CallTool.Result string with String(text.prefix(maxOutputLength)) before JSON.parse(__asc_call(...)) produces invalid JSON whenever a tool response exceeds 16 KB.

Appreciate your interest in the project! Closing this PR as not planned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants