<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Touches authentication/login flow, credentials-file permissions, and
subprocess lifecycle behavior across platforms; while mostly defensive,
regressions could impact login or process management on Windows/macOS
runners.
>
> **Overview**
> Improves Windows/cross-platform reliability across the CLI and MCP
server: OAuth login now binds the callback server to `127.0.0.1`, avoids
slow loopback reverse-DNS, adds a configurable callback timeout
(`--timeout` + env default), and opens URLs via a Windows-friendly
`_open_browser` to avoid flashing console windows.
>
> Centralizes CLI output via a shared `console` that forces UTF-8 on
Windows, standardizes UTF-8 file reads/writes throughout, tightens
credentials-file permissions on Windows using `icacls`, and adds shared
Windows subprocess helpers for **no-window** process creation and
graceful termination (used by `deploy`, MCP reload, and usage-tracking
worker).
>
> Updates client configuration UX/robustness (Windows AppData resolution
via `platformdirs`, Cursor config path fallbacks + compatibility writes,
overwrite warnings, absolute `uv` path for GUI clients, safer path
display) and improves `deploy` child-process handling to avoid
pipe-buffer deadlocks while giving better debug-aware error messages.
>
> Expands CI to run tests on Linux/Windows/macOS, adds a no-auth CLI
integration workflow, disables usage tracking in toolkits CI, and adds
extensive regression tests for Windows signals, subprocess cleanup,
UTF-8, and config-path edge cases; bumps `arcade-core` to `4.4.2` and
`arcade-mcp-server` to `1.17.2` (with updated dependency pin).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0fabd8ca1cd647039ba6ddbdf3f7809c330bab9e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Summary
- Removes the `Hint` column from `arcade secret list` table output —
secret hints were removed from the API in
[monorepo#322](https://github.com/ArcadeAI/monorepo/pull/322), causing a
`KeyError: 'hint'` crash
- Adds a test for `print_secret_table` with populated secrets (verifying
no hint column)
- Bumps version from 1.10.0 → 1.11.0
Closes TOO-444
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add Attio to the wellknown OAuth2 provider classes so toolkits can use
Attio(scopes=[...]) instead of OAuth2(id=..., scopes=[...]).
---------
Co-authored-by: Eric Gustin <eric@arcade.dev>
@EricGustin you can use this cli command:
```
uv run arcade evals mcp_building_evals_results/eval_toolkit_iteration_dict.py \
-p openai:gpt-4o,gpt-4o-mini \
-p anthropic:claude-sonnet-4-20250514 \
-k openai:$OPENAI_API_KEY \
-k anthropic:$ANTHROPIC_API_KEY \
-d \
--num-runs 3 \
--seed random \
--multi-run-pass-rule majority \
--max-concurrent 6 \
-o mcp_building_evals_results/results
```
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches core eval execution and all result formatters while adding new
CLI inputs and output schema (`run_stats`/`critic_stats` and capture
`runs`), so regressions could affect evaluation results and report
compatibility despite being additive and validated.
>
> **Overview**
> Adds **multi-run evaluation support** to `arcade evals` via new flags
`--num-runs`, `--seed`, and `--multi-run-pass-rule`, with upfront
validation and plumbing through the CLI runner into eval/capture suite
execution.
>
> Fixes provider selection UX/bug by making `--use-provider/-p`
**repeatable** (instead of a space-delimited string), updates
docs/examples accordingly, and extends capture mode to optionally record
**per-run tool calls** (`CapturedRun`) when `num_runs > 1`.
>
> Enhances all output formatters (HTML/Markdown/Text/JSON) to
**propagate and display** per-case `run_stats` and `critic_stats`,
including new HTML UI for run tabs/cards and comparative tables showing
mean ± stddev when multi-run data is present.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2ee1654b7d1fbb9538373507355636164b16a066. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
we actually don't want to deprecate ToolExecutionError
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: behavior change is limited to no longer emitting a
`DeprecationWarning` when `ToolExecutionError` is instantiated, plus a
patch version bump.
>
> **Overview**
> `ToolExecutionError` is no longer treated as deprecated: the
`warnings` import and runtime `DeprecationWarning` emission were
removed, and the class docstring was updated to describe it as the base
exception for errors raised from within a tool body.
>
> Bumps `arcade-core` version from `4.2.2` to `4.2.3`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
250d20e393a8a4d8dc20fad673a7faea1cba4797. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
When running `arcade_mcp_server` with `workers > 1`, uvicorn spawns
worker subprocesses that directly call `create_arcade_mcp_factory()`
without going through `main()`. Since `setup_logging()` is only called
in `main()`, these subprocesses have no logging configuration, causing:
1. Standard Python logging not intercepted by Loguru
2. DEBUG-level logs from libraries like urllib3 appearing when OTEL is
enabled
3. Inconsistent log formats between main process and workers
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches process-wide logging initialization for uvicorn worker
subprocesses, which can affect log levels/handlers and output across the
server. Functional impact is limited to observability but could change
verbosity when OTEL or libraries emit logs.
>
> **Overview**
> Fixes multi-worker/reload mode logging by configuring Loguru inside
`create_arcade_mcp_factory()` (using `ARCADE_MCP_DEBUG` to set `INFO` vs
`DEBUG`) so uvicorn-spawned worker subprocesses get the same
logging/interception as `main()`.
>
> Adds regression tests that assert the factory filters DEBUG logs by
default and enables them when `ARCADE_MCP_DEBUG=true`, and bumps
`arcade-mcp-server` to `1.15.2`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0c262eb9716ecbd589f1524842243a7aed80666e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
1. Resolves
[TOO-363](https://linear.app/arcadedev/issue/TOO-363/arcade-deploy-fails-when-additional-deps-are-added-to-the-server).
2. Resolves
[TOO-364](https://linear.app/arcadedev/issue/TOO-364/arcade-cores-tool-skip-logic-is-missing-case-for-direct-execution).
3. Resolves
[TOO-358](https://linear.app/arcadedev/issue/TOO-358/missing-evals-error-message-shows-wrong-command).
4. Resolves
[TOO-365](https://linear.app/arcadedev/issue/TOO-365/arcade-evals-unit-tests-are-hanging).
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Medium risk because it changes how `arcade deploy` spawns the server
process and adjusts toolkit discovery skip logic, which can affect
deployments and tool discovery; however, the changes are small and
covered by new unit/integration tests.
>
> **Overview**
> `arcade deploy` now starts the validation server using the project’s
`.venv` interpreter (via `find_python_interpreter`) instead of the CLI’s
own `sys.executable`, preventing missing dependency failures when the
CLI is installed in an isolated env.
>
> `arcade-core`’s `Toolkit.tools_from_directory` skip logic is hardened
to also skip the currently executing entrypoint by module name
(`__main__.__spec__.name`) when file paths don’t match (e.g., bundled
execution). CLI error printing now escapes plain messages to avoid rich
markup issues, and `arcade-evals` lock acquisition accepts an optional
timeout default.
>
> Adds unit tests for the new toolkit skip behavior and an integration
test that boots the MCP server via direct Python invocation to mirror
deployment behavior, and bumps `arcade-core`, `arcade-mcp-server`, and
root dependency versions accordingly.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e7785634c231c059f2e0bd1bc73a56bd7470a494. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
The 'MCP server started' events would fail to send to posthog if the CLI
was not installed. This PR fixes this by moving PostHog from being a
dependency of the CLI to a dependency of arcade-core.
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Aligns versions and dependency ranges across the CLI and server
packages; removes an unnecessary dependency.
>
> - Bump `arcade-mcp-server` to `1.14.2` and `arcade-mcp` to `1.8.1`
> - Update `arcade-core` constraint to `>=4.2.1,<5.0.0`; CLI now
requires `arcade-mcp-server>=1.14.2`
> - Remove `posthog` from CLI dependencies
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
69f8bb397737d4c01f57630863762109819dbc4f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
So even importing `fcntl` causes problems on windows. This PR replaces
fcntl with portalocker. Tests all pass, so I think we are good.
ref:
https://arcade-ai.slack.com/archives/C08K1SJ072S/p1767897850450239?thread_ts=1766186586.406019&cid=C08K1SJ072S
<img width="934" height="501" alt="Screenshot 2026-01-08 at 2 57 46 PM"
src="https://github.com/user-attachments/assets/1375b6b2-116c-44bd-bbe1-2157dd243d29"
/>
Closes ENGTOP-8
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Cross-platform file locking**
>
> - Replace `fcntl` with `portalocker` in
`arcade_core/usage/identity.py` (shared/exclusive locks); switch to
atomic `os.replace()`
> - Add `portalocker` dependency and bump `arcade-core` to `4.2.1`
>
> **Installation/CI**
>
> - New GitHub Actions workflow `test-install.yml` runs install/CLI
checks on macOS, Windows, and Linux for Python 3.10/3.12
> - Add `tests/install/test_install.py` and README to verify install,
`arcade` CLI availability, and `portalocker` locking behavior
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3fe98fbcbf177f51fdb0b7fc51b20060f7fc85ad. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
https://github.com/ArcadeAI/docs/pull/622 moved a lot of files to new
URLs
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Updates references to Arcade docs after site restructure and bumps
package versions.
>
> - Update docs URLs in `README.md`, `SECURITY.md`, contrib READMEs
(CrewAI, LangChain), and CLI template README to new `/en/...` paths
> - Update `documentation_url` in `arcade_mcp_server/server.py` error
message to the new "compare server types" doc
> - Bump versions: `arcade-mcp-server` to `1.14.1` and root `arcade-mcp`
to `1.7.2`
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
673b1ee7c2e5be6885ffd64914e7600b4685aaac. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
`arcade-mcp-server` version was not bumped in
https://github.com/ArcadeAI/arcade-mcp/pull/717, so this PR bumps
`arcade-mcp-server`, and then update's `arcade-mcp`'s dependency on
`arcade-mcp-server` by increasing the minimum version
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Bumps arcade-mcp-server to 1.13.0, updates arcade-mcp to 1.6.2, and
raises related dependency minimums (including example auth server).
>
> - **Versions**:
> - Bump `libs/arcade-mcp-server` project version from `1.12.0` to
`1.13.0`.
> - Bump `arcade-mcp` package version from `1.6.1` to `1.6.2`.
> - **Dependencies**:
> - Raise `arcade-mcp` dependency on `arcade-mcp-server` to `>=1.13.0`
in `pyproject.toml` (including `all` extra).
> - Increase example server
`examples/mcp_servers/authorization/pyproject.toml` minimum
`arcade-mcp-server` to `>=1.12.0`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8a4f606bd8d0b48dd50e3e8e836d31bb679c6eba. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Fixes [PLT-720: Refactor CLI to support multiple orgs +
projects](https://linear.app/arcadedev/issue/PLT-720/refactor-cli-to-support-multiple-orgs-projects)
This PR removes the legacy login flow (login to get an API key) from
Arcade CLI. Believe it or not, this flow predates the ability to get an
API key from the Dashboard, or even the Dashboard itself!
Notable changes:
**Legacy handling** - When a user with an existing `credentials.yaml`
updates the CLI, they will get instructions on fixing their old
credentials:
<img width="978" height="146" alt="Screenshot 2025-12-08 at 10 10 37"
src="https://github.com/user-attachments/assets/5aeaef2c-bef7-4642-a2f7-f917b257c94b"
/>
Any commands that require login (non-public commands) will be blocked
with the above message until `arcade logout / arcade login` is performed
again.
**New login flow**
```sh
arcade login
Opening a browser to log you in...
✅ Logged in as nate@arcade.dev.
Active project: Nate Barbettini's organization / Default project
Run 'arcade org list' or 'arcade project list' to see available options.
```
**List and set the active organization**
```sh
arcade org list
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ Name ┃ ID ┃ Default ┃ Active ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ Nate Barbettini's organization │ 1c64968e-fdc5-4c55-8612-2ce46cd7881b │ ✓ │ ✓ │
│ Sergio 743 │ 1f1f6184-58dc-4bac-bdde-b9184e43fdf3 │ │ │
└────────────────────────────────┴──────────────────────────────────────┴─────────┴────────┘
Use 'arcade org set <org_id>' to switch organizations.
```
```sh
arcade org set 1c64968e-fdc5-4c55-8612-2ce46cd7881b
✓ Switched to organization: Nate Barbettini's organization
Active project: Default project
```
**List and set the active project**
```sh
arcade project list
Active organization: Nate Barbettini's organization
Use 'arcade org list' and 'arcade org set <org_id>' to switch organizations.
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ Name ┃ ID ┃ Default ┃ Active ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ Default project │ 35166bf3-6e68-481e-bf16-f747fadc6c22 │ ✓ │ ✓ │
│ Second project │ 62963205-31ea-4fda-9fc4-af10db89c06f │ │ │
└─────────────────┴──────────────────────────────────────┴─────────┴────────┘
Use 'arcade project set <project_id>' to switch projects.
```
```sh
arcade project set 35166bf3-6e68-481e-bf16-f747fadc6c22
✓ Switched to project: Default project
```
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Migrates CLI to OAuth2 (PKCE) with saved org/project context, adds
org/project commands, rewrites Engine calls to org-scoped endpoints, and
bumps core packages.
>
> - **Auth & Config**
> - Implement OAuth2 Authorization Code + PKCE (`arcade_cli/authn.py`)
with local callback server and Jinja templates.
> - Persist tokens and active `context` (org/project) in
`credentials.yaml` via updated config models
(`arcade_core/config_model.py`).
> - Add token refresh and CLI config fetch utilities
(`arcade_core/auth_tokens.py`).
> - Detect legacy API-key credentials and block protected commands until
re-login; add `whoami` command.
> - **Org/Project Management**
> - New subcommands: `arcade org list|set`, `arcade project list|set`
(fetch via Coordinator).
> - **Engine API usage (org-scoped)**
> - Introduce org/project URL rewriting transports
(`arcade_core/network/org_transport.py`) and helpers
(`get_org_scoped_url`, `get_arcade_client`, `get_auth_headers`).
> - Update `deploy`, `server`, and `secret` commands to use Bearer
tokens and org-scoped paths; adjust log streaming/status, secrets CRUD,
and deployment workflows.
> - **CLI UX**
> - Replace legacy login URLs/constants; add success/failure HTML
templates for browser callback.
> - Tweak `dashboard` to health-check without credentials.
> - Usage tracking now includes `org_id`/`project_id` properties.
> - **Tests**
> - Update tests for dashboard, secrets, utils, and usage identity
(OAuth `/whoami`).
> - **Dependencies & Versions**
> - Bump packages: `arcade-core@4.0.0`, `arcade-mcp-server@1.12.0`,
`arcade-serve@3.2.0`, `arcade-tdk@3.3.0`; add `authlib`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
49702c2f74b9db15bb286d3ec71179b4e74a9134. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
# Valuable references for the reviewer:
- Docs PR: https://github.com/ArcadeAI/docs/pull/583
- Implements Phase 1 of the following planning doc:
https://linear.app/arcadedev/project/arcade-mcp-supports-mcp-auth-front-door-auth-7cbaa20cb054/overviewhttps://github.com/user-attachments/assets/79ad43fd-f5e8-4793-a1dd-18b35acefdc3
# PR Description
Adds OAuth 2.1 Resource Server authentication to arcade-mcp-server,
enabling HTTP MCP servers to validate Bearer tokens on every request.
This unlocks tool-level authorization and secrets support for HTTP
servers.
- Multiple authorization server support
- Granular token validation options (verify_exp, verify_iat, verify_iss)
- Environment variable configuration
- OAuth discovery metadata endpoint
(/.well-known/oauth-protected-resource)
- Extracts sub claim from token as context.user_id
- Lifts transport restrictions for tools requiring auth/secrets on HTTP
when protected
```python
from arcade_mcp_server import MCPApp
from arcade_mcp_server.resource_server import ResourceServerAuth, AuthorizationServerEntry
resource_server_auth = ResourceServerAuth(
canonical_url="http://127.0.0.1:8000/mcp",
authorization_servers=[
AuthorizationServerEntry(
authorization_server_url="https://auth.example.com",
issuer="https://auth.example.com",
jwks_uri="https://auth.example.com/jwks",
)
],
)
app = MCPApp(name="my_server", version="1.0.0", auth=resource_server_auth)
```
# Testing
Beyond the comprehensive unit tests, I also manually tested end-to-end
with WorkOS Authkit (DCR) and KeyCloak (non-DCR).
# Future Work
- CIMD support
- An `ArcadeResourceServer` to make adding front-door auth super easy
when using Arcade's Auth Server
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds OAuth 2.1 front-door auth (JWKS validation + OAuth discovery) and
propagates user identity to tools, enabling auth/secret-requiring tools
over HTTP.
>
> - **Authentication (Front-Door OAuth 2.1)**
> - New `resource_server` module with `ResourceServerAuth`
(multi-authorization-server, metadata) and `JWKSTokenValidator`
(JWKS-based JWT validation) plus granular validation options.
> - ASGI `ResourceServerMiddleware` validates Bearer tokens on every
HTTP request and injects `resource_owner`.
> - OAuth discovery endpoint via FastAPI router at
`/.well-known/oauth-protected-resource[/<path>]`.
> - **Integration**
> - `MCPApp`/`worker` accept `auth`/`resource_server_validator`, mount
middleware, expose discovery; logs accepted auth servers.
> - HTTP transport (`http_streamable`) carries `SessionMessage` with
`resource_owner` from request → session.
> - `Context`/`Session`/`Server` plumb `resource_owner`; `Server`
selects `user_id` preferring token `sub`.
> - **Behavior Changes**
> - HTTP transport restriction lifted for tools requiring
`authorization`/`secrets` when request is authenticated; otherwise
blocked with actionable error.
> - **Configuration**
> - Env-var based auth config via `MCP_RESOURCE_SERVER_*` in
`MCPSettings.ResourceServerSettings`; `.env` auto-load.
> - **Telemetry**
> - Usage tracking records `resource_server_type` on server start.
> - **Examples**
> - New `examples/mcp_servers/authorization` sample server (HTTP auth,
secrets, Reddit tool) with Docker setup.
> - **Tests**
> - Extensive unit tests for validators, middleware, env config,
multi-AS, transport rules, and app integration.
> - **Version**
> - Bump `arcade-mcp-server` to `1.12.0`; minor docstring tweak in
`__init__.py`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d1116cdcafb0c7cb8f91e66682eb1fbae380da31. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Resolves TOO-152
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Adds --workers to HTTP mode with validation, refactors server
startup/discovery for multi-process uvicorn, and removes all
Docker-related files/configs.
>
> - **MCP Server (HTTP mode)**
> - Add `--workers` arg to run multiple uvicorn workers; block `workers
> 1` with `stdio`, and `reload` with multiple workers.
> - Refactor startup: move tool discovery/config into
`create_arcade_mcp_factory()` driven by env vars; use `uvicorn.run(...,
workers=...)` for multi-worker/reload; retain `serve_with_force_quit()`
only for single-worker.
> - Adjust CLI to only discover tools in `stdio` path; HTTP path now
delegates discovery to the factory.
> - **MCPApp**
> - Minor run path cleanup; continue using `serve_with_force_quit()` for
single-worker HTTP.
> - **Ops/Packaging**
> - Remove `docker/` directory and all Dockerfiles, compose/configs, and
docs.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c5700ac8855173c1e82c6f7e41b30ca173aaec14. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
New and improved error message
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Enhances dependency checks to display uv/pip install commands and
updates evals command accordingly; bumps package version to 1.5.9.
>
> - **CLI utils**:
> - Update `require_dependency` to accept `uv_install_command` and
`pip_install_command` and format error message with both install
options.
> - **Evals command (`arcade_cli/main.py`)**:
> - Update `require_dependency` calls for `arcade_evals` and
`arcade_tdk` to provide uv/pip install commands.
> - **Version**:
> - Bump `project.version` in `pyproject.toml` from `1.5.8` to `1.5.9`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
217a6a87686e27747ef59d66bc0db05a270b294a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Other packages that depend on `arcade_mcp_server` will now be able to
use the type information that `arcade_mcp_server` provides
Avoids mypy errors like the following:
`arcade_google_drive/tools/folders.py:12: error: Argument 1 to
"create_folder" becomes "Any" due to an unfollowed import
[no-any-unimported]`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Add `arcade_mcp_server/py.typed` to expose inline type hints and bump
package version to 1.11.2.
>
> - **Types**:
> - Add `arcade_mcp_server/py.typed` to publish inline type hints to
dependents.
> - **Packaging**:
> - Bump `version` in `libs/arcade-mcp-server/pyproject.toml` from
`1.11.1` to `1.11.2`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f566b0acddc9174411896a01d03018cd34cf95cb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Update `arcade-core` and `arcade-tdk` dependency versions to resolve
`ImportError` caused by incompatible `Figma` auth provider imports.
The `Figma` OAuth2 provider was introduced in `arcade-core` 3.3.5.
`arcade-tdk` 3.2.0 and `arcade-mcp-server` 1.10.2 started importing
`Figma`, but their `pyproject.toml` dependency constraints were not
updated to require `arcade-core>=3.3.5`. This led to `ImportError` when
`arcade-tdk` or `arcade-mcp-server` were installed with an older
`arcade-core` version. This PR updates the minimum required versions in
`pyproject.toml` files across `arcade-tdk`, `arcade-mcp-server`, and the
root project to ensure compatibility.
---
Linear Issue:
[TOO-231](https://linear.app/arcadedev/issue/TOO-231/worker-fails-to-start-due-to-arcade-core-auth-import)
<a
href="https://cursor.com/background-agent?bcId=bc-4383bd24-eb8c-4d2e-bafe-c116a9d83e8b"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a> <a
href="https://cursor.com/agents?id=bc-4383bd24-eb8c-4d2e-bafe-c116a9d83e8b"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Align dependency minimums to `arcade-core>=3.3.5` and
`arcade-tdk>=3.2.0` and bump package versions across projects.
>
> - **Dependencies**:
> - Raise `arcade-core` minimum to `>=3.3.5,<4.0.0` in
`libs/arcade-mcp-server/pyproject.toml`,
`libs/arcade-tdk/pyproject.toml`, and root `pyproject.toml`.
> - Raise `arcade-tdk` minimum to `>=3.2.0,<4.0.0` in
`libs/arcade-mcp-server/pyproject.toml` and root `pyproject.toml`.
> - **Version bumps**:
> - `libs/arcade-mcp-server` version `1.10.2` → `1.10.3`.
> - `libs/arcade-tdk` version `3.2.0` → `3.2.1`.
> - Root package `arcade-mcp` version `1.5.6` → `1.5.7`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
abec5dff0d18c9e9c1c5a0ceafa73c67b6af661a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Closes TOO-192
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds a Figma OAuth2 auth provider and wires it through TDK and MCP
server, with tests updated and package versions bumped.
>
> - **Auth**:
> - Add `Figma` OAuth2 provider in
`libs/arcade-core/arcade_core/auth.py`.
> - **Exports**:
> - Expose `Figma` in
`libs/arcade-mcp-server/arcade_mcp_server/auth/__init__.py` and
`libs/arcade-tdk/arcade_tdk/auth/__init__.py` (`__all__`).
> - **Tests**:
> - Add Figma auth requirement test case in
`libs/tests/tool/test_create_tool_definition.py` and import `Figma`.
> - **Versioning**:
> - Bump `arcade-mcp-server` to `1.10.2` and `arcade-tdk` to `3.2.0`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2bacfdc5695b3e7fc5e4532dbd360c3b2263130e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Francisco Liberal <francisco@arcade.dev>
This PR does three things:
1. Executes synchronous tool calls in thread pool allowing for up to 4 +
# of CPUs executions in parallel.
2. Makes force quitting via double SIGINT/SIGTERM possible and via
single SIGINT/SIGTERM + graceful shutdown timeout expiry possible, even
if there are active connections.
3. Sets `timeout_graceful_shutdown` to
`ARCADE_UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN` env var if set, else defaults
to 15.
4. Disable the worker health check span to reduce noise
Tradeoffs:
Since this PR introduces executing synchronous tools via `await
asyncio.to_thread(func, **func_args)`, this means that there is no way
for the thread to be killed until it finishes. The ramifications of this
is that the force quitting logic that is also implemented in this PR has
to be very harsh `os._exit(1)` just in case there is a sync tool
actively executing. This means that `MCPApp` teardown logic will not
execute when force quitting is required. Although this was already the
case because we weren't previously able to force quit! This tradeoff is
justified for now since "parallel" tool executions will relieve us of
many worker timeouts that we are seeing in prod.
Future work:
Minimize/eliminate the need for `os._exit(1)` such that `MCPApp`
teardown logic will always execute, even when force quitting. The
solution will likely be moving away from `await asyncio.to_thread(func,
**func_args)` (while maintaining "parallelism" and then utilize the
`TaskTrackerMiddleware` introduced in this PR to cancel all of the
active HTTP requests.
Resolves PLT-713
Reponse 403 was returning RateLimiting all the time, but it was due only
checking if rate limiting header exists, but it should be checked if it
is 0 also.
---------
Co-authored-by: Francisco Liberal <francisco@arcade.dev>
…ng in WSL
When running `arcade configure claude` in WSL, the configuration file
was being written to the WSL filesystem
(~/.config/Claude/claude_desktop_config.json) instead of the Windows
AppData directory where Claude Desktop actually reads it.
This commit adds:
- WSL detection via WSL_DISTRO_NAME env var and /proc/version
- Windows username retrieval when running in WSL
- Updated config path functions to use Windows paths when in WSL
- Applied the same fix to Cursor and VS Code config paths for
consistency
The fix ensures that when running in WSL, the config file is written to:
/mnt/c/Users/{username}/AppData/Roaming/Claude/claude_desktop_config.json
This allows Claude Desktop on Windows to properly detect and use the MCP
server configuration.
Fixes#681
Co-authored-by: Claude <noreply@anthropic.com>
Since servers managed by Arcade use the `/worker` routes under the hood,
tools that use MCP-specific properties of `Context` will fail.
This PR helps reduce the 'blast radius' of the above fact. For
properties that were deemed 'non-critical' to the execution of a
deployed tool, we simply no-op. For properties that were deemed
'critical' to the execution of a deployed tool, we raise an error that
informs the caller that the feature is not supported for Arcade managed
servers.
- Non-critical property: A context property that returns None
- Critical property: A context property that may return something that
could be necessary for a tool execution to succeed.
Another small one.
When you `arcade deploy`, you need to
1. Run the command from the root of your project, and
2. Specify the relative path to your entrypoint file if it is not
located at the root of your repository or if it is named something other
than `server.py`.
Server start events were sometimes not being tracked because of a race
condition. Adding 150ms wait for now. Longer term solution:
https://app.clickup.com/t/86b7bm6kp
Other events do not suffer from this issue
#672 was a quick fix. This PR makes it a long term fix.
Whether a tool is added via `MCPApp.add_tools_from_module`,
`MCPApp.add_tool`, or `@app.tool`, the server's version and description
will be the same.
### The Bug:
When an entrypoint file imports its parent package and
calls add_tools_from_module() on that package, and the same entrypoint
file also defines tools using @app.tool or @tool decorators, then the
server fails to start with an `AttributeError`. This is because the
tools would be discovered via AST parsing, but those tools weren't added
to the module's namespace yet because the file is still executing.
For example, this would fail on startup:
```py
#!/usr/bin/env python3
"""local_filesystem MCP server"""
import sys
from typing import Annotated
from arcade_mcp_server import MCPApp
import local_filesystem
app = MCPApp(name="eric_server", version="1.0.0", log_level="DEBUG")
app.add_tools_from_module(local_filesystem)
@app.tool
def eric(name: Annotated[str, "The name of the person to greet"]) -> str:
"""Greet a person by name."""
return "return"
if __name__ == "__main__":
transport = sys.argv[1] if len(sys.argv) > 1 else "stdio"
app.run(transport="http", host="127.0.0.1", port=8074)
```
### The fix:
Skip the entrypoint file. This means that any tool defined inside of the
entrypoint file must be added via MCPApp.add_tool(...) or instead use
the recommended @app.tool.
We are now tracking whether a tool call event happens. We track generic
"failure reasons" if the tool call fails. We DO NOT track names of
tools, tool parameters, or any PII.
Event name:
- MCP tool called
Properties:
- is_execution_success
- failure_reason - one of "missing requirements", "transport
restriction", "error during tool execution", "unknown tool", "internal
error calling tool" or doesn't exist in the case of successful tool
execution.
- arcade_mcp_server_version
- runtime_language
- os_type
- os_release
- device_timestamp
As always you can opt out via setting the `ARCADE_USAGE_TRACKING`
environment variable to 0.