$git clone https://github.com/ArcadeAI/arcade-mcp</div>
| 1 | <div align="center"> |
| 2 | <img src="https://docs.arcade.dev/images/logo/arcade-logo.png" alt="Arcade" width="400"> |
| 3 | </div> |
| 4 | |
| 5 | <div align="center"> |
| 6 | |
| 7 | [](https://github.com/ArcadeAI/arcade-mcp/blob/main/LICENSE) |
| 8 | [](https://github.com/ArcadeAI/arcade-mcp/actions?query=branch%3Amain) |
| 9 | [](https://pypi.org/project/arcade-mcp/) |
| 10 | [](https://pypi.org/project/arcade-mcp/) |
| 11 | |
| 12 | </div> |
| 13 | |
| 14 | # Arcade MCP |
| 15 | |
| 16 | **Open-source Python framework for building MCP servers and tools.** |
| 17 | |
| 18 | [Documentation](https://docs.arcade.dev) • [Examples](examples/mcp_servers/) • [Discord](https://discord.com/invite/GUZEMpEZ9p) |
| 19 | |
| 20 | ## What is arcade-mcp |
| 21 | |
| 22 | `arcade-mcp` is the Python framework for building [Model Context Protocol](https://modelcontextprotocol.io) servers and the tools that run inside them. It powers the 7,500+ prebuilt tools across 81 MCP servers at [Arcade.dev](https://arcade.dev), and is open-sourced so you can build your own. |
| 23 | |
| 24 | Use it when you need MCP tools that aren't already in the prebuilt catalog: internal APIs, custom OAuth providers, domain-specific integrations. |
| 25 | |
| 26 | **Highlights:** |
| 27 | |
| 28 | - Decorator API covering the full MCP spec: tools, resources, prompts, sampling, elicitation, progress, logging. |
| 29 | - [Authorized tool calling](#authorized-tool-calling). Declare `requires_auth=GitHub(scopes=["repo"])` and Arcade handles OAuth, token refresh, and per-call scoping. The client and the LLM never see the token. |
| 30 | - Vendor-neutral. Any MCP client, any LLM, any agent framework (LangChain, Mastra, Pydantic AI, CrewAI, Google ADK, OpenAI Agents). |
| 31 | - `arcade evals` for testing tool-call accuracy against real LLMs. |
| 32 | - `arcade deploy` for one-command hosting on Arcade Cloud. |
| 33 | |
| 34 | ## Authorized tool calling |
| 35 | |
| 36 | Tools can declare: |
| 37 | |
| 38 | 1. Which OAuth scopes they need, and Arcade handles the rest: prompting the end user to authorize, storing and refreshing tokens, scoping them per call |
| 39 | 2. API keys or any other secrets, and Arcade hosts the secrets securely in an encrypted environment. |
| 40 | |
| 41 | The secrets (OAuth tokens, API keys, etc) are securely injected by Arcade into your tool call at runtime, so that your tool can authorize requests to upstream APIs, for example. **The client and the LLM never see the secret values.** |
| 42 | |
| 43 | A tool that reads the user's GitHub repos is one decorator away: |
| 44 | |
| 45 | ```python |
| 46 | from arcade_mcp_server import MCPApp, Context |
| 47 | from arcade_mcp_server.auth import GitHub |
| 48 | |
| 49 | app = MCPApp(name="gh", version="1.0.0") |
| 50 | |
| 51 | @app.tool(requires_auth=GitHub(scopes=["repo"])) |
| 52 | async def list_my_repos(context: Context) -> list[str]: |
| 53 | """List the authenticated user's GitHub repositories.""" |
| 54 | token = context.get_auth_token_or_empty() |
| 55 | ... |
| 56 | ``` |
| 57 | |
| 58 | When the tool is invoked through Arcade Cloud, the user is presented with a URL to complete the OAuth challenge in their browser. On success, the token is injected into `context` for that call. Subsequent calls reuse and refresh the token automatically. |
| 59 | |
| 60 | 22 helper classes ship with the framework for popular providers: |
| 61 | |
| 62 | `Asana`, `Atlassian`, `Attio`, `ClickUp`, `Discord`, `Dropbox`, `Figma`, `GitHub`, `Google`, `Hubspot`, `Linear`, `LinkedIn`, `Microsoft`, `Notion`, `PagerDuty`, `Reddit`, `Slack`, `Spotify`, `Twitch`, `X`, `Zoom`. |
| 63 | |
| 64 | For any other OAuth API, use the generic `OAuth2(...)` class and register your OAuth app in the Arcade Dashboard. |
| 65 | |
| 66 | ## Quick Start |
| 67 | |
| 68 | ### Install the CLI |
| 69 | |
| 70 | ```bash |
| 71 | uv tool install arcade-mcp |
| 72 | ``` |
| 73 | |
| 74 | ### Scaffold a new server |
| 75 | |
| 76 | ```bash |
| 77 | arcade new my_server |
| 78 | cd my_server/src/my_server |
| 79 | ``` |
| 80 | |
| 81 | The scaffold creates `pyproject.toml`, `.env.example`, and a `server.py` with example tools. |
| 82 | |
| 83 | A minimal tool: |
| 84 | |
| 85 | ```python |
| 86 | from typing import Annotated |
| 87 | from arcade_mcp_server import MCPApp |
| 88 | |
| 89 | app = MCPApp(name="my_server", version="1.0.0") |
| 90 | |
| 91 | @app.tool |
| 92 | def greet(name: Annotated[str, "Name to greet |