Arcade MCP

repository·main·Indexed 21 days ago

https://github.com/arcadeai/arcade-mcp

A Python framework for building Model Context Protocol (MCP) servers. It simplifies the creation of tools, resources, and prompts, featuring specialized support for secure, authorized tool calling via OAuth and secret injection. The package includes a CLI for running evaluations with the `evals` extra, Docker templates for containerization, and support for Resource Server Auth for protecting HTTP-transport endpoints.

Tokens
54.8K
Snippets
202
Records
265
Agent score
73%

What's inside arcade-mcp

  1. Overview of Arcade Core capabilities

    main

    Arcade Core provides the essential building blocks for the Arcade platform, including:

    • Tool Catalog & Toolkit Management: Core classes for managing and organizing tools.
    • Configuration & Schema Handling: Configuration management and validation.
    • Authentication & Authorization: Auth providers and security utilities.
    • Error Handling: Comprehensive error types and handling.
    • Telemetry & Observability: Monitoring and tracing capabilities.
    • Utilities: Common helper functions and validators.
  2. Overview of Arcade CLI capabilities

    main

    The Arcade CLI is a central interface for managing the Arcade platform lifecycle. Its primary capabilities include:

    • User Authentication: Managing sessions via login and logout.
    • Tool Development: Creating, testing, and managing Arcade tools.
    • Worker Deployment: Deploying and managing Arcade workers.
    • Interactive Chat: Testing tools within an interactive environment.
    • Project Templates: Generating new server projects using built-in templates.
  3. What is arcade-mcp

    main

    arcade-mcp is an open-source Python framework designed for building Model Context Protocol (MCP) servers and the tools that run within them. It provides a decorator-based API to implement the full MCP specification, including tools, resources, prompts, sampling, elicitation, progress reporting, and logging.

    Key features include:

    • Vendor-neutrality: Works with any MCP client, LLM, or agent framework (e.g., LangChain, Pydantic AI, CrewAI).
    • Authorized tool calling: Built-in support for OAuth and secret management.
    • Testing and Deployment: Includes arcade evals for testing tool-call accuracy and arcade deploy for hosting on Arcade Cloud.
  4. Arcade TDK Core Components

    main

    The Arcade TDK provides several key utilities for tool development:

    • Tool Decorator (@tool): The primary mechanism for defining Arcade tools.
    • Authentication: Includes auth providers (like Reddit) and helpers to secure tool execution.
    • Annotations: Leverages Python type annotations and Annotated metadata for parameter validation and model instruction.
    • Core Integration: Provides seamless integration with arcade-core components.
  5. What is Tool Metadata in Arcade MCP?

    main

    Tool metadata is structured information used to describe a tool's purpose, its side effects, and custom properties. It is categorized into three main fields:

    1. Classification: Defines the type of service the tool interfaces with (e.g., EMAIL, CRM). This is used for tool discovery and selection boosting.
    2. Behavior: Describes the tool's effects (e.g., READ, CREATE, DELETE). These map to MCP annotations that clients (like Claude) use to make policy decisions.
    3. Extras: A dictionary of arbitrary key/value pairs used for custom logic like routing, rate limits, or compliance metadata that does not affect tool selection.
  6. Implement server-level branding in MCP

    main

    As of the MCP 2025-11-25 protocol update, you can add branding fields to the Implementation object (returned in the serverInfo of an InitializeResult). This allows your server to provide a description, a website link, and a list of icons to the client.

    Branding Fields:

    • description: str: A free-form description of the server.
    • websiteUrl: str: A link to documentation, a landing page, or other relevant URLs.
    • icons: list[Icon]: A list of icons for the server (defined by SEP-973).

    Protocol Version Gating: Servers should gate these fields based on the client's protocolVersion. If a client uses an older version (e.g., 2025-06-18), the server should strip icons, description, and websiteUrl to prevent compatibility issues.

    {
      "name": "server_branding",
      "title": "Server Branding Demo",
      "version": "1.0.0",
      "description": "Example MCP server showing off the 2025-11-25 server-level branding fields: ...",
      "websiteUrl": "https://arcade.dev",
      "icons": [
        {
          "src": "data:image/svg+xml;base64,...",
          "mimeType": "image/svg+xml",
          "sizes": ["64x64", "any"],
          "theme": "light"
        }
      ]
    }
  7. Structure an evaluation script using @tool_eval()

    main

    Evaluation scripts follow a pattern of defining an asynchronous function decorated with @tool_eval(). Inside this function, you initialize an EvalSuite, load tools (e.g., via suite.add_arcade_gateway(...) or suite.add_mcp_stdio_server(...)), and add test cases using suite.add_case(...).

    # 1. Configuration section - Update these values
    ARCADE_API_KEY = os.environ.get("ARCADE_API_KEY", "YOUR_KEY_HERE")
    
    # 2. Eval suite with async loading
    @tool_eval()
    async def eval_my_suite() -> EvalSuite:
        suite = EvalSuite(name="...", system_message="...", rubric=...)
    
        # 3. Load tools with timeout and error handling
        try:
            await asyncio.wait_for(
                suite.add_arcade_gateway(...),
                timeout=10.0,
            )
            print("  ✓ Source loaded")
        except Exception as e:
            print(f"  ✗ Source failed: {e}")
            return suite
    
        # 4. Add test cases
        suite.add_case(name="...", user_message="...", ...)
    
        return suite
  8. Configure Multi-IdP support for MCP servers

    main
    You can trust multiple authorization servers simultaneously by passing multiple AuthorizationServerEntry objects to ResourceServerAuth. This is useful for multi-tenant environments or during migration windows (e.g., supporting both WorkOS and Keycloak). The server validates incoming tokens against every entry and accepts the token if it matches any of the configured servers.
  9. Understand the Tasks primitive for long-running tools

    main

    The Tasks primitive (introduced in SEP-1686) allows for durable, long-running tool invocations. Instead of a single synchronous request-response, tools can run as background tasks with pollable status, separate result retrieval, and cancellation support.

    When a tool is invoked as a task, the server returns a taskId immediately. Subsequent progress notifications, elicitation requests, or sampling requests emitted by the tool will include a _meta field containing io.modelcontextprotocol/related-task with the taskId. This allows the client to correlate background activity with the specific task instance.

  10. Configure MCP server package detection and file structure

    main

    The Dockerfile automatically detects the package name by reading the [project] name field in your pyproject.toml.

    Requirement: The build expects your server entrypoint to be located at src/<package_name>/server.py, where <package_name> matches the name defined in pyproject.toml.

    If the file is not found at this specific path, the build will fail and report the detected package name and the contents of the src/ directory.

  11. Enforce JSON Schema 2020-12 dialect (SEP-1613)

    main

    The context.ui.elicit method requires schemas to use the JSON Schema 2020-12 dialect. If you explicitly set a $schema key to an older version (like Draft 2019-09), the call will raise a ValueError.

    To avoid errors, either omit the $schema key (which defaults to 2020-12) or ensure it points to the correct 2020-12 URI.

    # ⚠️ This will raise a ValueError:
    await context.ui.elicit(
        "…",
        schema={
            "$schema": "https://json-schema.org/draft/2019-09/schema",
            "type": "object",
            "properties": {...},
        },
    )
  12. How authorized tool calling works

    main

    Arcade MCP allows tools to declare authentication requirements using the requires_auth parameter in the @app.tool decorator. Arcade handles the complexity of OAuth flows, token storage, and refreshing.

    Security Model:

    • Secrets (OAuth tokens, API keys) are securely injected by Arcade into the tool call at runtime.
    • The client and the LLM never see the secret values.
    • For OAuth, when invoked via Arcade Cloud, the user is presented with a URL to authorize in their browser. Once successful, the token is injected into the tool's Context object.

    Supported Providers: The framework includes 22 helper classes for popular providers including Asana, Atlassian, GitHub, Google, Microsoft, Notion, Slack, and more. For other OAuth APIs, use the generic OAuth2(...) class and register your app in the Arcade Dashboard.

    from arcade_mcp_server import MCPApp, Context
    from arcade_mcp_server.auth import GitHub
    
    app = MCPApp(name="gh", version="1.0.0")
    
    @app.tool(requires_auth=GitHub(scopes=["repo"]))
    async def list_my_repos(context: Context) -> list[str]:
        """List the authenticated user's GitHub repositories."""
        token = context.get_auth_token_or_empty()
        # Use token to make authorized requests...
        ...