arcade-mcp: A Python Framework for MCP Servers With OAuth Handled Outside the Tool
MCP Server Framework and Tool Development library for building custom capabilities into agents.
At a glance
- What is it?
- arcade-mcp is an MIT-licensed Python framework for building Model Context Protocol servers and the tools inside them. Its distinguishing feature is delegated secret handling: tools declare the OAuth scopes or API keys they need, and the token is injected at call time rather than held by the client or the model.
- Who is it for?
- Adopt arcade-mcp if you are writing MCP tools in Python that call third-party APIs behind OAuth, and you would rather declare scopes than build a token store. Skip it if your tools are local-only and need no credentials, or if you cannot route calls through Arcade Cloud and do not want to implement Resource Server Auth yourself.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap arcade-mcp fills: MCP tools that need someone else's API
The Model Context Protocol defines how a client talks to a server, but it says nothing about where your tool gets its credentials. That is fine for a tool that reads a local file. It stops being fine the moment the tool calls GitHub, Linear, or Notion on behalf of a signed-in user. You then own an OAuth redirect flow, an encrypted token store, refresh scheduling, and per-call scope checks, none of which is the tool logic you actually wanted to write.
arcade-mcp targets exactly that gap. The README frames the use case as tools that are not already in the prebuilt catalog: internal APIs, custom OAuth providers, domain-specific integrations. It is a Python framework, so the audience is Python developers, and the README states it powers the prebuilt tools at Arcade.dev, which is the vendor's own catalogue. The framework is open source under MIT; the surrounding cloud service is not.
One number in the README is worth reading carefully rather than repeating: the claim that arcade-mcp powers 7,500+ prebuilt tools across 81 MCP servers. That is a statement about the vendor's catalogue, not about adoption of the library by third parties, and the repository material does not break it down further.
Decorators, context injection, and where the token actually lives
The core object is MCPApp, constructed with a name and version. Tools are registered with an @app.tool decorator, and the framework's decorator API is documented as covering the full MCP spec: tools, resources, prompts, sampling, elicitation, progress, and logging. A tool is an ordinary async Python function with a docstring that becomes its description and type-annotated parameters.
The mechanism that matters is requires_auth. A tool declares requires_auth=GitHub(scopes=["repo"]), and the README says Arcade handles the rest: prompting the end user to authorize, storing and refreshing tokens, and scoping them per call. Inside the function, the token is retrieved from the injected Context object via context.get_auth_token_or_empty(). The README states plainly that the client and the LLM never see the secret values.
That last property is the architectural claim to interrogate. The token is not passed as a tool argument, so it cannot appear in a model's context window or in a client-side transcript. The trade is that the injection step is performed by Arcade at runtime. The README describes the flow as happening when the tool is invoked through Arcade Cloud: the user gets a URL to complete the OAuth challenge in a browser, and on success the token lands in context for that call, with later calls reusing and refreshing it. So the isolation of secrets is real, but on the documented path it is provided by the hosted engine, not by the library alone.
Getting a server running: uv, arcade new, and the transport flag
The README gives a short path. Install the CLI as a tool with uv tool install arcade-mcp. Scaffold a server with arcade new my_server, which creates pyproject.toml, .env.example, and a server.py containing example tools. The minimal example defines app = MCPApp(name="my_server", version="1.0.0"), registers an @app.tool function, and calls app.run(transport="stdio") under a __main__ guard.
Transport selection is a positional argument at run time. uv run server.py starts stdio, which the README recommends for Claude Desktop and CLI tools. uv run server.py http starts HTTP with SSE, aimed at Cursor and VS Code, and serves documentation at http://127.0.0.1:8000/docs. Wiring the server into a client is a separate command rather than hand-edited JSON: arcade configure claude for Claude Desktop over stdio, arcade configure cursor --transport http --port 8080 for Cursor on local HTTP, and arcade configure vscode --entrypoint my_server.py for VS Code over stdio. The README points to arcade --help for the full CLI surface, and to examples/mcp_servers/ for patterns beyond the basics, including resources, sampling, progress reporting, tool chaining, and end-to-end agents.
Building from source requires Python 3.10 or higher and uv, with make install as the documented entry point. CONTRIBUTING.md covers the development workflow and SECURITY.md covers vulnerability reporting.
The OAuth helper classes and the long tail of providers
The README lists 22 helper classes for named providers: Asana, Atlassian, Attio, ClickUp, Discord, Dropbox, Figma, GitHub, Google, Hubspot, Linear, LinkedIn, Microsoft, Notion, PagerDuty, Reddit, Slack, Spotify, Twitch, X, and Zoom. Each is imported from arcade_mcp_server.auth in the example shown. These are convenience wrappers around scope declaration, not SDKs for the underlying services.
Anything outside that list goes through a generic OAuth2 class, with the OAuth app registered in the Arcade Dashboard. That is a real constraint rather than a footnote: if your provider is not among the 22, you are configuring an application in someone else's dashboard before your tool can authenticate. The README does not describe what that registration involves, how credentials are rotated, or what happens to registered apps if you later stop using the hosted service. Those are the questions to ask before standardising on the generic path.
Secrets beyond OAuth are handled the same way. The README says API keys and other secrets are hosted in an encrypted environment and injected at runtime. It does not specify the encryption scheme or key management, so treat that as a vendor claim about the hosted side rather than a property you can audit from the repository.
Standalone operation and what it costs you
The framework does not require Arcade Cloud. The README states that standalone is supported: run the server in any MCP client over stdio or HTTP, and supply your own access tokens for tools that declare requires_auth. For production HTTP endpoints, the README points to Resource Server Auth in examples/mcp_servers/authorization/, which validates OAuth 2.1 Bearer tokens against your own identity provider.
The honest reading is that you are choosing between two burdens. On the hosted path, you get the browser challenge, token storage, refresh, and per-call scoping without writing them, and you accept that the flow runs through Arcade. On the standalone path, you keep the decorator API and the transport handling but you own the token lifecycle, and the README's own answer for securing an HTTP endpoint is an example directory rather than a built-in. That is the wrong tool for anyone who needs a fully self-contained credential system with no external service in the loop. It is also the wrong tool if your tools are purely local: the requires_auth machinery is the main reason to pick this over a thinner MCP server library, and without it you are carrying a dependency for decorators you could write yourself.
Evals, deployment, and the alternative you would otherwise reach for
Two CLI commands sit outside the request path. arcade evals is described as testing tool-call accuracy against real LLMs, which addresses a failure mode that unit tests miss: whether a model selects and fills your tool correctly. arcade deploy packages the server, discovers and upserts required secrets, and polls until it is healthy on Arcade Cloud, after which arcade server logs, arcade server list, arcade server status, and arcade dashboard provide management. The README does not give the shape of an eval suite or what accuracy threshold is meaningful, so the examples directory is the place to look.
The obvious alternative is the official Model Context Protocol Python SDK, which the repository's own topics list alongside the framework. The difference is scope. The SDK gives you the protocol: servers, transports, and message handling. arcade-mcp builds on that territory and adds the parts the protocol does not specify, namely the decorator surface across resources, prompts, and sampling, the requires_auth declaration, the provider helper classes, the client configuration commands, and the eval and deploy tooling. Choosing the SDK means writing the auth layer yourself and keeping a smaller dependency; choosing arcade-mcp means accepting a vendor-shaped abstraction in exchange for not writing it. Neither is a default. The decision turns on whether your tools need third-party credentials at all.
On licensing, the framework is MIT, which permits commercial use and modification. The hosted service is governed by separate terms that the README does not reproduce, and the README's link for the licence points at the repository LICENSE file. Anyone planning to depend on the deploy path should read those service terms rather than inferring them from the MIT grant.
Editorial conclusion
Adopt arcade-mcp if you are writing MCP tools in Python that call third-party APIs behind OAuth, and you would rather declare scopes than build a token store. Skip it if your tools are local-only and need no credentials, or if you cannot route calls through Arcade Cloud and do not want to implement Resource Server Auth yourself. Before committing, verify three things: that the provider you need is covered by the 22 helper classes or expressible through the generic OAuth2 class, that your Python version is 3.10 or higher, and that you are comfortable with the fact that the documented token injection path depends on the Arcade Engine.
Community notes