Appcircle MCP Server¶
How It Works¶
Model Context Protocol (MCP) is an open protocol that lets an AI client connect to external tools and data sources in a consistent, structured way. An MCP client discovers what a server can do (via tools/list) and invokes specific tools by name with typed arguments, enabling the AI to perform real actions rather than only generating text.
The Appcircle MCP Server is a Python MCP server that exposes Appcircle CI/CD capabilities (builds, signing identities, testing distribution, publish-to-stores operations, enterprise app store, and reporting) as MCP tools. This turns MCP clients (Claude Desktop, Cursor, etc.) into controlled operators that can safely fetch Appcircle configuration and operational data through the tool interface.
Details¶
Tool Registration and Transport¶
- The MCP server registers toolsets (groupings of related tools) and individual tools under those toolsets.
- Your MCP client connects to the server via local
stdioor localstreamable-httpand calls tools by name. - The server translates tool invocations into authenticated Appcircle API requests and returns structured responses (or structured errors) using a shared contract.
Example Interactions¶
User asks: List my build profiles and show me the workflow details for the first one.
Your build profiles (9 total)
CodePushTest (bafbb6bc-c652-46a2-ba09-fd134e1924ce) repo: rn-code-push-app-test
CacheTest-Android-Flutter (868aba31-...) repo: appcircleio/appcircle-sample-flutter
...
Workflows for CodePushTest:
Default Push Workflow, last used: 2025-10-08
Default PR Workflow, last used: null
User asks: Give me a build history report for the last 30 days and summarize the success vs failure ratio.
Build history report (2026-03-01 to 2026-03-30): 2 builds total.
Success: 1 | Failure: 1
Success rate: 50% | Failure rate: 50%
Project Structure¶
| Path | Role |
|---|---|
src/config/settings.py |
Server configuration, allowed toolset IDs, runtime validation, exclusion logic |
src/core/api_client.py |
Async HTTP client (httpx) for authenticated Appcircle API requests |
src/core/auth.py |
Per-request token handling via contextvars, with fallback to global token |
src/core/error_handler.py |
Maps API/transport exceptions to the shared MCP error envelope |
src/core/logger.py |
Application logger emitting to stderr with configurable log level |
src/schemas/responses.py |
Pydantic response envelope models (success_response, error_response) |
src/tools/ |
Tool implementations organized by toolset (build, signing, testing, publish, enterprise, report) |
test/ |
Unit tests (mocked HTTP) and integration tests (real API calls) |
pyproject.toml |
Project metadata, dependencies, CLI entrypoint, pytest/coverage config |
Environment Variables¶
| Variable | Required | Description |
|---|---|---|
APPCIRCLE_ACCESS_TOKEN |
Yes (stdio) | Appcircle API bearer token. For streamable-http, a per-request Authorization: Bearer header is used instead. |
APPCIRCLE_API_URL |
No | Overrides the API base URL (default: https://api.appcircle.io). |
APPCIRCLE_MCP_PORT |
No | Bind port for streamable-http transport (default: 8000). |
APPCIRCLE_MCP_ALLOWED_HOST |
No | Enables DNS rebinding protection and specifies allowed hostname(s). |
APPCIRCLE_EXCLUDED_TOOLSETS |
No | Comma-separated toolset IDs to exclude from registration. |
LOG_LEVEL |
No | Logging level (e.g. DEBUG, INFO; default: INFO). |
Info
Integration tests use additional variables: APPCIRCLE_TEST_COMMIT_ID, APPCIRCLE_TEST_BRANCH_ID, and APPCIRCLE_TEST_ORGANIZATION_ID.
Repository and Client Setup¶
- Repositories:
- Private repo (https://github.com/appcircleio/ac-mcp): This repo contains the release pipeline, the service hosted from mcp.appcircle.io is released from here.
- Public repo (https://github.com/appcircleio/appcircle-mcp): This is the public-facing mirror repo. It contains the codebase, docs and example dockerfile. The codebase between private and public repo should always kept synced. This mirror repo is designed so the release pipeline details won't be public to others.
- Client installation guides (Claude Desktop, Cursor, Codex, VS Code, Windsurf, Gemini CLI, GitHub Copilot CLI) are under
docs/installation_guides/. - Shared tool response contract:
docs/tool_contract.md.
Continuing Development¶
Tip
When adding new tools, copy an existing tool module within the same toolset and adjust the endpoint(s), payload shape, parameters/filtering logic, and the data/meta response fields.
Follow this workflow:
- Add or extend tool functionality under
src/tools/<toolset>/. - Keep responses consistent with the shared envelope in
src/schemas/responses.py. - Use
src/core/api_client.pyfor API calls andsrc/core/error_handler.pyfor exception mapping. - Ensure the toolset ID is registered in
src/config/settings.pyand that exclusions flow through startup correctly. - Add unit tests under
test/unit/and integration tests undertest/integration/.