Skip to Content
HomeBuild toolsCreate an MCP Server

Creating an MCP Server with Arcade

The arcade_mcp_server package is the secure framework to build and run servers with your Arcade . It is easiest to use with the arcade-mcp package (Arcade’s CLI) which can scaffold your with all the necessary files and dependencies, configure MCP Clients to connect to your server, deploy your server to the cloud, and more. This guide walks you through the complete process of creating a custom MCP server with Arcade.

Outcomes

Build and run a secure server with that you define.

You will Learn

  • How to run servers with Arcade using the arcade_mcp_server package
  • How to use arcade new from the arcade-mcp CLI to create your server with all necessary files and dependencies.
  • How to run your local Server with the Arcade CLI and register it with the so that your can find and use your .

Prerequisites

Install the Arcade CLI

In your terminal, run the following command to install the arcade-mcp package - Arcade’s CLI:

Terminal
uv tool install arcade-mcp

This will install the Arcade CLI as a uv tool , making it available system wide.

Create Your Server

In your terminal, run the following command to scaffold a new Server called my_server:

Terminal
arcade new my_server cd my_server/src/my_server

This generates a Python module with the following structure:

Terminal
my_server/ ├── src/ └── my_server/ ├── __init__.py ├── .env.example └── server.py └── pyproject.toml
  1. server.py Main server file with MCPApp and example . It creates an MCPApp, defines tools with @app.tool, and will start the server with app.run() when the file is executed directly.
  2. pyproject.toml Dependencies and configuration
  3. .env.example Example .env file containing a secret required by one of the generated in server.py. Environments are loaded on server start, so if you update the .env file, you will need to restart your server.
Python
server.py
#!/usr/bin/env python3 """my_server MCP server""" import sys from typing import Annotated import httpx from arcade_mcp_server import Context, MCPApp from arcade_mcp_server.auth import Reddit app = MCPApp(name="my_server", version="1.0.0", log_level="DEBUG") @app.tool def greet(name: Annotated[str, "The name of the person to greet"]) -> str: """Greet a person by name.""" return f"Hello, {name}!" # To use this tool locally, you need to either set the secret in the .env file or as an environment variable @app.tool(requires_secrets=["MY_SECRET_KEY"]) def whisper_secret(context: Context) -> Annotated[str, "The last 4 characters of the secret"]: """Reveal the last 4 characters of a secret""" # Secrets are injected into the context at runtime. # LLMs and MCP clients cannot see or access your secrets # You can define secrets in a .env file. try: secret = context.get_secret("MY_SECRET_KEY") except Exception as e: return str(e) return "The last 4 characters of the secret are: " + secret[-4:] # To use this tool locally, you need to install the Arcade CLI (uv tool install arcade-mcp) # and then run 'arcade login' to authenticate. @app.tool(requires_auth=Reddit(scopes=["read"])) async def get_posts_in_subreddit( context: Context, subreddit: Annotated[str, "The name of the subreddit"] ) -> dict: """Get posts from a specific subreddit""" # Normalize the subreddit name subreddit = subreddit.lower().replace("r/", "").replace(" ", "") # Prepare the httpx request # OAuth token is injected into the context at runtime. # LLMs and MCP clients cannot see or access your OAuth tokens. oauth_token = context.get_auth_token_or_empty() headers = { "Authorization": f"Bearer {oauth_token}", "User-Agent": "finally-mcp-server", } params = {"limit": 5} url = f"https://oauth.reddit.com/r/{subreddit}/hot" # Make the request async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers, params=params) response.raise_for_status() # Return the response return response.json() # Run with specific transport if __name__ == "__main__": # Get transport from command line argument, default to "stdio" # - "stdio" (default): Standard I/O for Claude Desktop, CLI tools, etc. # Supports tools that require_auth or require_secrets out-of-the-box # - "http": HTTPS streaming for Cursor, VS Code, etc. # Does not support tools that require_auth or require_secrets unless the server is deployed # using 'arcade deploy' or added in the Arcade Developer Dashboard with 'Arcade' server type transport = sys.argv[1] if len(sys.argv) > 1 else "stdio" # Run the server app.run(transport=transport, host="127.0.0.1", port=8000)

Setup the secrets in your environment

Secrets are sensitive strings like passwords, , or other tokens that grant access to a protected resource or API. Arcade includes the “whisper_secret” that requires a secret key to be set in your environment. If the secret is not set, the tool will return an error.

You can create a .env file at the same directory as your (server.py) and add your secret:

ENV
.env
MY_SECRET_KEY="my-secret-value"

The generated includes a .env.example file with the secret key name and example value. You can rename it to .env to start using it.

Terminal
mv .env.example .env

Connect to Arcade to unlock authorized tool calling

Since the Reddit tool accesses information only available to your Reddit , you’ll need to authorize it. For this, you’ll need to create an Arcade account and connect to it from the terminal, run:

Terminal
arcade login

Follow the instructions in your browser, and once you’ve finished, your terminal will be connected to your Arcade .

Run your MCP Server

Run your Server using one of the following commands in your terminal:

Terminal
uv run server.py stdio

When using the stdio transport, clients typically launch the as a subprocess. Because of this, the server may run in a different environment and not have access to secrets defined in your local .env file. Please refer to the create a tool with secrets guide for more information.

You should see output like this in your terminal:

Terminal
2025-11-03 13:46:11.041 | DEBUG | arcade_mcp_server.mcp_app:add_tool:242 - Added tool: greet 2025-11-03 13:46:11.042 | DEBUG | arcade_mcp_server.mcp_app:add_tool:242 - Added tool: whisper_secret 2025-11-03 13:46:11.043 | DEBUG | arcade_mcp_server.mcp_app:add_tool:242 - Added tool: get_posts_in_subreddit INFO | 13:46:11 | arcade_mcp_server.mcp_app:299 | Starting my_server v1.0.0 with 3 tools

Configure your MCP Client(s)

Now you can connect Clients to your :

Terminal
# Configure Cursor to use your MCP server with the default transport (stdio) arcade configure cursor # Configure Cursor to use your MCP server with the http transport arcade configure cursor --transport http

That’s it! Your server is running and connected to your AI assistant.

Key takeaways

  • Minimal Setup Create MCPApp, define with @app.tool, and run with app.run()
  • Direct Execution Run your server file directly with uv run or python
  • Transport Flexibility Works with both stdio and HTTP
  • Type Annotations Use Annotated from the builtin typing library to provide descriptions to the language model for parameters and return values
  • Docstrings Use docstrings to provide a description of a tool to the language model
  • Command Line Arguments Pass transport type as command line argument

Next steps

Last updated on

Creating an MCP Server with Arcade | Arcade Docs