# https://docs.arcade.dev llms-full.txt ## AI Agent Deployment # Welcome to Arcade! Learn how to move AI agents from demo to production with Arcade. Arcade enables your AI agent to securely take real-world actions through user-specific permissions, pre-built integrations with Gmail, Slack, GitHub, and more. You can also build your own agentic tools and MCP servers with our authoring and testing suite. Arcade is your toolengine,registry, andruntime. Get started with a 5-minute quickstart. [Get Started](https://docs.arcade.dev/home/quickstart) [Build a tool](https://docs.arcade.dev/home/build-tools/create-a-toolkit) ## Sample Applications Get started quickly with our pre-built templates and example applications. [![Arcade Chat](https://docs.arcade.dev/_next/image?url=%2Fimages%2Fsample-apps%2Farcade-chat.png&w=3840&q=75)\\ \\ **Arcade Chat** \\ \\ A chatbot that can help you with your daily tasks.](https://chat.arcade.dev/) [![Archer](https://docs.arcade.dev/_next/image?url=%2Fimages%2Flogo%2Farcade.png&w=3840&q=75)\\ \\ **Archer** \\ \\ A bot for Slack that can act on your behalf.](https://github.com/ArcadeAI/ArcadeSlackAgent) [![Summarize YouTube Podcasts in Slack](https://docs.arcade.dev/_next/image?url=%2Fimages%2Fsample-apps%2Fslack-aipodcast-summaries.jpg&w=3840&q=75)\\ \\ **Summarize YouTube Podcasts in Slack** \\ \\ A Slack bot that extracts and summarizes YouTube transcripts in Weaviate, perfect for AI podcasts.](https://github.com/dforwardfeed/slack-AIpodcast-summaries) ## Arcade Overview ![arcade overview](https://docs.arcade.dev/_next/image?url=%2Fimages%2Foverview.png&w=1920&q=75) [Arcade Engine\\ \\ The Arcade engine is your MCP Server and Agentic tool provider. It allows you to write your tools once and serve them across any LLM or orchestration framework, no matter the protocol. The engine manages agent authentication, tool registration, and tool execution.](https://docs.arcade.dev/home#) [Control Plane\\ \\ The Control Plane is how you manage your tools, users, and deployments from a single place. No matter how large your deployment or organization gets, the Control Plane will scale with you.](https://docs.arcade.dev/home#) [Public and Private Tools\\ \\ Arcade makes it easy to develop custom tools that just work with Agents. Our SDKs and framework integrations make it easy to get started. When you are ready, it's easy to run your tools either on-prem or in our cloud.](https://docs.arcade.dev/home#) [Tools and MCP Servers Together\\ \\ The Arcade Engine is the only way to combine MCP servers with your Agentic tools. Regardless of where your tool is hosted, you can serve and manage access to it via the Engine. You easily can mix our public tools with your own private tools in your agents.](https://docs.arcade.dev/home#) [Contact us](https://docs.arcade.dev/home/contact-us "[object Object]") ## Arcade.dev Changelog [Home](https://docs.arcade.dev/home "Home") Changelog # Changelog _Here’s what’s new at Arcade.dev!_ ## For the week ending on 2025-06-20 [Permalink for this section](https://docs.arcade.dev/home/changelog\#for-the-week-ending-on-2025-06-20) **Frameworks** - `[feature - 🚀]` Support for OpenAI Agent SDK in Typescript ( [docs](https://docs.arcade.dev/home/oai-agents/overview) and [example](https://github.com/ArcadeAI/arcade-ai/tree/main/examples/openai-agents-ts)) **Toolkits** - `[feature - 🚀]` Jira toolkit released ( [docs](https://docs.arcade.dev/toolkits/productivity/jira)) **CLI and TDK** - `[feature - 🚀]` V2.0 of Python Tool Development Kit (TDK) ( [migration guide](https://docs.arcade.dev/home/migrate-to-v2)) - `[feature - 🚀]` Admin API client support - Requires v1.6.0 of `arcade-py`, or v1.8.0 of `arcade-js`, or v0.1.0-alpha.4 of `arcade-go` **Platform and Engine** - `[feature - 🚀]` Admin APIs released for managing users, secrets, and tools ( [API References](https://reference.arcade.dev/api-reference#tag/admin)) - `[bugfix - 🐛]` Unauthenticated MCP servers can be called anonymously - `[feature - 🚀]` End-user credentials and auth status can be fetched in batches ( [docs](https://docs.arcade.dev/home/auth/tool-auth-status)) **Misc** - `[feature - 🚀]` Launched Github Discussions for product feedback and support ( [link](https://github.com/ArcadeAI/arcade-ai/discussions)) - `[feature - 🚀]` Launched status.arcade.dev for monitoring platform status ( [link](https://status.arcade.dev/)) [FAQ](https://docs.arcade.dev/home/faq "FAQ") [Registry Early Access](https://docs.arcade.dev/home/registry-early-access "Registry Early Access") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## MCP Overview [Home](https://docs.arcade.dev/home "Home") MCP Overview # Model Context Protocol (MCP): The Arcade.dev Perspective ## What is MCP and Why Should Developers Care? [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#what-is-mcp-and-why-should-developers-care) Model Context Protocol represents a significant step toward standardizing how AI agents interact with tools and external systems. As the developer-first platform for authenticated tool-calling, Arcade.dev has been at the forefront of connecting AI models to real-world actions - which is why our perspective on MCP matters. For developers building AI applications that need to do more than just generate text, understanding the strengths and limitations of protocols like MCP is critical to making informed architecture decisions. ## The Current State of Model Context Protocol [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#the-current-state-of-model-context-protocol) MCP aims to standardize how AI models access and use applications to get data or use tools - a problem space Arcade.dev has been solving since day one. While the protocol rightly focuses on how applications provide context to LLMs, our hands-on experience building production agent systems reveals both opportunities and challenges. ### Where MCP Gets It Right [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#where-mcp-gets-it-right) - **Standardization attempt**: Creating common patterns for tool definitions across different AI providers is a step in the right direction. It allows agent builders to switch between different LLM providers and optimize costs and performance for each component using an LLM. - **Focus on function-calling**: Correctly identifies that giving AI models the ability to call functions is fundamental to realize the agent’s full potential. The protocol got the difference between LLM resources and regular APIs right from the beginning. While traditional APIs are designed for developers to use, LLM-optimized tools require additional context to be used effectively by AI systems. The recognition of what we call [Machine Experience Engineering](https://blog.arcade.dev/the-birth-of-machine-experience-engineering) is something MCP designers also identified early on. - **Community momentum**: Building adoption across multiple providers creates healthy ecosystem dynamics, giving all actors that adopt MCP the benefits of a robust, well-tested and growing ecosystem of LLM-ready resources, both local and remote. ### Where MCP is Evolving [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#where-mcp-is-evolving) - **Authentication gaps**: The protocol was initially designed for local resources only, and required considerable technical knowledge to integrate with clients like VSCode, Cursor, and Claude Desktop. 99% of MCP servers today are built for single-user use, even hosted ones. If you need to configure the MCP server with a PAT (personal access token) or an API key, it’s not usable by a multi-user (B2B2C) or cloud-based agent. At a minimum, MCP servers need to support [HTTP](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http), [MCP authorization](https://modelcontextprotocol.io/specification/draft/basic/authorization), and support multi-user authorization. Having a robust standard for tool calling without the same robustness for auth quickly began the adoption of ad-hoc solutions that were more or less insecure for remote tool calling, the #1 bottleneck in moving AI agents to production. Fortunately, active work is ongoing on the MCP community to adopt a solid auth component in the protocol. [Arcade.dev’s own auth team actively contribute](https://www.youtube.com/watch?v=f1sLBGWnByc) to the specification in this crucial area. - **Production readiness**: Enterprise-grade concerns like observability, security, and compliance need stronger representation. As the protocol evolves, we expect all of these aspects to be integrated into the protocol. - **Developer experience**: Implementation complexity can create significant friction for teams without specialized AI expertise. MCP is a very new protocol undergoing rapid changes, so the DX is expected to be turbulent until the protocol matures. Arcade.dev supports this from day one while providing the best DX for building tools that can be served over MCP to any AI agent. ## How Arcade.dev Complements and Extends MCP [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#how-arcadedev-complements-and-extends-mcp) Rather than viewing MCP as either perfect or problematic, we see it as part of an evolving ecosystem. Arcade.dev bridges critical gaps in the protocol by providing: 1. **Authentication-first architecture**: Secure, OAuth-based connections that let AI access tools as the end user - not as a “bot” 2. **Production infrastructure**: Monitoring, logging, and evaluation capabilities built for enterprise deployment. This also includes improvements to tool selection when many tools are enabled. 3. **Developer acceleration**: SDKs that dramatically reduce time-to-value when implementing tool-calling patterns 4. **Multi-model compatibility**: Works seamlessly with all major LLM providers, regardless of their MCP implementation status. You can start building your agents today, and switch to MCP seamlessly when your LLM provider supports it, or when the MCP SDK reaches enterprise level readiness | | | | --- | --- | | ![MCP Auth Diagram](https://docs.arcade.dev/images/mcp/mcp-auth-1.jpg) | ![MCP Auth Diagram](https://docs.arcade.dev/images/mcp/mcp-auth-2.jpg) | ## Why This Matters for Your AI Applications [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#why-this-matters-for-your-ai-applications) AI that can’t authenticate to access accounts or use data is fundamentally limited. This disconnect is why less than 30% of AI projects go to production. The biggest opportunity in AI today isn’t better models—it’s enabling those models to take real actions. Developers need secure connections between AI and authenticated services, user data, and enterprise systems. By combining MCP’s standardization efforts with Arcade.dev’s authentication-first approach, developers can build AI applications that don’t just suggest actions—they take them. ## Our Commitment to the Protocol Ecosystem [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#our-commitment-to-the-protocol-ecosystem) At Arcade.dev, we’re active participants in the evolving tool-calling ecosystem. Our team contributes to open standards like MCP while building the production-grade infrastructure developers need today. As Sam Partee, our CTO, explains: “Protocols like MCP are important stepping stones toward more capable AI agents. Our focus is making sure developers can build with these patterns today, with authentication and security baked in from the start.” ## Frequently Asked MCP Questions [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#frequently-asked-mcp-questions) ### Is Arcade.dev an alternative to MCP? [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#is-arcadedev-an-alternative-to-mcp) No. Arcade.dev complements protocol standards like MCP by providing the authentication layer, developer tooling, and production infrastructure needed to implement them successfully in real-world applications. Arcade’s Engine can be an MCP server with super-powers, and you can pull in upstream MCP servers as tools into Arcade. ### Do I need to understand MCP to use Arcade.dev? [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#do-i-need-to-understand-mcp-to-use-arcadedev) Not at all. Arcade.dev provides intuitive SDKs that handle the complexities of tool-calling patterns, regardless of which underlying protocol standards are in use. ### What models work with Arcade.dev’s approach to MCP? [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#what-models-work-with-arcadedevs-approach-to-mcp) Arcade.dev works with all major models including Claude, GPT-4, Llama, Mistral, and more - supporting both MCP-compatible and non-MCP implementations through our unified API. ### How does Arcade.dev handle authentication within the MCP framework? [Permalink for this section](https://docs.arcade.dev/home/mcp-overview\#how-does-arcadedev-handle-authentication-within-the-mcp-framework) Arcade.dev extends(\*) basic MCP implementations with enterprise-grade OAuth flows, secure token management, and fine-grained permissions - solving the authentication gap that often blocks production deployment. (\*) Arcade is currently compatible with the existing ratified MCP specifications, and is working to extend them for [tool authorization](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/475). [Using Arcade tools](https://docs.arcade.dev/home/vercelai/use-arcade-tools "Using Arcade tools") [Use Arcade with Claude Desktop](https://docs.arcade.dev/home/mcp-desktop-clients/claude-desktop-client "Use Arcade with Claude Desktop") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Twitch Auth Configuration [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Entertainment](https://docs.arcade.dev/toolkits/entertainment/spotify "Entertainment") Twitch # Twitch auth provider At this time, Arcade does not offer a default Twitch Auth Provider. To use Twitch auth, you must create a custom Auth Provider with your own Twitch OAuth 2.0 credentials as described below. The Twitch auth provider enables tools and agents to call the Twitch API on behalf of a user. Behind the scenes, the Arcade Engine and the Twitch auth provider seamlessly manage Twitch OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#whats-documented-here) This page describes how to use and configure Twitch auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/toolkits/entertainment/twitch#using-twitch-auth-in-app-code) that needs to call Twitch APIs - Or, your [custom tools](https://docs.arcade.dev/toolkits/entertainment/twitch#using-twitch-auth-in-custom-tools) that need to call Twitch APIs ## Configuring Twitch auth [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#configuring-twitch-auth) ### Create a Twitch app [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#create-a-twitch-app) - Twitch requires that you have two-factor authentication enabled for your account. Enable in your [account security seetings](https://www.twitch.tv/settings/security) - Create a Twitch Application in the [Twitch App Console](https://dev.twitch.tv/console/apps) - Set the OAuth Redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Select your Application category - Select the ‘Confidential’ Client Type - Copy the App key (Client ID) and App secret (Client Secret), which you’ll need below Next, add the Twitch app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ### Configuring Twitch auth with the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#configuring-twitch-auth-with-the-arcade-dashboard) 1. Navigate to the OAuth section of the Arcade Dashboard and click **Add OAuth Provider**. 2. Select **Twitch** as the provider. 3. Choose a unique **ID** for your provider (e.g. “my-twitch-provider”) with an optional **Description**. 4. Enter your **Client ID** and **Client Secret** from your Twitch app. 5. Click **Save**. When you use tools that require Twitch auth using your Arcade account credentials, the Arcade Engine will automatically use this Twitch OAuth provider. ### Configuring Twitch auth in self-hosted Arcade Engine configuration [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#configuring-twitch-auth-in-self-hosted-arcade-engine-configuration) ### Set environment variables [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#set-environment-variables) The Client ID is the Twitch “App key” and the Client Secret is the Twitch “App secret”. Set the following environment variables: ```nextra-code export TWITCH_CLIENT_ID="" export TWITCH_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code TWITCH_CLIENT_SECRET="" TWITCH_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `twitch` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-twitch description: "The default Twitch provider" enabled: true type: oauth2 provider_id: twitch client_id: ${env:TWITCH_CLIENT_ID} client_secret: ${env:TWITCH_CLIENT_SECRET} ``` ## Using Twitch auth in app code [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#using-twitch-auth-in-app-code) Use the Twitch auth provider in your own agents and AI apps to get a user-scoped token for the Twitch API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Twitch API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="twitch", scopes=["channel:manage:polls"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "twitch", { scopes: ["channel:manage:polls"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Twitch auth in custom tools [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/twitch\#using-twitch-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Twitch API. Use the `Twitch()` auth class to specify that a tool requires authorization with Twitch. The `context.authorization.token` field will be automatically populated with the user’s Twitch token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Twitch @tool( requires_auth=Twitch( scopes=["channel:manage:polls"], ) ) async def create_poll( context: ToolContext, broadcaster_id: Annotated[\ str,\ "The ID of the broadcaster to create the poll for.",\ ], title: Annotated[\ str,\ "The title of the poll.",\ ], choices: Annotated[\ list[str],\ "The choices of the poll.",\ ], duration: Annotated[\ int,\ "The duration of the poll in seconds.",\ ], ) -> Annotated[dict, "The poll that was created"]: """Create a poll for a Twitch channel.""" url = "https://api.twitch.tv/helix/polls" headers = { "Authorization": f"Bearer {context.authorization.token}", "Client-Id": "your_client_id", "Content-Type": "application/json", } payload = { "broadcaster_id": broadcaster_id, "title": title, "choices": [{"title": choice} for choice in choices], "duration": duration, } async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, json=payload) response.raise_for_status() return response.json() ``` ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_twitch\\ ```](https://docs.arcade.dev/home/hosting-overview) [Spotify](https://docs.arcade.dev/toolkits/entertainment/spotify "Spotify") [Code Sandbox](https://docs.arcade.dev/toolkits/development/code-sandbox "Code Sandbox") ## Google Hotels Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google Hotels # Google Hotels **Description:** Empower your agents to search for hotels using Arcade. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google Hotels toolkit lets you search for hotels with ease. Use this tool to build intelligent agents and applications that search for hotels worldwide. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_hotels\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchHotels | Retrieve hotel search results using the Google Hotels API. | ## Search.SearchHotels [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_hotels\#searchsearchhotels) Retrieve hotel search results using the Google Hotels API. **Parameters** - **`location`** _(string, required)_: Location to search for hotels, e.g., a city name, a state, etc. - **`check_in_date`** _(string, required)_: Check-in date in YYYY-MM-DD format. - **`check_out_date`** _(string, required)_: Check-out date in YYYY-MM-DD format. - **`query`** _(string, optional)_: Anything that would be used in a regular Google Hotels search. - **`currency`** _(string, optional)_: Currency code for prices. Defaults to ‘USD’. - **`min_price`** _(int, optional)_: Minimum price per night. Defaults to no minimum. - **`max_price`** _(int, optional)_: Maximum price per night. Defaults to no maximum. - **`num_adults`** _(int, optional)_: Number of adults per room. Defaults to 2. - **`num_children`** _(int, optional)_: Number of children per room. Defaults to 0. - **`sort_by`** _(enum ( [GoogleHotelsSortBy](https://docs.arcade.dev/toolkits/search/reference#googlehotelssortby)), optional)_: The sorting order of the results. Defaults to RELEVANCE. - **`num_results`** _(int, optional)_: Maximum number of results to return. Defaults to 5. Max 20. See Example > ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_hotels\#auth) The Arcade Google Hotels toolkit uses the [SerpAPI](https://serpapi.com/) to search for hotels from Google Hotels. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google Flights](https://docs.arcade.dev/toolkits/search/google_flights "Google Flights") [Google Jobs](https://docs.arcade.dev/toolkits/search/google_jobs "Google Jobs") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Toolkit Reference [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Google](https://docs.arcade.dev/toolkits/productivity/google/calendar "Google") Reference # Reference for Google Toolkit ## OrderBy [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#orderby) Sort keys for ordering files in Google Drive. Each key has both ascending and descending options. - **`CREATED_TIME`**: When the file was created (ascending). - **`CREATED_TIME_DESC`**: When the file was created (descending). - **`FOLDER`**: The folder ID, sorted using alphabetical ordering (ascending). - **`FOLDER_DESC`**: The folder ID, sorted using alphabetical ordering (descending). - **`MODIFIED_BY_ME_TIME`**: The last time the file was modified by the user (ascending). - **`MODIFIED_BY_ME_TIME_DESC`**: The last time the file was modified by the user (descending). - **`MODIFIED_TIME`**: The last time the file was modified by anyone (ascending). - **`MODIFIED_TIME_DESC`**: The last time the file was modified by anyone (descending). - **`NAME`**: The name of the file, sorted using alphabetical ordering (ascending). - **`NAME_DESC`**: The name of the file, sorted using alphabetical ordering (descending). - **`NAME_NATURAL`**: The name of the file, sorted using natural sort ordering (ascending). - **`NAME_NATURAL_DESC`**: The name of the file, sorted using natural sort ordering (descending). - **`QUOTA_BYTES_USED`**: The number of storage quota bytes used by the file (ascending). - **`QUOTA_BYTES_USED_DESC`**: The number of storage quota bytes used by the file (descending). - **`RECENCY`**: The most recent timestamp from the file’s date-time fields (ascending). - **`RECENCY_DESC`**: The most recent timestamp from the file’s date-time fields (descending). - **`SHARED_WITH_ME_TIME`**: When the file was shared with the user, if applicable (ascending). - **`SHARED_WITH_ME_TIME_DESC`**: When the file was shared with the user, if applicable (descending). - **`STARRED`**: Whether the user has starred the file (ascending). - **`STARRED_DESC`**: Whether the user has starred the file (descending). - **`VIEWED_BY_ME_TIME`**: The last time the file was viewed by the user (ascending). - **`VIEWED_BY_ME_TIME_DESC`**: The last time the file was viewed by the user (descending). ## DocumentFormat [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#documentformat) The format of the document to be returned. - **`MARKDOWN`**: Markdown format. - **`HTML`**: HTML format. - **`GOOGLE_API_JSON`**: Original JSON format returned by the Google API. ## DateRange [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#daterange) Represents different date ranges for filtering events. - **`TODAY`**: Today. - **`TOMORROW`**: Tomorrow. - **`THIS_WEEK`**: This week. - **`NEXT_WEEK`**: Next week. - **`THIS_MONTH`**: This month. - **`NEXT_MONTH`**: Next month. ## Day [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#day) Represents specific days for scheduling. - **`YESTERDAY`**: Yesterday. - **`TODAY`**: Today. - **`TOMORROW`**: Tomorrow. - **`THIS_SUNDAY`**: This Sunday. - **`THIS_MONDAY`**: This Monday. - **`THIS_TUESDAY`**: This Tuesday. - **`THIS_WEDNESDAY`**: This Wednesday. - **`THIS_THURSDAY`**: This Thursday. - **`THIS_FRIDAY`**: This Friday. - **`THIS_SATURDAY`**: This Saturday. - **`NEXT_SUNDAY`**: Next Sunday. - **`NEXT_MONDAY`**: Next Monday. - **`NEXT_TUESDAY`**: Next Tuesday. - **`NEXT_WEDNESDAY`**: Next Wednesday. - **`NEXT_THURSDAY`**: Next Thursday. - **`NEXT_FRIDAY`**: Next Friday. - **`NEXT_SATURDAY`**: Next Saturday. ## TimeSlot [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#timeslot) Represents time slots in a day. - **`_0000`**: 00:00 - **`_0015`**: 00:15 - **`_0030`**: 00:30 - **`_0045`**: 00:45 - **`_0100`**: 01:00 - **`_0115`**: 01:15 - **`_0130`**: 01:30 - **`_0145`**: 01:45 - **`_0200`**: 02:00 - **`_0215`**: 02:15 - **`_0230`**: 02:30 - **`_0245`**: 02:45 - **`_0300`**: 03:00 - **`_0315`**: 03:15 - **`_0330`**: 03:30 - **`_0345`**: 03:45 - **`_0400`**: 04:00 - **`_0415`**: 04:15 - **`_0430`**: 04:30 - **`_0445`**: 04:45 - **`_0500`**: 05:00 - **`_0515`**: 05:15 - **`_0530`**: 05:30 - **`_0545`**: 05:45 - **`_0600`**: 06:00 - **`_0615`**: 06:15 - **`_0630`**: 06:30 - **`_0645`**: 06:45 - **`_0700`**: 07:00 - **`_0715`**: 07:15 - **`_0730`**: 07:30 - **`_0745`**: 07:45 - **`_0800`**: 08:00 - **`_0815`**: 08:15 - **`_0830`**: 08:30 - **`_0845`**: 08:45 - **`_0900`**: 09:00 - **`_0915`**: 09:15 - **`_0930`**: 09:30 - **`_0945`**: 09:45 - **`_1000`**: 10:00 - **`_1015`**: 10:15 - **`_1030`**: 10:30 - **`_1045`**: 10:45 - **`_1100`**: 11:00 - **`_1115`**: 11:15 - **`_1130`**: 11:30 - **`_1145`**: 11:45 - **`_1200`**: 12:00 - **`_1215`**: 12:15 - **`_1230`**: 12:30 - **`_1245`**: 12:45 - **`_1300`**: 13:00 - **`_1315`**: 13:15 - **`_1330`**: 13:30 - **`_1345`**: 13:45 - **`_1400`**: 14:00 - **`_1415`**: 14:15 - **`_1430`**: 14:30 - **`_1445`**: 14:45 - **`_1500`**: 15:00 - **`_1515`**: 15:15 - **`_1530`**: 15:30 - **`_1545`**: 15:45 - **`_1600`**: 16:00 - **`_1615`**: 16:15 - **`_1630`**: 16:30 - **`_1645`**: 16:45 - **`_1700`**: 17:00 - **`_1715`**: 17:15 - **`_1730`**: 17:30 - **`_1745`**: 17:45 - **`_1800`**: 18:00 - **`_1815`**: 18:15 - **`_1830`**: 18:30 - **`_1845`**: 18:45 - **`_1900`**: 19:00 - **`_1915`**: 19:15 - **`_1930`**: 19:30 - **`_1945`**: 19:45 - **`_2000`**: 20:00 - **`_2015`**: 20:15 - **`_2030`**: 20:30 - **`_2045`**: 20:45 - **`_2100`**: 21:00 - **`_2115`**: 21:15 - **`_2130`**: 21:30 - **`_2145`**: 21:45 - **`_2200`**: 22:00 - **`_2215`**: 22:15 - **`_2230`**: 22:30 - **`_2245`**: 22:45 - **`_2300`**: 23:00 - **`_2315`**: 23:15 - **`_2330`**: 23:30 - **`_2345`**: 23:45 ## EventVisibility [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#eventvisibility) Defines the visibility of an event. - **`DEFAULT`**: Default visibility. - **`PUBLIC`**: Public visibility. - **`PRIVATE`**: Private visibility. - **`CONFIDENTIAL`**: Confidential visibility. ## EventType [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#eventtype) Specifies the type of an event. - **`BIRTHDAY`**: Birthday events. - **`DEFAULT`**: Regular events. - **`FOCUS_TIME`**: Focus time events. - **`FROM_GMAIL`**: Events from Gmail. - **`OUT_OF_OFFICE`**: Out of office events. - **`WORKING_LOCATION`**: Working location events. ## SendUpdatesOptions [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/reference\#sendupdatesoptions) Options for sending updates about events. - **`NONE`**: No notifications are sent. - **`ALL`**: Notifications are sent to all guests. - **`EXTERNAL_ONLY`**: Notifications are sent to non-Google Calendar guests only. [Sheets](https://docs.arcade.dev/toolkits/productivity/google/sheets "Sheets") [Jira](https://docs.arcade.dev/toolkits/productivity/jira "Jira") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Local Installation [Home](https://docs.arcade.dev/home "Home") Local Deployment [Install](https://docs.arcade.dev/home/local-deployment/install/overview "Install") Local # Installing Arcade Locally This guide will help you install Arcade and set up your development environment. If you are developing tools to use with Arcade, this guide will provide you with a complete local deployment of Arcade for developing and testing tools. ## Prerequisites [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#prerequisites) Before you begin, make sure you have the following: - **Python 3.10 or higher** - **pip**: The Python package installer should be available. It’s typically included with Python. - **Arcade Account**: Sign up for an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=local-install) if you haven’t already. - **Package Manager**: Either Brew (macOS) or Apt (linux) to install the engine binary. Verify your Python version by running `python --version` or `python3 --version` in your terminal. ## Installation [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#installation) ### Install the Client [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#install-the-client) To connect to the cloud or local Arcade Engine, we need to install the Arcade CLI from the `arcade-ai` package. ```nextra-code pip install arcade-ai arcade login ``` For a simple example on using the Arcade CLI, see the [quickstart on building tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) ### Install the Engine [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#install-the-engine) To run the Arcade Engine locally, you’ll need to install `arcade-engine`. Choose the installation method that matches your operating system. This will install a template engine configuration. macOS (Homebrew)Ubuntu/Debian (APT)Windows (coming soon) ```nextra-code brew install ArcadeAI/tap/arcade-engine ``` ```nextra-code wget -qO - https://deb.arcade.dev/public-key.asc | sudo apt-key add - echo "deb https://deb.arcade.dev/ubuntu stable main" | sudo tee /etc/apt/sources.list.d/arcade-ai.list sudo apt update sudo apt install arcade-engine ``` ```nextra-code Windows support is coming soon! ``` Want to see Windows support sooner? Show your interest by adding a 👍 to [this GitHub issue](https://github.com/ArcadeAI/arcade-ai/issues/258). ### Install a toolkit [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#install-a-toolkit) In order to run the Arcade worker, you’ll need to install at least one tool. For local development, you can just `pip install` a tool in the same environment as the client. ```nextra-code pip install arcade-math ``` For more information on installing toolkits, see the [Toolkit Installation](https://docs.arcade.dev/home/local-deployment/install/toolkits) page. To see all available toolkits, view the [Toolkits Page](https://docs.arcade.dev/toolkits). ### Set OpenAI API key [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#set-openai-api-key) Before starting the Engine, we need to set an OpenAI API Key that the Engine can use to connect to OpenAI. Edit the `engine.env` file to set the `OPENAI_API_KEY` environment variable: ```nextra-code OPENAI_API_KEY="" ``` See the [configuration overview](https://docs.arcade.dev/home/local-deployment/configure/overview) for more information on how to configure Arcade Engine and how to locate the `engine.env` file. ### Start the Engine and worker [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#start-the-engine-and-worker) To run both the engine and a local worker, follow these steps: 1. First, start the worker: ```nextra-code arcade serve ``` 2. Then, start the engine: ```nextra-code arcade-engine ``` The Engine and worker should both be running locally now. To run the Engine on it’s own, you can run: ```nextra-code arcade-engine ``` Note that the Engine requires at least one Arcade worker to run. ### Connect [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#connect) To chat with the running Engine, in a separate terminal instance, run: ```nextra-code arcade chat -h localhost ``` You are now chatting with Arcade locally! ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#next-steps) - **Building Tools**: Learn how to build tools with your local Arcade Instance in the [Creating a Toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit) guide. - **Hosting With Docker**: Learn how to run the [Engine in Docker](https://docs.arcade.dev/home/local-deployment/install/docker). ## Troubleshooting [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#troubleshooting) ### Engine Binary Not Found [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#engine-binary-not-found) ```nextra-code ❌ Engine binary not found ``` or ```nextra-code command not found: arcade-engine ``` This means that the Arcade Engine cannot be found in your path. Brew and Apt will automatically add the binary to you path. Check that the binary has been properly installed (These are the common installation locations): **Brew** ```nextra-code ls $HOMEBREW_REPOSITORY/Cellar/arcade-engine//bin/arcade-engine ``` **Apt** ```nextra-code ls /usr/bin/arcade-engine ``` If the binary is found, add it to your path with: ```nextra-code export PATH=$PATH:/path/to/your/binary ``` ### Toolkits Not Found [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#toolkits-not-found) ```nextra-code No toolkits found in Python environment. Exiting... ``` This means that there are no toolkits found in the same environment as the Arcade SDK. Ensure that you are installing the toolkit package in the same environment and see the [Toolkit Installation Guide](https://docs.arcade.dev/home/local-deployment/install/toolkits) for more details. ### Engine Config Not Found [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/local\#engine-config-not-found) ```nextra-code ❌ Config file 'engine.yaml' not found in any of the default locations. ``` or ```nextra-code Arcade Engine has finished with error: unable to read config file $HOME/.arcade/engine.yaml: open $HOME/.arcade/engine.yaml: no such file or directory ``` The engine config may be located in one of the following directories: - $HOME/.arcade/engine.yaml - $HOMEBREW\_REPOSITORY/etc/arcade-engine/engine.yaml (Homebrew) - /etc/arcade-ai/engine.yaml (Apt) The engine config will be downloaded by and added to one of these locations when installing the engine. When running the engine, the config needs to be in the `$HOME/.arcade/` directory or explicitly located with `arcade-engine -c /path/to/engine.yaml`. If you cannot find your engine config, you can save and use the [Configuration Templates](https://docs.arcade.dev/home/local-deployment/configure/templates). * * * [Overview](https://docs.arcade.dev/home/local-deployment/install/overview "Overview") [Docker](https://docs.arcade.dev/home/local-deployment/install/docker "Docker") ## Arcade Deploy Guide [Home](https://docs.arcade.dev/home "Home") Serve toolsArcade Deploy # Deploying to the cloud with Arcade Deploy This guide shows you how to deploy a worker with a local toolkit with Arcade Deploy. ## Requirements [Permalink for this section](https://docs.arcade.dev/home/serve-tools/arcade-deploy\#requirements) - **Python 3.10** or higher Verify your Python version by running `python --version` or `python3 --version` in your terminal. - **Arcade Account**: Sign up for an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=custom-tools) if you haven’t already. - **Arcade CLI**: Install the Arcade CLI uvpip ```nextra-code uv pip install arcade-ai ``` ```nextra-code pip install arcade-ai ``` ## Create your deployment config [Permalink for this section](https://docs.arcade.dev/home/serve-tools/arcade-deploy\#create-your-deployment-config) Create a `worker.toml` file in your project directory: ```nextra-code ### Worker 1 [[worker]] [worker.config] id = "my-worker" secret = # Replace with your own secret [worker.local_source] packages = ["./"] # Replace with the path to your toolkit directory ``` For more information on the `worker.toml` file, see the [Arcade Deploy documentation](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy). * * * ## Deploy your worker [Permalink for this section](https://docs.arcade.dev/home/serve-tools/arcade-deploy\#deploy-your-worker) Run the deploy command in the directory containing your `worker.toml` file: ```nextra-code arcade deploy ``` You should see output like the following: ```nextra-code Deploying 'my-worker...' main.py:589 ⠏ Deploying 1 workers ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┓ ┃ Added ┃ Removed ┃ Updated ┃ No Changes ┃ ┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━┩ │ custom-toolkit │ │ │ │ └─────────────────┴─────────┴─────────┴────────────┘ ✅ Worker 'my-worker' deployed successfully. ``` * * * ## List your workers [Permalink for this section](https://docs.arcade.dev/home/serve-tools/arcade-deploy\#list-your-workers) Run the following command to list your workers: ```nextra-code arcade worker list ``` You should see output like the following: ```nextra-code Workers ┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ ID ┃ Cloud Deployed ┃ Engine Registered ┃ Enabled ┃ Host ┃ Toolkits ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ my-worker │ True │ True │ True │ https://4bdfrgfdgftlu0ahyko56gdsr.server.arcade.dev │ CustomToolkit │ └───────────┴────────────────┴───────────────────┴─────────┴─────────────────────────────────────────────────────┴───────────────┘ ``` Your worker and toolkits are now deployed and registered with the engine and ready to use! You can go to the [dashboard](https://api.arcade.dev/dashboard/workers) to see your worker and its details. [Run evaluations](https://docs.arcade.dev/home/evaluate-tools/run-evaluations "Run evaluations") [Docker](https://docs.arcade.dev/home/serve-tools/docker-worker "Docker") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Twilio Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") [Twilio](https://docs.arcade.dev/toolkits/social-communication/twilio/readme "Twilio") Reference # Twilio Toolkit | | | | --- | --- | | Name | twilio | | Package | [arcade\_twilio](https://pypi.org/project/arcade_twilio/0.1.0/) | | Repository | [Github](https://github.com/sdserranog/arcade-twilio) | | Install | `pip install arcade_twilio==0.1.0` | | Description | A twilio integration to send SMS and WhatsApps. | | Author | [sdserranog@gmail.com](mailto:sdserranog@gmail.com) | | Tool Name | Description | | --- | --- | | [SendSms](https://docs.arcade.dev/toolkits/social-communication/twilio/reference#sendsms) | Send an SMS/text message to a phone number | | [SendWhatsapp](https://docs.arcade.dev/toolkits/social-communication/twilio/reference#sendwhatsapp) | Send a WhatsApp message to a phone number | ### SendSms [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/reference\#sendsms) Send an SMS/text message to a phone number #### Parameters [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/reference\#parameters) - `phone_number` _(string, required)_ The phone number to send the message to. Use ‘my\_phone\_number’ when a phone number is not specified or when the request implies sending to the user themselves - `message` _(string, required)_ The text content to be sent via SMS * * * ### SendWhatsapp [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/reference\#sendwhatsapp) Send a WhatsApp message to a phone number #### Parameters [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/reference\#parameters-1) - `phone_number` _(string, required)_ The phone number to send the message to. Use ‘my\_phone\_number’ when a phone number is not specified or when the request implies sending to the user themselves - `message` _(string, required)_ The text content to be sent via WhatsApp [Readme](https://docs.arcade.dev/toolkits/social-communication/twilio/readme "Readme") [X](https://docs.arcade.dev/toolkits/social-communication/x "X") ## Stripe Payment Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") Payments & FinanceStripe # Stripe **Description:** Empower your agents to interact with the Stripe API. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/stripe) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_stripe)](https://pypi.org/project/arcade_stripe/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_stripe)](https://pypi.org/project/arcade_stripe/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_stripe)](https://pypi.org/project/arcade_stripe/)[![Downloads](https://img.shields.io/pypi/dm/arcade_stripe)](https://pypi.org/project/arcade_stripe/) The Arcade Stripe toolkit lets you interact with the Stripe API. Use these tools to build intelligent agents and applications that process payments, create invoices, and more. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#available-tools) | Tool Name | Description | | --- | --- | | Stripe.CreateCustomer | This tool will create a customer in Stripe. | | Stripe.ListCustomers | This tool will fetch a list of Customers from Stripe. | | Stripe.CreateProduct | This tool will create a product in Stripe. | | Stripe.ListProducts | This tool will fetch a list of Products from Stripe. | | Stripe.CreatePrice | This tool will create a price in Stripe. If a product has not already been | | Stripe.ListPrices | This tool will fetch a list of Prices from Stripe. | | Stripe.CreatePaymentLink | This tool will create a payment link in Stripe. | | Stripe.ListInvoices | This tool will list invoices in Stripe. | | Stripe.CreateInvoice | This tool will create an invoice in Stripe. | | Stripe.CreateInvoiceItem | This tool will create an invoice item in Stripe. | | Stripe.FinalizeInvoice | This tool will finalize an invoice in Stripe. | | Stripe.RetrieveBalance | This tool will retrieve the balance from Stripe. It takes no input. | | Stripe.CreateRefund | This tool will refund a payment intent in Stripe. | | Stripe.ListPaymentIntents | This tool will list payment intents in Stripe. | | Stripe.CreateBillingPortalSession | This tool will create a billing portal session. | If you need an action that’s not listed here, please [contact us](mailto:contact@arcade.dev) to request a new tool, or [create your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Stripe.CreateCustomer [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreatecustomer) Create a customer in Stripe. **Parameters** - **`name`** _(string, required)_: The name of the customer. - **`email`** _(string, optional)_: The email address of the customer. See Example > ## Stripe.ListCustomers [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripelistcustomers) Fetch a list of customers from Stripe. **Parameters** - **`limit`** _(int, optional, defaults to 10)_: A limit on the number of objects to be returned. Limit can range between 1 and 100. - **`email`** _(string, optional)_: A case-sensitive filter on the list based on the customer’s email field. See Example > ## Stripe.CreateProduct [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreateproduct) Create a product in Stripe. **Parameters** - **`name`** _(string, required)_: The name of the product. - **`description`** _(string, optional)_: The description of the product. See Example > ## Stripe.ListProducts [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripelistproducts) Fetch a list of products from Stripe. **Parameters** - **`limit`** _(int, optional, defaults to 10)_: A limit on the number of products returned. Limit can range between 1 and 100, and defaults to 10. See Example > ## Stripe.CreatePrice [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreateprice) Create a price in Stripe. **Parameters** - **`product`** _(string, required)_: The ID of the product to create the price for. - **`unit_amount`** _(int, required)_: The unit amount of the price in cents. - **`currency`** _(string, required)_: The currency of the price. See Example > ## Stripe.ListPrices [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripelistprices) Fetch a list of prices from Stripe. **Parameters** - **`product`** _(string, optional)_: The ID of the product to list prices for. - **`limit`** _(int, optional, defaults to 10)_: A limit on the number of objects to be returned. Limit can range between 1 and 100, and defaults to 10. See Example > ## Stripe.CreatePaymentLink [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreatepaymentlink) Create a payment link in Stripe. **Parameters** - **`price`** _(string, required)_: The ID of the price to create the payment link for. - **`quantity`** _(int, required)_: The quantity of the product to include. See Example > ## Stripe.ListInvoices [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripelistinvoices) List invoices in Stripe. **Parameters** - **`customer`** _(string, optional)_: The ID of the customer to list invoices for. - **`limit`** _(int, optional, defaults to 10)_: A limit on the number of invoices returned. Limit can range between 1 and 100, and defaults to 10. See Example > ## Stripe.CreateInvoice [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreateinvoice) Create an invoice in Stripe. **Parameters** - **`customer`** _(string, required)_: The ID of the customer to create the invoice for. - **`days_until_due`** _(int, optional)_: The number of days until the invoice is due. See Example > ## Stripe.CreateInvoiceItem [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreateinvoiceitem) Create an invoice item in Stripe. **Parameters** - **`customer`** _(string, required)_: The ID of the customer to create the invoice item for. - **`price`** _(string, required)_: The ID of the price for the item. - **`invoice`** _(string, required)_: The ID of the invoice to create the item for. See Example > ## Stripe.FinalizeInvoice [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripefinalizeinvoice) Finalize an invoice in Stripe. **Parameters** - **`invoice`** _(string, required)_: The ID of the invoice to finalize. See Example > ## Stripe.RetrieveBalance [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#striperetrievebalance) Retrieve the balance from Stripe. This tool takes no inputs. See Example > ## Stripe.CreateRefund [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreaterefund) Refund a payment intent in Stripe. **Parameters** - **`payment_intent`** _(string, required)_: The ID of the PaymentIntent to refund. - **`amount`** _(int, optional)_: The refund amount to refund in cents. See Example > ## Stripe.ListPaymentIntents [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripelistpaymentintents) List payment intents in Stripe. **Parameters** - **`customer`** _(string, optional)_: The ID of the customer to list payment intents for. - **`limit`** _(int, optional)_: A limit on the number of payment intents returned. Limit can range between 1 and 100, and defaults to 10. See Example > ## Stripe.CreateBillingPortalSession [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#stripecreatebillingportalsession) Create a billing portal session in Stripe. **Parameters** - **`customer`** _(string, required)_: The ID of the customer to create the billing portal session for. - **`return_url`** _(string, optional)_: The default URL to return to afterwards. See Example > ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/payments/stripe\#auth) The Arcade Stripe toolkit uses the [Stripe Agent Toolkit](https://github.com/stripe/agent-toolkit) to interact with the Stripe API. - **Required Secret:** - `STRIPE_SECRET_KEY`: Your Stripe API key. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_stripe\\ ```](https://docs.arcade.dev/home/hosting-overview) [Web](https://docs.arcade.dev/toolkits/development/web/web "Web") [Google Finance](https://docs.arcade.dev/toolkits/search/google_finance "Google Finance") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Notion Integration Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") Notion # Notion **Description:** Enable agents to interact with Notion. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/notion) **Auth:** User authorizationvia the [Notion auth provider](https://docs.arcade.dev/home/auth-providers/notion) [![PyPI Version](https://img.shields.io/pypi/v/arcade_notion-toolkit)](https://pypi.org/project/arcade_notion-toolkit/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_notion-toolkit)](https://pypi.org/project/arcade_notion-toolkit/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_notion-toolkit)](https://pypi.org/project/arcade_notion-toolkit/)[![Downloads](https://img.shields.io/pypi/dm/arcade_notion-toolkit)](https://pypi.org/project/arcade_notion-toolkit/) The Arcade Notion toolkit provides a pre-built set of tools for interacting with Notion. These tools make it easy to build agents and AI apps that can: - Get a page’s content - Create a new page - Search for pages or databases by title - Get the metadata of a Notion object (page or database) - Get a workspace’s folder structure ## Available tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#available-tools) These tools are currently available in the Arcade Notion toolkit. | Tool Name | Description | | --- | --- | | NotionToolkit.GetPageContentById | Get the content of a Notion page as markdown by page ID. | | NotionToolkit.GetPageContentByTitle | Get the content of a Notion page as markdown by title. | | NotionToolkit.CreatePage | Create a new Notion page by specifying a parent page title. | | NotionToolkit.SearchByTitle | Search for pages or databases by title. | | NotionToolkit.GetObjectMetadata | Get the metadata of a Notion object (page or database) using its title or ID. | | NotionToolkit.GetWorkspaceStructure | Get the complete workspace structure of your Notion workspace. | If you need to perform an action that’s not listed here, you can [get in touch with us](mailto:contact@arcade.dev) to request a new tool, or [create your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Notion auth provider](https://docs.arcade.dev/home/auth-providers/notion). ## NotionToolkit.GetPageContentById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#notiontoolkitgetpagecontentbyid) See Example > Get the content of a Notion page as markdown with the page’s ID. **Parameters** - **`page_id`** _(string, required)_ The ID of the page to get content from. * * * ## NotionToolkit.GetPageContentByTitle [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#notiontoolkitgetpagecontentbytitle) See Example > Get the content of a Notion page as markdown with the page’s title. **Parameters** - **`title`** _(string, required)_ The title of the page to get content from. * * * ## NotionToolkit.CreatePage [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#notiontoolkitcreatepage) See Example > Create a new Notion page by specifying an existing parent page and the new page details. **Parameters** - **`parent_title`** _(string, required)_ Title of an existing page where the new page will be created. - **`title`** _(string, required)_ Title of the new page. - **`content`** _(string, optional)_ The content of the new page. * * * ## NotionToolkit.SearchByTitle [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#notiontoolkitsearchbytitle) See Example > Search for similar titles of pages, databases, or both within the user’s Notion workspace. This tool returns minimal information about matching objects without their content. **Parameters** - **`query`** _(string, optional)_ A substring to search for within page and database titles. If not provided, all items are returned. - **`select`** _(str, optional)_ Limit the search to only pages or only databases. If provided, must be one of `page` or `database`. Defaults to both. - **`order_by`** _(str, optional)_ The direction to sort search results by last edited time. Must be either `ascending` or `descending`. Defaults to `descending`. - **`limit`** _(int, optional)_ The maximum number of results to return. Defaults to 100. Use -1 for no limit. * * * ## NotionToolkit.GetObjectMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#notiontoolkitgetobjectmetadata) See Example > Get the metadata of a Notion object (page or database) using its title or ID. One of `object_title` or `object_id` must be provided (but not both). The returned metadata includes the object’s ID, timestamps, properties, URL, and more. **Parameters** - **`object_title`** _(string, optional)_ The title of the page or database whose metadata to retrieve. - **`object_id`** _(string, optional)_ The ID of the page or database whose metadata to retrieve. - **`object_type`** _(str, optional)_ The type of object to match the title against. If provided, must be one of `page` or `database`. Defaults to both if not provided. * * * ## NotionToolkit.GetWorkspaceStructure [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#notiontoolkitgetworkspacestructure) See Example > Get the complete workspace structure of your Notion workspace. This tool returns a hierarchical view of pages and databases, making it easier to understand the organization of your workspace. **Parameters** _None_ ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/notion\#auth) The Arcade Notion toolkit uses the [Notion auth provider](https://docs.arcade.dev/home/auth-providers/notion) to connect to users’ Notion accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Notion auth provider](https://docs.arcade.dev/home/auth-providers/notion#configuring-notion-auth) with your own Notion app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_notion_toolkit\\ ```](https://docs.arcade.dev/home/hosting-overview) [Outlook Mail](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail "Outlook Mail") [Obsidian](https://docs.arcade.dev/toolkits/productivity/obsidian "Obsidian") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## X Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") X # X auth provider The X auth provider enables tools and agents to call the X (Twitter) API on behalf of a user. Behind the scenes, the Arcade Engine and the X auth provider seamlessly manage X OAuth 2.0 authorization for your users. Want to quickly get started with X services in your agent or AI app? The pre-built [Arcade X toolkit](https://docs.arcade.dev/toolkits/social-communication/x) is what you want! ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#whats-documented-here) This page describes how to use and configure X auth with Arcade. This auth provider is used by: - The [Arcade X toolkit](https://docs.arcade.dev/toolkits/social-communication/x), which provides pre-built tools for interacting with X - Your [app code](https://docs.arcade.dev/home/auth-providers/x#using-x-auth-in-app-code) that needs to call X APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/x#using-x-auth-in-custom-tools) that need to call X APIs ## Configuring X auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#configuring-x-auth) In a production environment, you will most likely want to use your own X app credentials. This way, your users will see your application’s name requesting permission. You can use your own X credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your X app credentials, let’s go through the steps to create a X app. ### Create an X app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#create-an-x-app) - Follow X’s guide to [creating an app](https://developer.x.com/en/docs/x-api/getting-started/getting-access-to-the-x-api) - Enable user authentication for your new app, and set its type to “Web App, Automated App or Bot” - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the client ID and client secret to use below Next, add the X app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own X Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#configuring-your-own-x-auth-provider-in-arcade) There are two ways to configure your X app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure X Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **X**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-x-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your X app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require X auth using your Arcade account credentials, the Arcade Engine will automatically use this X OAuth provider. If you have multiple X providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring X auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#set-environment-variables) Set the following environment variables: ```nextra-code export X_CLIENT_ID="" export X_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code X_CLIENT_ID="" X_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#edit-the-engine-configuration) Edit the `engine.yaml` file and add an `x` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-x description: "The default X provider" enabled: true type: oauth2 provider_id: x client_id: ${env:X_CLIENT_ID} client_secret: ${env:X_CLIENT_SECRET} ``` ## Using X auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#using-x-auth-in-app-code) Use the X auth provider in your own agents and AI apps to get a user token for the X API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for X: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="x", scopes=["tweet.read", "tweet.write", "users.read"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "x", [\ "tweet.read",\ "tweet.write",\ "users.read",\ ]); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using X auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/x\#using-x-auth-in-custom-tools) You can use the pre-built [Arcade X toolkit](https://docs.arcade.dev/toolkits/social-communication/x) to quickly build agents and AI apps that interact with X. If the pre-built tools in the X toolkit don’t meet your needs, you can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the X API. Use the `X()` auth class to specify that a tool requires authorization with X. The `context.authorization.token` field will be automatically populated with the user’s X token: ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import X @tool( requires_auth=X( scopes=["tweet.read", "tweet.write", "users.read"], ) ) async def post_tweet( context: ToolContext, tweet_text: Annotated[str, "The text content of the tweet you want to post"], ) -> Annotated[str, "Success string and the URL of the tweet"]: """Post a tweet to X (Twitter).""" url = "https://api.x.com/2/tweets" headers = { "Authorization": f"Bearer {context.authorization.token}", "Content-Type": "application/json", } payload = {"text": tweet_text} async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, json=payload) response.raise_for_status() tweet_id = response.json()["data"]["id"] return f"Tweet with id {tweet_id} posted successfully. URL: https://x.com/x/status/{tweet_id}" ``` [Twitch](https://docs.arcade.dev/home/auth-providers/twitch "Twitch") [Zoom](https://docs.arcade.dev/home/auth-providers/zoom "Zoom") ## User Authentication Flows [Home](https://docs.arcade.dev/home "Home") [Mastra](https://docs.arcade.dev/home/mastra/overview "Mastra") Managing user authorization ## Dynamic Tool Loading with Toolsets [Permalink for this section](https://docs.arcade.dev/home/mastra/user-auth-interrupts\#dynamic-tool-loading-with-toolsets) Mastra lets you dynamically provide tools to an agent at runtime using toolsets. This approach is essential when integrating Arcade tools in web applications where each user needs their own authentication flow. ### Per-User Tool Authentication in Web Applications [Permalink for this section](https://docs.arcade.dev/home/mastra/user-auth-interrupts\#per-user-tool-authentication-in-web-applications) In web applications serving multiple users, implement user-specific authentication flows with these steps: First, set up your Mastra configuration and agents in separate files: ```nextra-code // @/mastra/index.ts import { Mastra } from "@mastra/core"; import { githubAgent } from "./agents/githubAgent"; // Initialize Mastra export const mastra = new Mastra({ agents: { githubAgent, }, }); ``` ```nextra-code // @/mastra/agents/githubAgent.ts import { Agent } from "@mastra/core/agent"; import { anthropic } from "@ai-sdk/anthropic"; // Create the agent without tools - we'll add them at runtime export const githubAgent = new Agent({ name: "githubAgent", instructions: `You are a GitHub Agent that helps with repository management. You can help with tasks like: - Listing repositories - Creating and managing issues - Viewing pull requests - Managing repository settings If a tool requires authorization, you will receive an authorization URL. When that happens, clearly present this URL to the user and ask them to visit it to grant permissions.`, model: anthropic("claude-3-7-sonnet-20250219"), // No tools defined here - will be provided dynamically at runtime }); ``` Then, create an API endpoint that provides tools dynamically: ```nextra-code // app/api/chat/route.ts import { NextRequest, NextResponse } from "next/server"; import { mastra } from "@/mastra"; import { Arcade } from "@arcadeai/arcadejs"; import { getUserSession } from "@/lib/auth"; // Your authentication handling import { toZodToolSet } from "@arcadeai/arcadejs/lib"; import { executeOrAuthorizeZodTool } from "@arcadeai/arcadejs/lib"; export async function POST(req: NextRequest) { // Extract request data const { messages, threadId } = await req.json(); // Authenticate the user const session = await getUserSession(req); if (!session) { return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); } try { // Get the agent from Mastra const githubAgent = mastra.getAgent("githubAgent"); const arcade = new Arcade(); const githubToolkit = await arcade.tools.list({ toolkit: "github", limit: 30 }); // Fetch user-specific Arcade tools for GitHub const arcadeTools = toZodToolSet({ tools: githubToolkit.items, client: arcade, userId: session.user.email, executeFactory: executeOrAuthorizeZodTool, }); // Stream the response with dynamically provided tools const response = await githubAgent.stream(messages, { threadId, // Optional: For maintaining conversation context resourceId: session.user.id, // Optional: For associating memory with user toolChoice: "auto", toolsets: { arcade: arcadeTools, // Provide tools in a named toolset }, }); // Return streaming response return response.toDataStreamResponse(); } catch (error) { console.error("Error processing GitHub request:", error); return NextResponse.json( { message: "Failed to process request" }, { status: 500 }, ); } } ``` This approach provides several benefits: - Each user gets their own separate authentication flow with Arcade tools - A single agent instance works with multiple user-specific toolsets The toolsets parameter provides tools only for the current request without modifying the agent’s base configuration. This makes it ideal for multi-user applications where each user needs their own secure OAuth flow with Arcade. ## Handling Tool Authorization [Permalink for this section](https://docs.arcade.dev/home/mastra/user-auth-interrupts\#handling-tool-authorization) When a tool requires user authorization, the agent receives a response with: ```nextra-code { authorization_required: true, url: "https://auth.arcade.com/...", message: "Forward this url to the user for authorization" } ``` Your agent should recognize this pattern and present the URL to the user. To create a better user experience: - Display the authorization URL as a clickable link in your UI - Explain which service needs authorization and why - Provide a way for users to retry their request after authorization ## Tips for Selecting Tools [Permalink for this section](https://docs.arcade.dev/home/mastra/user-auth-interrupts\#tips-for-selecting-tools) - **Focus on relevance**: Choose tools that directly support your agent’s specific purpose - **Consider performance**: Some tools may have higher latency than others - **Handle errors gracefully**: Implement robust error handling for third-party service failures - **Create clear user flows**: Design intuitive authorization experiences ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/mastra/user-auth-interrupts\#next-steps) After integrating Arcade tools into your Mastra agent, you can: - Add [memory capabilities](https://mastra.ai/docs/agents/agent-memory) to maintain context between interactions - Implement [structured workflows](https://mastra.ai/docs/workflows/overview) for complex multi-step operations - Enhance your agent with [RAG capabilities](https://mastra.ai/docs/rag/overview) for domain-specific knowledge - Set up [logging and tracing](https://mastra.ai/docs/observability/logging) to monitor performance For more detailed information on Mastra’s capabilities, visit the [Mastra documentation](https://mastra.ai/docs). [Using Arcade tools](https://docs.arcade.dev/home/mastra/use-arcade-tools "Using Arcade tools") [Overview](https://docs.arcade.dev/home/oai-agents/overview "Overview") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Integrations Overview # Integrations There are 4 designations for Arcade integrations: ## Arcade Toolkit Official integrations developed and maintained by Arcade. ## Verified Toolkit Community-created integrations, thoroughly tested and verified by Arcade. ## Community Toolkit Created and maintained by the Arcade community, offering a wide range of integrations. ## Auth Integration Auth integrations allow you to develop custom tools that connect your agent APIs and services. ## Build your own integration Don't see what you need? Use Arcade's SDK to integrate with any service or API. [Learn how to build a toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit) 96 result(s) found All ToolsProductivity & DocsSocial & CommunicationDeveloper ToolsEntertainmentSearchPayments & FinanceSales [![Asana logo](https://docs.arcade.dev/images/icons/asana.svg)\\ \\ Asana\\ \\ Arcade Toolkit\\ \\ Manage projects, tasks, and more in Asana with your agents.](https://docs.arcade.dev/toolkits/productivity/asana) [![Code Runner logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fe2b.png&w=96&q=75)\\ \\ Code Runner\\ \\ Arcade Toolkit\\ \\ Execute and test code in a secure sandbox environment](https://docs.arcade.dev/toolkits/development/code-sandbox) [![Confluence logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fatlassian.png&w=96&q=75)\\ \\ Confluence\\ \\ Arcade Toolkit\\ \\ Manage Confluence pages and spaces with your agents](https://docs.arcade.dev/toolkits/productivity/confluence) [![Dropbox logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fdropbox.png&w=96&q=75)\\ \\ Dropbox\\ \\ Arcade Toolkit\\ \\ Manage Dropbox files and folders with your agents](https://docs.arcade.dev/toolkits/productivity/dropbox) [![GitHub logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgithub.png&w=96&q=75)\\ \\ GitHub\\ \\ Arcade Toolkit\\ \\ Interact with private and public GitHub repositories, issues, pull requests, and more](https://docs.arcade.dev/toolkits/development/github/github) [![Gmail logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgmail.png&w=96&q=75)\\ \\ Gmail\\ \\ Arcade Toolkit\\ \\ Send, write, draft, delete, trash, and search Gmail emails with your agents.](https://docs.arcade.dev/toolkits/productivity/google/gmail) [![Google Calendar logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_calendar.png&w=96&q=75)\\ \\ Google Calendar\\ \\ Arcade Toolkit\\ \\ Create, update, delete, and search events in Google Calendar with your agents.](https://docs.arcade.dev/toolkits/productivity/google/calendar) [![Google Contacts logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_contacts.png&w=96&q=75)\\ \\ Google Contacts\\ \\ Arcade Toolkit\\ \\ Create and search contacts in Google Contacts with your agents.](https://docs.arcade.dev/toolkits/productivity/google/contacts) [![Google Docs logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_docs.png&w=96&q=75)\\ \\ Google Docs\\ \\ Arcade Toolkit\\ \\ Create, edit, and get information about Google Docs documents with your agents.](https://docs.arcade.dev/toolkits/productivity/google/docs) [![Google Drive logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_drive.png&w=96&q=75)\\ \\ Google Drive\\ \\ Arcade Toolkit\\ \\ List documents in Google Drive with your agents.](https://docs.arcade.dev/toolkits/productivity/google/drive) [![Google Finance logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_finance.png&w=96&q=75)\\ \\ Google Finance\\ \\ Arcade Toolkit\\ \\ Get stock data from Google Finance](https://docs.arcade.dev/toolkits/search/google_finance) [![Google Flights logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_flights.png&w=96&q=75)\\ \\ Google Flights\\ \\ Arcade Toolkit\\ \\ Search for flights](https://docs.arcade.dev/toolkits/search/google_flights) [![Google Hotels logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_hotels.png&w=96&q=75)\\ \\ Google Hotels\\ \\ Arcade Toolkit\\ \\ Search for hotels](https://docs.arcade.dev/toolkits/search/google_hotels) [![Google Jobs logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_jobs.png&w=96&q=75)\\ \\ Google Jobs\\ \\ Arcade Toolkit\\ \\ Search for job openings with Google Jobs.](https://docs.arcade.dev/toolkits/search/google_jobs) [![Google Maps logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_maps.png&w=96&q=75)\\ \\ Google Maps\\ \\ Arcade Toolkit\\ \\ Get directions between two locations with Google Maps](https://docs.arcade.dev/toolkits/search/google_maps) [![Google News logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_news.png&w=96&q=75)\\ \\ Google News\\ \\ Arcade Toolkit\\ \\ Search for news articles with Google News](https://docs.arcade.dev/toolkits/search/google_news) [![Google Search logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_search.png&w=96&q=75)\\ \\ Google Search\\ \\ Arcade Toolkit\\ \\ Perform Google searches and retrieve relevant information](https://docs.arcade.dev/toolkits/search/google_search) [![Google Sheets logo](https://docs.arcade.dev/images/icons/google_sheets.svg)\\ \\ Google Sheets\\ \\ Arcade Toolkit\\ \\ Create, read, and update Google Sheets with your agents.](https://docs.arcade.dev/toolkits/productivity/google/sheets) [![Google Shopping logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fgoogle_shopping.png&w=96&q=75)\\ \\ Google Shopping\\ \\ Arcade Toolkit\\ \\ Search for products on Google Shopping.](https://docs.arcade.dev/toolkits/search/google_shopping) [![HubSpot logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fhubspot.png&w=96&q=75)\\ \\ HubSpot\\ \\ Arcade Toolkit\\ \\ Manage companies, contacts, deals, and more in HubSpot with your agents.](https://docs.arcade.dev/toolkits/sales/hubspot) [![LinkedIn logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Flinkedin.png&w=96&q=75)\\ \\ LinkedIn\\ \\ Arcade Toolkit\\ \\ Connect and interact with LinkedIn's professional network through your agents](https://docs.arcade.dev/toolkits/social-communication/linkedin) [![Notion logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fnotion.png&w=96&q=75)\\ \\ Notion\\ \\ Arcade Toolkit\\ \\ Create, read, and search Notion pages](https://docs.arcade.dev/toolkits/productivity/notion) [![Outlook Calendar logo](https://docs.arcade.dev/images/icons/outlook_calendar.svg)\\ \\ Outlook Calendar\\ \\ Arcade Toolkit\\ \\ Manage Outlook calendar with your agents](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar) [![Outlook Mail logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Foutlook_mail.png&w=96&q=75)\\ \\ Outlook Mail\\ \\ Arcade Toolkit\\ \\ Manage Outlook emails with your agents](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail) [![Reddit logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Freddit.png&w=96&q=75)\\ \\ Reddit\\ \\ Arcade Toolkit\\ \\ Interact with Reddit with your agents](https://docs.arcade.dev/toolkits/social-communication/reddit) [![Salesforce logo](https://docs.arcade.dev/images/icons/salesforce.svg)\\ \\ Salesforce\\ \\ Arcade Toolkit\\ \\ Manage customer relationships and sales with your agents.](https://docs.arcade.dev/toolkits/sales/salesforce) [![Slack logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fslack.png&w=96&q=75)\\ \\ Slack\\ \\ Arcade Toolkit\\ \\ Send and receive messages to Slack channels and users with agents](https://docs.arcade.dev/toolkits/social-communication/slack) [![Spotify logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fspotify.png&w=96&q=75)\\ \\ Spotify\\ \\ Arcade Toolkit\\ \\ Control music playback and manage playlists on Spotify](https://docs.arcade.dev/toolkits/entertainment/spotify) [![Stripe logo](https://docs.arcade.dev/images/icons/stripe.svg)\\ \\ Stripe\\ \\ Arcade Toolkit\\ \\ Process payments and manage subscriptions with your agents.](https://docs.arcade.dev/toolkits/payments/stripe) [![Walmart Search logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fwalmart.png&w=96&q=75)\\ \\ Walmart Search\\ \\ Arcade Toolkit\\ \\ Search and get details about products listed on Walmart.](https://docs.arcade.dev/toolkits/search/walmart) [![Web logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fweb.png&w=96&q=75)\\ \\ Web\\ \\ Arcade Toolkit\\ \\ Browse and interact with web pages programmatically](https://docs.arcade.dev/toolkits/development/web/web) [![X logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Ftwitter.png&w=96&q=75)\\ \\ X\\ \\ Arcade Toolkit\\ \\ Integrate agents with X (Twitter), including tweets, users, and more](https://docs.arcade.dev/toolkits/social-communication/x) [![Youtube Search logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fyoutube.png&w=96&q=75)\\ \\ Youtube Search\\ \\ Arcade Toolkit\\ \\ Search and get details about YouTube videos.](https://docs.arcade.dev/toolkits/search/youtube) [![Zoom logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fzoom.png&w=96&q=75)\\ \\ Zoom\\ \\ Arcade Toolkit\\ \\ Join and manage Zoom meetings with your agents](https://docs.arcade.dev/toolkits/social-communication/zoom) [![Twilio logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Ftwilio.png&w=96&q=75)\\ \\ Twilio\\ \\ Verified Toolkit\\ \\ Send SMS and WhatsApp messages through Twilio's platform](https://docs.arcade.dev/toolkits/social-communication/twilio/readme) [![Close.io logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fcloseio.png&w=96&q=75)\\ \\ Close.io\\ \\ Community Toolkit\\ \\ Manage leads, contacts, and deals in Close.io CRM](https://docs.arcade.dev/toolkits/productivity/closeio) [![Discord logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fdiscord.png&w=96&q=75)\\ \\ Discord\\ \\ Auth Integration\\ \\ Manage Discord servers, channels, and more with your agents](https://docs.arcade.dev/toolkits/social-communication/discord) [![Jira logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fatlassian.png&w=96&q=75)\\ \\ Jira\\ \\ Auth Integration\\ \\ Manage Jira projects, issues, and more with your agents](https://docs.arcade.dev/toolkits/productivity/jira) [![Obsidian logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fobsidian.png&w=96&q=75)\\ \\ Obsidian\\ \\ Community Toolkit\\ \\ Create, edit, and manage Obsidian notes](https://docs.arcade.dev/toolkits/productivity/obsidian) [![Twitch logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Ftwitch.png&w=96&q=75)\\ \\ Twitch\\ \\ Auth Integration\\ \\ Create clips, get videos, and more from Twitch with your agents](https://docs.arcade.dev/toolkits/entertainment/twitch) ![ADP Workforce Now logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fadp.png&w=96&q=75) ADP Workforce Now Arcade Toolkit Coming Soon Manage payroll, HR, and workforce data with your agents. ![Aha logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Faha.png&w=96&q=75) Aha Arcade Toolkit Coming Soon Manage product roadmaps and strategy with your agents. ![Airtable logo](https://docs.arcade.dev/images/icons/airtable.svg) Airtable Arcade Toolkit Coming Soon Create, edit, and manage Airtable bases with your agents. ![Amplitude logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Famplitude.png&w=96&q=75) Amplitude Arcade Toolkit Coming Soon Analyze user behavior and product analytics with your agents. ![Ashby logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fashby.png&w=96&q=75) Ashby Arcade Toolkit Coming Soon Manage recruiting and hiring processes with your agents. ![Auth0 logo](https://docs.arcade.dev/images/icons/auth0.svg) Auth0 Arcade Toolkit Coming Soon Manage authentication and authorization with your agents. ![BambooHR logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbamboohr.png&w=96&q=75) BambooHR Arcade Toolkit Coming Soon Manage employee data and HR processes with your agents. ![Basecamp logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbasecamp.png&w=96&q=75) Basecamp Arcade Toolkit Coming Soon Manage projects, tasks, and team communication with your agents. ![Bill.com logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbill.png&w=96&q=75) Bill.com Arcade Toolkit Coming Soon Manage invoices and payments with your agents. ![Bitbucket logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbitbucket.png&w=96&q=75) Bitbucket Arcade Toolkit Coming Soon Manage repositories, pull requests, and pipelines with your agents. ![Bluesky logo](https://docs.arcade.dev/images/icons/bluesky.svg) Bluesky Arcade Toolkit Coming Soon Interact with Bluesky with your agents. ![Box logo](https://docs.arcade.dev/images/icons/box.svg) Box Arcade Toolkit Coming Soon Manage files and folders in Box with your agents. ![Braze logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbraze.png&w=96&q=75) Braze Arcade Toolkit Coming Soon Manage customer engagement campaigns with your agents. ![Brex logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbrex.png&w=96&q=75) Brex Arcade Toolkit Coming Soon Manage business expenses and cards with your agents. ![Buffer logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fbuffer.png&w=96&q=75) Buffer Arcade Toolkit Coming Soon Schedule and manage social media posts with your agents. ![Calendly logo](https://docs.arcade.dev/images/icons/calendly.svg) Calendly Arcade Toolkit Coming Soon Manage scheduling and appointments with your agents. ![ClickUp logo](https://docs.arcade.dev/images/icons/clickup.svg) ClickUp Arcade Toolkit Coming Soon Manage projects, tasks, and documents with your agents. ![Coinbase logo](https://docs.arcade.dev/images/icons/coinbase.svg) Coinbase Arcade Toolkit Coming Soon Manage cryptocurrency transactions and wallets with your agents. ![Datadog logo](https://docs.arcade.dev/images/icons/datadog.svg) Datadog Arcade Toolkit Coming Soon Monitor applications and infrastructure with your agents. ![DigitalOcean logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fdigitalocean.png&w=96&q=75) DigitalOcean Arcade Toolkit Coming Soon Manage cloud servers and infrastructure with your agents. ![eBay logo](https://docs.arcade.dev/images/icons/ebay.svg) eBay Arcade Toolkit Coming Soon Manage listings, orders, and inventory on eBay with your agents. ![Evernote logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fevernote.png&w=96&q=75) Evernote Arcade Toolkit Coming Soon Create and manage notes with your agents. ![Factorial logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Ffactorial.png&w=96&q=75) Factorial Arcade Toolkit Coming Soon Manage HR processes and employee data with your agents. ![Figma logo](https://docs.arcade.dev/images/icons/figma.svg) Figma Arcade Toolkit Coming Soon Access design files and collaborate on designs with your agents. ![GitLab logo](https://docs.arcade.dev/images/icons/gitlab.svg) GitLab Arcade Toolkit Coming Soon Manage repositories, issues, and merge requests with your agents. ![Heroku logo](https://docs.arcade.dev/images/icons/heroku.svg) Heroku Arcade Toolkit Coming Soon Deploy and manage applications on Heroku with your agents. ![Hootsuite logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fhootsuite.png&w=96&q=75) Hootsuite Arcade Toolkit Coming Soon Manage and schedule social media content with your agents. ![Intercom logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fintercom.png&w=96&q=75) Intercom Arcade Toolkit Coming Soon Manage customer communications and support with your agents. ![Linear logo](https://docs.arcade.dev/images/icons/linear.svg) Linear Arcade Toolkit Coming Soon Manage issues and projects with your agents. ![Mailchimp logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fmailchimp.png&w=96&q=75) Mailchimp Arcade Toolkit Coming Soon Manage email campaigns and subscribers with your agents. ![Microsoft Dynamics logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fmsft.png&w=96&q=75) Microsoft Dynamics Arcade Toolkit Coming Soon Manage CRM and ERP processes with your agents. ![Miro logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fmiro&w=96&q=75) Miro Arcade Toolkit Coming Soon Create and collaborate on visual boards with your agents. ![Model Context Protocol (MCP) logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fmcp.png&w=96&q=75) Model Context Protocol (MCP) Arcade Toolkit Coming Soon Manage context and improve AI interactions with your agents. ![Monday logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fmonday.png&w=96&q=75) Monday Arcade Toolkit Coming Soon Manage projects and workflows with your agents. ![Netsuite logo](https://docs.arcade.dev/images/icons/netsuite.svg) Netsuite Arcade Toolkit Coming Soon Manage financial and business operations with your agents. ![Okta logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fokta.png&w=96&q=75) Okta Arcade Toolkit Coming Soon Manage identity and access with your agents. ![OneDrive logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fmsft.png&w=96&q=75) OneDrive Arcade Toolkit Coming Soon Manage OneDrive files and folders with your agents ![Pinecone logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fpinecone.png&w=96&q=75) Pinecone Arcade Toolkit Coming Soon Manage vector databases and similarity search with your agents. ![Pinterest logo](https://docs.arcade.dev/images/icons/pinterest.svg) Pinterest Arcade Toolkit Coming Soon Create and manage pins and boards with your agents. ![Pipedrive logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fpipedrive.png&w=96&q=75) Pipedrive Arcade Toolkit Coming Soon Manage sales pipelines and leads with your agents. ![Plaid logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fplaid.png&w=96&q=75) Plaid Arcade Toolkit Coming Soon Connect with financial accounts and manage financial data with your agents. ![QuickBooks logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fquickbooks.png&w=96&q=75) QuickBooks Arcade Toolkit Coming Soon Manage accounting and finances with your agents. ![Shopify logo](https://docs.arcade.dev/images/icons/shopify.svg) Shopify Arcade Toolkit Coming Soon Manage e-commerce stores and products with your agents. ![SingleStore logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fsinglestore.png&w=96&q=75) SingleStore Arcade Toolkit Coming Soon Manage databases and data operations with your agents. ![Snowflake logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fsnowflake.png&w=96&q=75) Snowflake Arcade Toolkit Coming Soon Manage data warehouses and analytics with your agents. ![Splunk logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fsplunk.png&w=96&q=75) Splunk Arcade Toolkit Coming Soon Monitor and analyze machine data with your agents. ![Square logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fsquare.png&w=96&q=75) Square Arcade Toolkit Coming Soon Process payments and manage business operations with your agents. ![Squarespace logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fsquarespace.png&w=96&q=75) Squarespace Arcade Toolkit Coming Soon Manage websites and online presence with your agents. ![TikTok logo](https://docs.arcade.dev/images/icons/tiktok.svg) TikTok Arcade Toolkit Coming Soon Create and manage TikTok content with your agents. ![Trello logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Ftrello.png&w=96&q=75) Trello Arcade Toolkit Coming Soon Manage boards, cards, and lists with your agents. ![Vercel logo](https://docs.arcade.dev/images/icons/vercel.svg) Vercel Arcade Toolkit Coming Soon Deploy and manage web applications with your agents. ![Weaviate logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fweaviate.png&w=96&q=75) Weaviate Arcade Toolkit Coming Soon Manage vector databases and semantic search with your agents. ![Workday logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fworkday.png&w=96&q=75) Workday Arcade Toolkit Coming Soon Manage HR, finance, and planning with your agents. ![Wrike logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fwrike.png&w=96&q=75) Wrike Arcade Toolkit Coming Soon Manage projects and collaborate with your agents. ![Xero logo](https://docs.arcade.dev/images/icons/xero.svg) Xero Arcade Toolkit Coming Soon Manage accounting and finances with your agents. ![Zendesk logo](https://docs.arcade.dev/_next/image?url=%2Fimages%2Ficons%2Fzendesk.png&w=96&q=75) Zendesk Arcade Toolkit Coming Soon Manage customer support and service with your agents. [Asana](https://docs.arcade.dev/toolkits/productivity/asana "Asana") ## Agent Authorization Simplified [Home](https://docs.arcade.dev/home "Home") AuthorizationHow Arcade Helps # How Arcade helps with Agent Authorization ### The challenges that Arcade solves [Permalink for this section](https://docs.arcade.dev/home/auth/how-arcade-helps\#the-challenges-that-arcade-solves) Applications that use models to perform tasks ( _agentic applications_) commonly require access to sensitive data and services. Authentication complexities often hinder AI from performing tasks that require user-specific information, like what emails you recently received or what’s coming up on your calendar. To retrieve this information, agentic applications need to be able to authenticate and authorize access to external services you use like Gmail or Google Calendar. Authenticating to retrieve information, however, is not the only challenge. Agentic applications also need to authenticate in order to **act** on your behalf - like sending an email or updating your calendar. Without auth, AI agents are severely limited in what they can do. ### How Arcade solves this [Permalink for this section](https://docs.arcade.dev/home/auth/how-arcade-helps\#how-arcade-solves-this) Arcade provides an authorization system that handles OAuth 2.0, API keys, and user tokens needed by AI agents to access external services through tools. This means your AI agents can now act on behalf of users securely and privately. With Arcade, developers can now create agents that can _act as the end users of their application_ to perform tasks like: - Creating a new Zoom meeting - Sending or reading email - Answering questions about files in Google Drive. ### Auth permissions and scopes [Permalink for this section](https://docs.arcade.dev/home/auth/how-arcade-helps\#auth-permissions-and-scopes) Each tool in Arcade’s toolkits has a set of required permissions - or, more commonly referred to in OAuth2, **scopes**. For example, the [`Google.SendEmail`](https://docs.arcade.dev/toolkits/productivity/google/gmail#sendemail) tool requires the [`https://www.googleapis.com/auth/gmail.send`](https://developers.google.com/identity/protocols/oauth2/scopes#gmail) scope. A scope is what the user has authorized someone else (in this case, the AI agent) to do on their behalf. In any OAuth2-compatible service, each kind of action requires a different set of permissions. This gives the user fine-grained control over what data third-party services can access and what actions can be executed in their accounts. When a tool is called, the Arcade Engine will check if the user has granted the required permissions. If not, it will automatically prompt the user to authorize the tool, coordinating the OAuth2 flow with the service provider. ### How to implement OAuth2-authorized tool calling [Permalink for this section](https://docs.arcade.dev/home/auth/how-arcade-helps\#how-to-implement-oauth2-authorized-tool-calling) To learn how Arcade allows for actions (tools) to be authorized through OAuth2 and how to implement it, check out [Authorized Tool Calling](https://docs.arcade.dev/home/auth/auth-tool-calling). ### Tools that don’t require authorization [Permalink for this section](https://docs.arcade.dev/home/auth/how-arcade-helps\#tools-that-dont-require-authorization) Some tools, like [`Search.SearchGoogle`](https://docs.arcade.dev/toolkits/search/google_search#searchgoogle), allow AI agents to retrieve information or perform actions without needing user-specific authorization. PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade(api_key="arcade_api_key") # or set the ARCADE_API_KEY env var # Use the Search.SearchGoogle tool to perform a web search response = await client.tools.execute( tool_name="Search.SearchGoogle", input={"query": "Latest AI advancements"}, ) print(response.output.value) ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(api_key="arcade_api_key"); // or set the ARCADE_API_KEY env var // Use the Search.SearchGoogle tool to perform a web search const response = await client.tools.execute({ tool_name: "Search.SearchGoogle", input: { query: "Latest AI advancements" }, }); console.log(response.output.value); ``` [Tool formats](https://docs.arcade.dev/home/use-tools/get-tool-definitions "Tool formats") [Authorized Tool Calling](https://docs.arcade.dev/home/auth/auth-tool-calling "Authorized Tool Calling") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Dropbox Integration Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") DropboxDropbox # Dropbox **Description:** Enable agents to interact with files and folders in Dropbox. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/dropbox) **Auth:** User authorization [![PyPI Version](https://img.shields.io/pypi/v/arcade_dropbox)](https://pypi.org/project/arcade_dropbox/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_dropbox)](https://pypi.org/project/arcade_dropbox/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_dropbox)](https://pypi.org/project/arcade_dropbox/)[![Downloads](https://img.shields.io/pypi/dm/arcade_dropbox)](https://pypi.org/project/arcade_dropbox/) The Arcade Dropbox toolkit provides a pre-built set of tools for interacting with Dropbox. These tools make it easy to build agents and AI apps that can: - Browse files and folders - Search for files and folders - Download files ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox\#available-tools) | Tool Name | Description | | --- | --- | | Dropbox.ListItemsInFolder | List all items in a folder. | | Dropbox.SearchFilesAndFolders | Search for files and folders in Dropbox. | | Dropbox.DownloadFile | Download a file from Dropbox. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Dropbox.ListItemsInFolder [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox\#dropboxlistitemsinfolder) See Example > List all items in a folder. **Parameters** - **folder\_path** _(string, required)_ Path to the folder. E.g. ‘/My Documents/My Folder’ - **limit** _(int, optional, Defaults to `100`)_ Maximum number of items to return. Defaults to 100. Maximum allowed is 2000. - **cursor** _(string, optional)_ A cursor to use for pagination. Defaults to `None`. ## Dropbox.SearchFilesAndFolders [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox\#dropboxsearchfilesandfolders) See Example > Search for files and folders in Dropbox. **Parameters** - **keywords** _(string, required)_ The keywords to search for. E.g. ‘quarterly report’ - **search\_in\_folder\_path** _(string, optional)_ Restricts the search to the specified folder path. E.g. ‘/My Documents/My Folder’. Defaults to `None` (search in the entire Dropbox). - **filter\_by\_category** _(list of enum [DropboxItemCategory](https://docs.arcade.dev/toolkits/productivity/dropbox/reference#dropboxitemcategory), optional)_ Restricts the search to the specified category(ies) of items. Defaults to `None` (returns all items). - **limit** _(int, optional, Defaults to `100`)_ Maximum number of items to return. Defaults to 100. Maximum allowed is 2000. - **cursor** _(string, optional)_ A cursor to use for pagination. Defaults to `None`. ## Dropbox.DownloadFile [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox\#dropboxdownloadfile) See Example > Download a file from Dropbox. **Parameters** - **file\_path** _(string, optional)_ Path to the file. E.g. ‘/My Documents/My Folder/My File.pdf’ - **file\_id** _(string, optional)_ The ID of the file to download. E.g. ‘id:a4ayc\_80\_OEAAAAAAAAAYa’ Note: to call this tool, you must provide either `file_path` or `file_id`. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox\#auth) The Arcade Dropbox toolkit uses the [Dropbox auth provider](https://docs.arcade.dev/home/auth-providers/dropbox) to connect to users’ Dropbox accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Dropbox auth provider](https://docs.arcade.dev/home/auth-providers/dropbox#configuring-dropbox-auth) with your own Dropbox app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_dropbox\\ ```](https://docs.arcade.dev/home/hosting-overview) [Confluence](https://docs.arcade.dev/toolkits/productivity/confluence "Confluence") [Reference](https://docs.arcade.dev/toolkits/productivity/dropbox/reference "Reference") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Local Toolkit Installation [Home](https://docs.arcade.dev/home "Home") Local Deployment [Install](https://docs.arcade.dev/home/local-deployment/install/overview "Install") Toolkits # Install a tool or toolkit ## Running a Local worker [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/toolkits\#running-a-local-worker) To run a local worker without the arcade engine, you can run the following command locally: ```nextra-code arcade serve ``` This will check for any toolkits installed in the current python virtual environment and register them with the worker. You can also pass in the `--host` and `--port` flags to specify the host and port to run the worker on. The default host is `127.0.0.1` and the default port is `8002`. ## PyPI Installation [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/toolkits\#pypi-installation) All Arcade toolkits are available on PyPI. To install a toolkit, run the following in the same python virtual environment as the arcade-ai package: ```nextra-code pip install arcade-[toolkit_name] ``` For example, to install the math toolkit, run: ```nextra-code pip install arcade-math ``` To verify the installation, run: ```nextra-code arcade show --local ``` which should return output similar to: ```nextra-code ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Description ┃ Toolkit ┃ Version ┃ ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━┩ │ Math.Add │ Add two numbers together │ Math │ 0.1.0 │ └──────────────┴──────────────────────────────┴─────────┴─────────┘ ``` These are all tools that are installed in the same python virtual environment as the arcade-ai package. See our [Toolkits Overview page](https://docs.arcade.dev/toolkits) for all available toolkits and individual installation instructions. ## Local Package Installation [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/toolkits\#local-package-installation) Locally built toolkits can also be installed with: ```nextra-code pip install . ``` or ```nextra-code pip install ``` in the same python virtual environment as the arcade-ai package. ## Hosted Toolkits [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/toolkits\#hosted-toolkits) To add a toolkit to a hosted worker such as FastAPI, you can register them in the worker itself. This allows you to explicitly define which tools should be included on a particular worker. ```nextra-code import arcade_math from fastapi import FastAPI from arcade_tdk import Toolkit from arcade_serve.fastapi import FastAPIWorker app = FastAPI() worker_secret = os.environ.get("ARCADE_WORKER_SECRET") worker = FastAPIWorker(app, secret=worker_secret) worker.register_toolkit(Toolkit.from_module(arcade_math)) ``` ## Showing Tools From a Hosted Engine [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/toolkits\#showing-tools-from-a-hosted-engine) To show all tools that are available on an engine, you can run ```nextra-code arcade show -h -p ``` ```nextra-code ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Description ┃ Package ┃ Version ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩ │ Github.CountStargazers │ Count the number of stargazers (stars) for a GitHub repository. │ Github │ 0.0.15 │ │ Github.CreateIssue │ Create an issue in a GitHub repository. │ Github │ 0.0.15 │ │ Github.CreateIssueComment │ Create a comment on an issue in a GitHub repository. │ Github │ 0.0.15 │ │ Github.CreateReplyForReviewComment │ Create a reply to a review comment for a pull request. │ Github │ 0.0.15 │ │ Github.CreateReviewComment │ Create a review comment for a pull request in a GitHub repository. │ Github │ 0.0.15 │ │ Github.GetPullRequest │ Get details of a pull request in a GitHub repository. │ Github │ 0.0.15 │ │ Github.GetRepository │ Get a repository. │ Github │ 0.0.15 │ .... ``` ## Authenticated Tools [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/toolkits\#authenticated-tools) Some Toolkits may need authentication through an API key or OAuth, which can be configured in the Arcade Engine. To see the specific configuration requirements, you can checkout our [Auth Providers](https://docs.arcade.dev/home/auth-providers). [Docker](https://docs.arcade.dev/home/local-deployment/install/docker "Docker") [Overview](https://docs.arcade.dev/home/local-deployment/configure/overview "Overview") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade FAQ [Home](https://docs.arcade.dev/home "Home") FAQ # Frequently Asked Questions ## What if I need a Tool that Arcade doesn’t have? [Permalink for this section](https://docs.arcade.dev/home/faq\#what-if-i-need-a-tool-that-arcade-doesnt-have) Arcade makes it easy to build your own tools! You can fork our existing tools, or build your own from scratch. Learn more about [building your own toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## How do I contribute back a Tool to the Registry? [Permalink for this section](https://docs.arcade.dev/home/faq\#how-do-i-contribute-back-a-tool-to-the-registry) We’re always looking for new tools and toolkits! If you have a tool that you think would be useful to others, please let us know. You can contribute a tool by submitting a pull request to the [Arcade GitHub repository](https://github.com/ArcadeAI/arcade-ai). ## What is the difference between the Arcade CLI and the Arcade Clients? [Permalink for this section](https://docs.arcade.dev/home/faq\#what-is-the-difference-between-the-arcade-cli-and-the-arcade-clients) The [Arcade CLI](https://docs.arcade.dev/home/arcade-cli) is a command line tool that makes it easy to build, test, and deploy your own tools to production. The [Arcade Client libraries](https://docs.arcade.dev/home/arcade-clients) are what you will use within your own agents and applications to call the tools. ## How does Arcade.dev relate to the Model Context Protocol (MCP)? [Permalink for this section](https://docs.arcade.dev/home/faq\#how-does-arcadedev-relate-to-the-model-context-protocol-mcp) The Arcade.dev engine both speaks MCP and extends it with an authentication-first architecture. This means that you can use Arcade.dev to build tools that can be called by any LLM that supports MCP, while also providing a secure and easy way to authenticate users and manage access to those tools. Learn more about [Arcade.dev and MCP](https://docs.arcade.dev/home/mcp-overview). ## Auth FAQ [Permalink for this section](https://docs.arcade.dev/home/faq\#auth-faq) ### What is the difference between adding an included provider and adding a custom provider? [Permalink for this section](https://docs.arcade.dev/home/faq\#what-is-the-difference-between-adding-an-included-provider-and-adding-a-custom-provider) This is an important observation. Technically, both included and custom providers are OAuth providers. However, when you add an included provider, the Arcade Engine requires less information from you to configure the provider, because it can use the values defined by that provider on their official documentation. Also, most importantly, the Engine will automatically route tools so they connect to the added provider. ### Can my users connect multiple accounts of the same provider? [Permalink for this section](https://docs.arcade.dev/home/faq\#can-my-users-connect-multiple-accounts-of-the-same-provider) Today this is possible if you assign multiple Arcade `user_id` s to the same user on your system. You will need to manage the mapping between users in your system and the different Arcade `user_id` s assigned to them. ### Can I authenticate multiple tools at once? [Permalink for this section](https://docs.arcade.dev/home/faq\#can-i-authenticate-multiple-tools-at-once) Yes, as long as they are from the same OAuth provider. You need to collect all the scopes required by the tools you need, and then authenticate with that provider with all these scopes. For example, for [Google\\ Tools](https://docs.arcade.dev/home/auth-providers/google), you can use this code to authenticate once: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable USER_ID = "you@example.com" # get the list of tools tools = client.tools.list(toolkit="Google") # collect the scopes scopes = set() for tool in tools: if tool.requirements.authorization.oauth2.scopes: scopes |= set(tool.requirements.authorization.oauth2.scopes) # start auth auth_response = client.auth.start(user_id=USER_ID, scopes=list(scopes), provider="google") # show the url to the user if needed if auth_response.status != "complete": print(f"Please click here to authorize: {auth_response.url}") # Wait for the authorization to complete client.auth.wait_for_completion(auth_response) ``` ```nextra-code import Arcade from "@arcadeai/arcadejs"; const client = new Arcade(); const user_id = "user@example.com"; // get the list of tools const googleToolkit = await client.tools.list({toolkit: "google"}) // collect scopes const scopes = new Set(googleToolkit.items.flatMap(i => i.requirements?.authorization?.oauth2?.scopes ?? [])); // start authentication let auth_response = await client.auth.start(user_id, "google", { scopes:[...scopes] }); // show the url to the user if needed if (auth_response.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(auth_response.url); // Wait for the authorization to complete auth_response = await client.auth.waitForCompletion(auth_response); } ``` ## Your question is not here? [Permalink for this section](https://docs.arcade.dev/home/faq\#your-question-is-not-here) Please go to the discussions page on GitHub. Someone else may have asked something similar already. If not, please start a new discussion and we’ll get to it as soon as possible. [Get Answers on GitHub](https://github.com/ArcadeAI/arcade-ai/discussions) [Zoom](https://docs.arcade.dev/home/auth-providers/zoom "Zoom") [Changelog](https://docs.arcade.dev/home/changelog "Changelog") ## Arcade and Google ADK [Home](https://docs.arcade.dev/home "Home") Google ADKOverview # Arcade with Google ADK The `google-adk-arcade` package provides a seamless integration between [Arcade](https://arcade.dev/) and the [Google ADK](https://github.com/google/adk-python/). This integration allows you to enhance your AI agents with powerful Arcade tools including Google Mail, LinkedIn, GitHub, and many more. ## Installation [Permalink for this section](https://docs.arcade.dev/home/google-adk/overview\#installation) Install the necessary packages to get started: ```nextra-code pip install google-adk-arcade ``` Make sure you have your Arcade API key ready. [Get an API key](https://docs.arcade.dev/home/api-keys) if you don’t already have one. ## Key features [Permalink for this section](https://docs.arcade.dev/home/google-adk/overview\#key-features) - **Easy integration** with the Google ADK framework - **Access to all Arcade toolkits** including Google, GitHub, LinkedIn, X, and more - **Create custom tools** with the Arcade Tool SDK - **Manage user authentication** for tools that require it - **Asynchronous support** compatible with Google’s ADK framework ## Basic usage [Permalink for this section](https://docs.arcade.dev/home/google-adk/overview\#basic-usage) Here’s a simple example of using Arcade tools with OpenAI Agents: ```nextra-code import asyncio from arcadepy import AsyncArcade from google.adk import Agent, Runner from google.adk.artifacts import InMemoryArtifactService from google.adk.sessions import InMemorySessionService from google.genai import types from google_adk_arcade.tools import get_arcade_tools async def main(): app_name = 'my_app' user_id = 'user@example.com' session_service = InMemorySessionService() artifact_service = InMemoryArtifactService() client = AsyncArcade() google_tools = await get_arcade_tools(client, tools=["Google.ListEmails"]) # authorize the tools for tool in google_tools: result = await client.tools.authorize( tool_name=tool.name, user_id=user_id ) if result.status != "completed": print(f"Click this link to authorize {tool.name}:\n{result.url}") await client.auth.wait_for_completion(result) # create the agent google_agent = Agent( model="gemini-2.0-flash", name="google_tool_agent", instruction="I can use Google tools to manage an inbox!", description="An agent equipped with tools to read Gmail emails." tools=google_tools, ) #create the session and pass the user ID to the state session = await session_service.create_session( app_name=app_name, user_id=user_id, state={ "user_id": user_id, } ) runner = Runner( app_name=app_name, agent=google_agent, artifact_service=artifact_service, session_service=session_service, ) user_input = "summarize my latest 3 emails" content = types.Content( role='user', parts=[types.Part.from_text(text=user_input)] ) for event in runner.run( user_id=user_id, session_id=session.id, new_message=content, ): if event.content.parts and event.content.parts[0].text: print(f'** {event.author}: {event.content.parts[0].text}') if __name__ == '__main__': asyncio.run(main()) ``` ## Handling authorization [Permalink for this section](https://docs.arcade.dev/home/google-adk/overview\#handling-authorization) When a user needs to authorize access to a tool (like Google or GitHub), the agent will reply with a URL for the user to visit, which will be displayed to the user. After visiting the URL and authorizing access, the user can run the agent again with the same `user_id`, and it will work without requiring re-authorization. Alternatively, you can authorize the tool before running the agent: ```nextra-code # authorize the tools for tool in google_tools: result = await client.tools.authorize( tool_name=tool.name, user_id=user_id ) if result.status != "completed": print(f"Click this link to authorize {tool.name}:\n{result.url}") await client.auth.wait_for_completion(result) ``` ## Available toolkits [Permalink for this section](https://docs.arcade.dev/home/google-adk/overview\#available-toolkits) Arcade provides a variety of toolkits you can use with your agents: - **Google Suite**: Gmail, Calendar, Drive, Docs - **Social Media**: LinkedIn, X - **Development**: GitHub - **Web**: Web search, content extraction - **And more**: Weather, financial data, etc. For a full list of available toolkits, visit the [Arcade Integrations](https://docs.arcade.dev/toolkits) documentation. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/google-adk/overview\#next-steps) Ready to start building with Arcade and OpenAI Agents? Check out these guides: - [Using Arcade tools](https://docs.arcade.dev/home/google-adk/use-arcade-tools) \- Learn the basics of using Arcade tools with Google ADK - [Creating custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) \- Build your own tools with the Arcade Tool SDK Enjoy exploring Arcade and building powerful AI-enabled applications! [Custom auth flow](https://docs.arcade.dev/home/crewai/custom-auth-flow "Custom auth flow") [Using Arcade tools](https://docs.arcade.dev/home/google-adk/use-arcade-tools "Using Arcade tools") ## Create Evaluation Suite [Home](https://docs.arcade.dev/home "Home") [Evaluate tools](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools "Evaluate tools") Create an evaluation suite # Evaluate tools In this guide, you’ll learn how to evaluate your custom tools to ensure they function correctly with the AI assistant, including defining evaluation cases and using different critics. We’ll create evaluation cases to test our `hello` tool and measure its performance. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#prerequisites) - [Build a custom tool](https://docs.arcade.dev/home/build-tools/create-a-toolkit) - Install the evaluation dependencies: uvpip ```nextra-code uv pip install 'arcade-ai[evals]' ``` ```nextra-code pip install 'arcade-ai[evals]' ``` ### Create an evaluation suite [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#create-an-evaluation-suite) Navigate to your toolkit’s `evals` directory: ```nextra-code cd arcade_my_new_toolkit/evals ``` Create a new Python file for your evaluations, e.g., `eval_hello.py`. ### Define your evaluation cases [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#define-your-evaluation-cases) Open `eval_hello.py` and add the following code: ```nextra-code from arcade_evals import ( EvalSuite, EvalRubric, ExpectedToolCall, BinaryCritic, tool_eval, ) from arcade_tdk import ToolCatalog from arcade_my_new_toolkit.tools.hello import hello # Create a catalog of tools to include in the evaluation catalog = ToolCatalog() catalog.add_tool(hello) # Define the evaluation rubric rubric = EvalRubric( fail_threshold=0.8, warn_threshold=0.9, ) @tool_eval() def hello_eval_suite() -> EvalSuite: """Create an evaluation suite for the hello tool.""" suite = EvalSuite( name="Hello Tool Evaluation", system_message="You are a helpful assistant.", catalog=catalog, rubric=rubric, ) # Example evaluation case suite.add_case( name="Simple Greeting", user_message="Say hello to Alice", expected_tool_calls=[\ ExpectedToolCall(\ func=hello,\ args={\ "name": "Alice",\ },\ )\ ], critics=[\ BinaryCritic(critic_field="name", weight=1.0),\ ], ) return suite ``` ### Run the evaluation [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#run-the-evaluation) From the `evals` directory, run: ```nextra-code arcade evals . ``` This command executes your evaluation suite and provides a report. ### How it works [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#how-it-works) The evaluation framework in Arcade allows you to define test cases ( `EvalCase`) with expected tool calls and use critics to assess the AI’s performance. By running the evaluation suite, you can measure how well the AI assistant is using your tools. ### Next steps [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#next-steps) Explore different types of critics and evaluation criteria to thoroughly test your tools. [Learn more about Critic classes](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite#critic-classes) ## Critic classes [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#critic-classes) Arcade provides several critic classes to evaluate different aspects of tool usage. ### BinaryCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#binarycritic) Checks if a parameter value matches exactly. ```nextra-code BinaryCritic(critic_field="name", weight=1.0) ``` ### SimilarityCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#similaritycritic) Evaluates the similarity between expected and actual values. ```nextra-code from arcade_evals import SimilarityCritic SimilarityCritic(critic_field="message", weight=1.0) ``` ### NumericCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#numericcritic) Assesses numeric values within a specified tolerance. ```nextra-code from arcade_evals import NumericCritic NumericCritic(critic_field="score", tolerance=0.1, weight=1.0) ``` ### DatetimeCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#datetimecritic) Evaluates the closeness of datetime values within a specified tolerance. ```nextra-code from datetime import timedelta from arcade_evals import DatetimeCritic DatetimeCritic(critic_field="start_time", tolerance=timedelta(seconds=10), weight=1.0) ``` ## Advanced evaluation cases [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#advanced-evaluation-cases) You can add more evaluation cases to test different scenarios. ### Example: Greeting with emotion [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite\#example-greeting-with-emotion) Modify your `hello` tool to accept an `emotion` parameter: ```nextra-code from arcade_tdk import tool from typing import Annotated class Emotion(str, Enum): HAPPY = "happy" SLIGHTLY_HAPPY = "slightly happy" SAD = "sad" SLIGHTLY_SAD = "slightly sad" @tool def hello( name: Annotated[str, "The name of the person to greet"] = "there", emotion: Annotated[Emotion, "The emotion to convey"] = Emotion.HAPPY ) -> Annotated[str, "A greeting to the user"]: """ Say hello to the user with a specific emotion. """ return f"Hello {name}! I'm feeling {emotion.value} today." ``` Add an evaluation case for this new parameter: ```nextra-code suite.add_case( name="Greeting with Emotion", user_message="Say hello to Bob sadly", expected_tool_calls=[\ ExpectedToolCall(\ func=hello,\ args={\ "name": "Bob",\ "emotion": Emotion.SAD,\ },\ )\ ], critics=[\ BinaryCritic(critic_field="name", weight=0.5),\ SimilarityCritic(critic_field="emotion", weight=0.5),\ ], ) ``` Add an evaluation case with additional conversation context: ```nextra-code suite.add_case( name="Greeting with Emotion", user_message="Say hello to Bob based on my current mood.", expected_tool_calls=[\ ExpectedToolCall(\ func=hello,\ args={\ "name": "Bob",\ "emotion": Emotion.HAPPY,\ },\ )\ ], critics=[\ BinaryCritic(critic_field="name", weight=0.5),\ SimilarityCritic(critic_field="emotion", weight=0.5),\ ], # Add some context to the evaluation case additional_messages= [\ {"role": "user", "content": "Hi, I'm so happy!"},\ {\ "role": "assistant",\ "content": "That’s awesome! What’s got you feeling so happy today?",\ },\ ] ) ``` Add an evalutation case with multiple expected tool calls: ```nextra-code suite.add_case( name="Greeting with Emotion", user_message="Say hello to Bob based on my current mood. And then say hello to Alice with slightly less of that emotion.", expected_tool_calls=[\ ExpectedToolCall(\ func=hello,\ args={\ "name": "Bob",\ "emotion": Emotion.HAPPY,\ },\ ),\ ExpectedToolCall(\ func=hello,\ args={\ "name": "Alice",\ "emotion": Emotion.SLIGHTLY_HAPPY,\ },\ )\ ], critics=[\ BinaryCritic(critic_field="name", weight=0.5),\ SimilarityCritic(critic_field="emotion", weight=0.5),\ ], # Add some context to the evaluation case additional_messages= [\ {"role": "user", "content": "Hi, I'm so happy!"},\ {\ "role": "assistant",\ "content": "That’s awesome! What’s got you feeling so happy today?",\ },\ ] ) ``` * * * Ensure that your `hello` tool and evaluation cases are updated accordingly and that you rerun `arcade evals .` to test your changes. [Why evaluate tools?](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools "Why evaluate tools?") [Run evaluations](https://docs.arcade.dev/home/evaluate-tools/run-evaluations "Run evaluations") ## Spotify Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Spotify # Spotify auth provider At this time, Arcade does not offer a default Spotify Auth Provider. To use Spotify auth, you must create a custom Auth Provider with your own Spotify OAuth 2.0 credentials as described below. The Spotify auth provider enables tools and agents to call the Spotify API on behalf of a user. Behind the scenes, the Arcade Engine and the Spotify auth provider seamlessly manage Spotify OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#whats-documented-here) This page describes how to use and configure Spotify auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/spotify#using-spotify-auth-in-app-code) that needs to call Spotify APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/spotify#using-spotify-auth-in-custom-tools) that need to call Spotify APIs ## Configuring Spotify auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#configuring-spotify-auth) In a production environment, you will most likely want to use your own Spotify app credentials. This way, your users will see your application’s name requesting permission. You can use your own Spotify credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Spotify app credentials, let’s go through the steps to create a Spotify app. ### Create a Spotify app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#create-a-spotify-app) - Follow Spotify’s guide to [registering an app](https://developer.spotify.com/documentation/web-api/tutorials/getting-started) - Choose the “Web API” product (at a minimum) - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the client ID and client secret to use below Next, add the Spotify app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Spotify Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#configuring-your-own-spotify-auth-provider-in-arcade) There are two ways to configure your Spotify app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Spotify Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Spotify**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-spotify-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Spotify app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Spotify auth using your Arcade account credentials, the Arcade Engine will automatically use this Spotify OAuth provider. If you have multiple Spotify providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Spotify auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#set-environment-variables) Set the following environment variables: ```nextra-code export SPOTIFY_CLIENT_ID="" export SPOTIFY_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code SPOTIFY_CLIENT_ID="" SPOTIFY_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `spotify` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-spotify description: "The default Spotify provider" enabled: true type: oauth2 provider_id: spotify client_id: ${env:SPOTIFY_CLIENT_ID} client_secret: ${env:SPOTIFY_CLIENT_SECRET} ``` ## Using Spotify auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#using-spotify-auth-in-app-code) Use the Spotify auth provider in your own agents and AI apps to get a user token for the Spotify API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Spotify API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="spotify", scopes=["user-read-playback-state"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "spotify", [\ "user-read-playback-state",\ ]); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Spotify auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/spotify\#using-spotify-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Spotify API. Use the `Spotify()` auth class to specify that a tool requires authorization with Spotify. The `context.authorization.token` field will be automatically populated with the user’s Spotify token: ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Spotify @tool( requires_auth=Spotify( scopes=["user-read-playback-state"], ) ) async def get_playback_state( context: ToolContext, ) -> Annotated[dict, "Information about the user's current playback state"]: """Get information about the user's current playback state, including track or episode, progress, and active device.""" endpoint = "/me/player" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.get( f"https://api.spotify.com/v1/{endpoint}", headers=headers, ) response.raise_for_status() if response.status_code == 204: return {"status": "Playback not available or active"} return response.json() ``` [Slack](https://docs.arcade.dev/home/auth-providers/slack "Slack") [Twitch](https://docs.arcade.dev/home/auth-providers/twitch "Twitch") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## GitHub Toolkit Integration [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Developer Tools](https://docs.arcade.dev/toolkits/development/code-sandbox "Developer Tools") GitHubGitHub # GitHub **Description:** Enable agents to interact with GitHub repositories, issues, and pull requests. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/github) **Auth:** User authorizationvia the [GitHub auth provider](https://docs.arcade.dev/home/auth-providers/github) [![PyPI Version](https://img.shields.io/pypi/v/arcade_github)](https://pypi.org/project/arcade_github/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_github)](https://pypi.org/project/arcade_github/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_github)](https://pypi.org/project/arcade_github/)[![Downloads](https://img.shields.io/pypi/dm/arcade_github)](https://pypi.org/project/arcade_github/) The Arcade GitHub toolkit provides a pre-built set of tools for interacting with GitHub. These tools make it easy to build agents and AI apps that can: - Access private repositories (with the user’s permission) - Get info about repositories, issues, pull requests, and more - Post issues, comments, and replies as the user ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#available-tools) These tools are currently available in the Arcade GitHub toolkit. | Tool Name | Description | | --- | --- | | Github.SetStarred | Star or unstar a GitHub repository. | | Github.ListStargazers | List the stargazers of a GitHub repository. | | Github.CreateIssue | Create an issue in a GitHub repository. | | Github.CreateIssueComment | Create a comment on an issue in a GitHub repository. | | Github.ListPullRequests | List pull requests in a GitHub repository. | | Github.GetPullRequest | Get details of a pull request in a GitHub repository. | | Github.UpdatePullRequest | Update a pull request in a GitHub repository. | | Github.ListPullRequestCommits | List commits on a pull request in a GitHub repository. | | Github.CreateReplyForReviewComment | Create a reply to a review comment on a pull request. | | Github.ListReviewCommentsOnPullRequest | List review comments on a pull request. | | Github.CreateReviewComment | Create a review comment on a pull request. | | Github.CountStargazers | Count the number of stargazers for a GitHub repository. | | Github.ListOrgRepositories | List repositories of a GitHub organization. | | Github.GetRepository | Get details of a GitHub repository. | | Github.ListRepositoryActivities | List activities of a GitHub repository. | | Github.ListReviewCommentsInARepository | List review comments in a repository. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [GitHub auth\\ provider](https://docs.arcade.dev/home/auth-providers/github#using-github-auth-in-customtools). ## Github.SetStarred [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubsetstarred) See Example > Star or unstar a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The owner of the repository. - **`name`** _(string, required)_ The name of the repository. - **`starred`** _(boolean, required)_ Whether to star ( `true`) or unstar ( `false`) the repository. * * * ## Github.ListStargazers [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubliststargazers) See Example > List the stargazers of a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The owner of the repository. - **`repo`** _(string, required)_ The name of the repository. - **`limit`** _(int, optional, Defaults to `None`)_ The maximum number of stargazers to return. If not provided, all stargazers will be returned. * * * ## Github.CreateIssue [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubcreateissue) See Example > Create an issue in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`title`** _(string, required)_ The title of the issue. - **`body`** _(string, optional)_ The contents of the issue. - **`assignees`** _(array of strings, optional)_ Logins for Users to assign to this issue. - **`milestone`** _(integer, optional)_ The number of the milestone to associate this issue with. - **`labels`** _(array of strings, optional)_ Labels to associate with this issue. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the issue. This is a large payload and may impact performance - use with caution. * * * ## Github.CreateIssueComment [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubcreateissuecomment) See Example > Create a comment on an issue in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`issue_number`** _(integer, required)_ The number that identifies the issue. - **`body`** _(string, required)_ The contents of the comment. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the comment. This is a large payload and may impact performance - use with caution. * * * ## Github.ListPullRequests [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githublistpullrequests) See Example > List pull requests in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`state`** _(enum ( [PRState](https://docs.arcade.dev/toolkits/development/github/reference#prstate)), optional, Defaults to `PRState.OPEN`)_ The state of the pull requests to return. - **`head`** _(string, optional)_ Filter pulls by head user or head organization and branch name in the format of user:ref-name or organization:ref-name. - **`base`** _(string, optional, Defaults to `'main'`)_ Filter pulls by base branch name. - **`sort`** _(enum ( [PRSortProperty](https://docs.arcade.dev/toolkits/development/github/reference#prsortproperty)), optional, Defaults to `PRSortProperty.CREATED`)_ The property to sort the results by. - **`direction`** _(enum ( [SortDirection](https://docs.arcade.dev/toolkits/development/github/reference#sortdirection)), optional)_ The direction of the sort. - **`per_page`** _(integer, optional, Defaults to `30`)_ The number of results per page (max 100). - **`page`** _(integer, optional, Defaults to `1`)_ The page number of the results to fetch. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the pull requests. This is a large payload and may impact performance - use with caution. * * * ## Github.GetPullRequest [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubgetpullrequest) See Example > Get details of a pull request in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`pull_number`** _(integer, required)_ The number that identifies the pull request. - **`include_diff_content`** _(boolean, optional, Defaults to `false`)_ If true, return the diff content of the pull request. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the pull requests. This is a large payload and may impact performance - use with caution. * * * ## Github.UpdatePullRequest [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubupdatepullrequest) See Example > Update a pull request in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`pull_number`** _(integer, required)_ The number that identifies the pull request. - **`title`** _(string, optional)_ The title of the pull request. - **`body`** _(string, optional)_ The contents of the pull request. - **`state`** _(enum ( [PRState](https://docs.arcade.dev/toolkits/development/github/reference#prstate)), optional)_ State of this Pull Request. Either open or closed. - **`base`** _(string, optional)_ The name of the branch you want your changes pulled into. - **`maintainer_can_modify`** _(boolean, optional)_ Indicates whether maintainers can modify the pull request. * * * ## Github.ListPullRequestCommits [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githublistpullrequestcommits) See Example > List commits (from oldest to newest) on a pull request in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`pull_number`** _(integer, required)_ The number that identifies the pull request. - **`per_page`** _(integer, optional, Defaults to `30`)_ The number of results per page (max 100). - **`page`** _(integer, optional, Defaults to `1`)_ The page number of the results to fetch. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the pull requests. This is a large payload and may impact performance - use with caution. * * * ## Github.CreateReplyForReviewComment [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubcreatereplyforreviewcomment) See Example > Create a reply to a review comment for a pull request in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`pull_number`** _(integer, required)_ The number that identifies the pull request. - **`comment_id`** _(integer, required)_ The unique identifier of the comment to reply to. - **`body`** _(string, required)_ The text of the reply comment. * * * ## Github.ListReviewCommentsOnPullRequest [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githublistreviewcommentsonpullrequest) See Example > List review comments on a pull request in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`pull_number`** _(integer, required)_ The number that identifies the pull request. - **`sort`** _(enum ( [ReviewCommentSortProperty](https://docs.arcade.dev/toolkits/development/github/reference#reviewcommentsortproperty)), optional, Defaults to `'created'`)_ The property to sort the results by. Can be one of: `created`, `updated`. - **`direction`** _(enum ( [SortDirection](https://docs.arcade.dev/toolkits/development/github/reference#sortdirection)), optional, Defaults to `'desc'`)_ The direction to sort results. Can be one of: `asc`, `desc`. - **`since`** _(string, optional)_ Only show results that were last updated after the given time. This is a timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. - **`per_page`** _(integer, optional, Defaults to `30`)_ The number of results per page (max 100). - **`page`** _(integer, optional, Defaults to `1`)_ The page number of the results to fetch. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the pull requests. This is a large payload and may impact performance - use with caution. * * * ## Github.CreateReviewComment [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubcreatereviewcomment) See Example > Create a review comment for a pull request in a GitHub repository. If the subject\_type is not ‘file’, then the start\_line and end\_line parameters are required. If the subject\_type is ‘file’, then the start\_line and end\_line parameters are ignored. If the commit\_id is not provided, the latest commit SHA of the PR’s base branch will be used. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`pull_number`** _(integer, required)_ The number that identifies the pull request. - **`body`** _(string, required)_ The text of the review comment. - **`path`** _(string, required)_ The relative path to the file that necessitates a comment. - **`commit_id`** _(string, optional)_ The SHA of the commit needing a comment. If not provided, the latest commit SHA of the PR’s base branch will be used. - **`start_line`** _(integer, optional)_ The start line of the range of lines in the pull request diff that the comment applies to. Required unless ‘subject\_type’ is ‘file’. - **`end_line`** _(integer, optional)_ The end line of the range of lines in the pull request diff that the comment applies to. Required unless ‘subject\_type’ is ‘file’. - **`side`** _(enum ( [DiffSide](https://docs.arcade.dev/toolkits/development/github/reference#diffside)), optional, Defaults to `'RIGHT'`)_ The side of the diff that the pull request’s changes appear on. Use LEFT for deletions that appear in red. Use RIGHT for additions that appear in green or unchanged lines that appear in white and are shown for context. - **`start_side`** _(string, optional)_ The starting side of the diff that the comment applies to. - **`subject_type`** _(enum ( [ReviewCommentSubjectType](https://docs.arcade.dev/toolkits/development/github/reference#reviewcommentsubjecttype)), optional, Defaults to `'FILE'`)_ The type of subject that the comment applies to. Can be one of: file, hunk, or line. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the review comment. This is a large payload and may impact performance - use with caution. * * * ## Github.CountStargazers [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubcountstargazers) See Example > Count the number of stargazers (stars) for a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The owner of the repository. - **`name`** _(string, required)_ The name of the repository. * * * ## Github.ListOrgRepositories [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githublistorgrepositories) See Example > List repositories for the specified GitHub organization. **Parameters** - **`org`** _(string, required)_ The organization name. The name is not case sensitive. - **`repo_type`** _(enum ( [RepoType](https://docs.arcade.dev/toolkits/development/github/reference#repotype)), optional, Defaults to `'ALL'`)_ The types of repositories to return. - **`sort`** _(enum ( [RepoSortProperty](https://docs.arcade.dev/toolkits/development/github/reference#reposortproperty)), optional, Defaults to `'CREATED'`)_ The property to sort the results by. - **`sort_direction`** _(enum ( [SortDirection](https://docs.arcade.dev/toolkits/development/github/reference#sortdirection)), optional, Defaults to `'ASC'`)_ The order to sort by. - **`per_page`** _(integer, optional, Defaults to `30`)_ The number of results per page. - **`page`** _(integer, optional, Defaults to `1`)_ The page number of the results to fetch. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the repositories. This is a large payload and may impact performance - use with caution. * * * ## Github.GetRepository [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githubgetrepository) See Example > Get detailed information about a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the repository. This is a large payload and may impact performance - use with caution. * * * ## Github.ListRepositoryActivities [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githublistrepositoryactivities) See Example > List repository activities such as pushes, merges, force pushes, and branch changes. Retrieves a detailed history of changes to a repository, such as pushes, merges, force pushes, and branch changes,and associates these changes with commits and users. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`direction`** _(enum ( [SortDirection](https://docs.arcade.dev/toolkits/development/github/reference#sortdirection)), optional, Defaults to `'DESC'`)_ The direction to sort the results by. - **`per_page`** _(integer, optional, Defaults to `30`)_ The number of results per page (max 100). - **`before`** _(string, optional)_ A cursor (unique identifier, e.g., a SHA of a commit) to search for results before this cursor. - **`after`** _(string, optional)_ A cursor (unique identifier, e.g., a SHA of a commit) to search for results after this cursor. - **`ref`** _(string, optional)_ The Git reference for the activities you want to list. Can be formatted as `refs/heads/BRANCH_NAME` or just `BRANCH_NAME`. - **`actor`** _(string, optional)_ The GitHub username to filter by the actor who performed the activity. - **`time_period`** _(enum ( [RepoTimePeriod](https://docs.arcade.dev/toolkits/development/github/reference#repotimeperiod)), optional)_ The time period to filter by. - **`activity_type`** _(enum ( [ActivityType](https://docs.arcade.dev/toolkits/development/github/reference#activitytype)), optional)_ The activity type to filter by. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the activities. This is a large payload and may impact performance - use with caution. * * * ## Github.ListReviewCommentsInARepository [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#githublistreviewcommentsinarepository) See Example > List review comments in a GitHub repository. **Parameters** - **`owner`** _(string, required)_ The account owner of the repository. The name is not case sensitive. - **`repo`** _(string, required)_ The name of the repository without the .git extension. The name is not case sensitive. - **`sort`** _(enum ( [ReviewCommentSortProperty](https://docs.arcade.dev/toolkits/development/github/reference#reviewcommentsortproperty)), optional, Defaults to `'created'`)_ The property to sort the results by. Can be one of: created, updated. - **`direction`** _(enum ( [SortDirection](https://docs.arcade.dev/toolkits/development/github/reference#sortdirection)), optional, Defaults to `'DESC'`)_ The direction to sort results. Ignored without sort parameter. Can be one of: asc, desc. - **`since`** _(string, optional)_ Only show results that were last updated after the given time. This is a timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. - **`per_page`** _(integer, optional, Defaults to `30`)_ The number of results per page (max 100). - **`page`** _(integer, optional, Defaults to `1`)_ The page number of the results to fetch. - **`include_extra_data`** _(boolean, optional, Defaults to `false`)_ If true, return all the data available about the pull requests. This is a large payload and may impact performance - use with caution. * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/github\#auth) The Arcade GitHub toolkit uses the [GitHub auth provider](https://docs.arcade.dev/home/auth-providers/github) to connect to users’ GitHub accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the GitHub auth provider](https://docs.arcade.dev/home/auth-providers/github#configuring-github-auth) with your own GitHub app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_github\\ ```](https://docs.arcade.dev/home/hosting-overview) [Code Sandbox](https://docs.arcade.dev/toolkits/development/code-sandbox "Code Sandbox") [Reference](https://docs.arcade.dev/toolkits/development/github/reference "Reference") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Flights Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google Flights # Google Flights **Description:** Empower your agents to search for flights using Arcade. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google Flights toolkit lets you search for flights with ease. Use these tools to build intelligent agents and applications that: - Search for round-trip flights. - Search for one-way flights. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_flights\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchRoundtripFlights | Retrieve roundtrip flight search results using Google Flights. | | Search.SearchOneWayFlights | Retrieve one-way flight search results using Google Flights. | ## Search.SearchRoundtripFlights [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_flights\#searchsearchroundtripflights) Retrieve flight search results using Google Flights. **Parameters** - **`departure_airport_code`** _(string, required)_: The departure airport code. An uppercase 3-letter code. - **`arrival_airport_code`** _(string, required)_: The arrival airport code. An uppercase 3-letter code. - **`outbound_date`** _(string, required)_: Flight outbound date in YYYY-MM-DD format. - **`return_date`** _(string, optional)_: Flight return date in YYYY-MM-DD format. - **`currency_code`** _(string, optional)_: Currency of the returned prices. Defaults to ‘USD’. - **`travel_class`** _(enum ( [GoogleFlightsTravelClass](https://docs.arcade.dev/toolkits/search/reference#googleflightstravelclass)), optional)_: Travel class of the flight. Defaults to ‘ECONOMY’. - **`num_adults`** _(int, optional)_: Number of adult passengers. Defaults to 1. - **`num_children`** _(int, optional)_: Number of child passengers. Defaults to 0. - **`max_stops`** _(enum ( [GoogleFlightsMaxStops](https://docs.arcade.dev/toolkits/search/reference#googleflightsmaxstops)), optional)_: Maximum number of stops (layovers) for the flight. Defaults to any number of stops. - **`sort_by`** _(enum ( [GoogleFlightsSortBy](https://docs.arcade.dev/toolkits/search/reference#googleflightssortby)), optional)_: The sorting order of the results. Defaults to TOP\_FLIGHTS. See Example > ## Search.SearchOneWayFlights [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_flights\#searchsearchonewayflights) Retrieve flight search results for a one-way flight using Google Flights. **Parameters** - **`departure_airport_code`** _(string, required)_: The departure airport code. An uppercase 3-letter code. - **`arrival_airport_code`** _(string, required)_: The arrival airport code. An uppercase 3-letter code. - **`outbound_date`** _(string, required)_: Flight departure date in YYYY-MM-DD format. - **`currency_code`** _(string, optional)_: Currency of the returned prices. Defaults to ‘USD’. - **`travel_class`** _(enum ( [GoogleFlightsTravelClass](https://docs.arcade.dev/toolkits/search/reference#googleflightstravelclass)), optional)_: Travel class of the flight. Defaults to ‘ECONOMY’. - **`num_adults`** _(int, optional)_: Number of adult passengers. Defaults to 1. - **`num_children`** _(int, optional)_: Number of child passengers. Defaults to 0. - **`max_stops`** _(enum ( [GoogleFlightsMaxStops](https://docs.arcade.dev/toolkits/search/reference#googleflightsmaxstops)), optional)_: Maximum number of stops (layovers) for the flight. Defaults to any number of stops. - **`sort_by`** _(enum ( [GoogleFlightsSortBy](https://docs.arcade.dev/toolkits/search/reference#googleflightssortby)), optional)_: The sorting order of the results. Defaults to TOP\_FLIGHTS. See Example > ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_flights\#auth) The Arcade Google Flights toolkit uses the [SerpAPI](https://serpapi.com/) to search for flights from Google Flights. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google Finance](https://docs.arcade.dev/toolkits/search/google_finance "Google Finance") [Google Hotels](https://docs.arcade.dev/toolkits/search/google_hotels "Google Hotels") ## Google Sheets Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Google](https://docs.arcade.dev/toolkits/productivity/google/calendar "Google") Sheets # Google Sheets **Description:** Enable agents to create, read, and update spreadsheets in Google Sheets. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/google) **Auth:** User authorizationvia the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) [![PyPI Version](https://img.shields.io/pypi/v/arcade_google)](https://pypi.org/project/arcade_google/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_google)](https://pypi.org/project/arcade_google/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_google)](https://pypi.org/project/arcade_google/)[![Downloads](https://img.shields.io/pypi/dm/arcade_google)](https://pypi.org/project/arcade_google/) The Arcade Google Sheets toolkit provides pre-built tools for working with spreadsheets using the Google Sheets API. Use these tools to: - Create new spreadsheets - Retrieve spreadsheet data - Update cell values ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/sheets\#available-tools) These tools are currently available in the Arcade Sheets toolkit. | Tool Name | Description | | --- | --- | | Google.CreateSpreadsheet | Create a new spreadsheet with a title and optional data. | | Google.GetSpreadsheet | Retrieve spreadsheet properties and cell data for all sheets. | | Google.WriteToCell | Write a value to a specific cell in a spreadsheet. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Google.CreateSpreadsheet [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/sheets\#googlecreatespreadsheet) Create a new spreadsheet with a custom title and optional data in the first sheet. **Parameters** - **`title`** _(string, required, default “Untitled spreadsheet”)_: The title of the new spreadsheet. - **`data`** _(string, optional)_: A JSON string representing a dictionary that maps row numbers to dictionaries. Each sub-dictionary maps column letters to cell values. For example, `data[23]["C"]` is the value for row 23, column C. See Example > ## Google.GetSpreadsheet [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/sheets\#googlegetspreadsheet) Retrieve all properties and cell data for every sheet in a spreadsheet. **Parameters** - **`spreadsheet_id`** _(string, required)_: The ID of the spreadsheet to retrieve. See Example > ## Google.WriteToCell [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/sheets\#googlewritetocell) Write a value to a specific cell in a spreadsheet. **Parameters** - **`spreadsheet_id`** _(string, required)_: The ID of the spreadsheet. - **`column`** _(string, required)_: The column to write to (for example, “A”, “F”, or “AZ”). - **`row`** _(int, required)_: The row number to write to. - **`value`** _(string, required)_: The value to set in the specified cell. - **`sheet_name`** _(string, optional, default “Sheet1”)_: The name of the sheet to update. See Example > * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/sheets\#auth) The Arcade Sheets toolkit uses the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) to connect to users’ Google accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Google auth provider](https://docs.arcade.dev/home/auth-providers/google#configuring-google-auth) with your own Google app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_google\\ ```](https://docs.arcade.dev/home/hosting-overview) [Gmail](https://docs.arcade.dev/toolkits/productivity/google/gmail "Gmail") [Reference](https://docs.arcade.dev/toolkits/productivity/google/reference "Reference") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Deploy Arcade Worker [Home](https://docs.arcade.dev/home "Home") [Serve tools](https://docs.arcade.dev/home/serve-tools/arcade-deploy "Serve tools") Modal # Deploy a custom worker on Modal This guide shows you how to deploy a custom Arcade Worker using Modal. It takes you through setting up the environment, deploying the worker, and connecting it to the Arcade Engine. ### Requirements [Permalink for this section](https://docs.arcade.dev/home/serve-tools/modal-worker\#requirements) - Python 3.10+ - Modal CLI ( `pip install modal`) ### Deploy [Permalink for this section](https://docs.arcade.dev/home/serve-tools/modal-worker\#deploy) Navigate to the directory containing your worker script and deploy it using Modal: ```nextra-code cd examples/serving-tools modal deploy run-arcade-worker.py ``` ### Changing the Toolkits [Permalink for this section](https://docs.arcade.dev/home/serve-tools/modal-worker\#changing-the-toolkits) To change the toolkits, edit the `toolkits` list in the `run-arcade-worker.py` file. ### Example `run-arcade-worker.py` [Permalink for this section](https://docs.arcade.dev/home/serve-tools/modal-worker\#example-run-arcade-workerpy) ```nextra-code import os from modal import App, Image, asgi_app # Define the FastAPI app app = App("arcade-worker") toolkits = ["arcade-google", "arcade-slack"] image = ( Image.debian_slim() .pip_install("arcade_tdk") .pip_install("arcade_serve") .pip_install(toolkits) ) @app.function(image=image) @asgi_app() def fastapi_app(): from fastapi import FastAPI from arcade_tdk import Toolkit from arcade_serve.fastapi import FastAPIWorker web_app = FastAPI() # Initialize app and Arcade FastAPIWorker worker_secret = os.environ.get("ARCADE_WORKER_SECRET", "dev") worker = FastAPIWorker(web_app, secret=worker_secret) # Register toolkits we've installed installed_toolkits = Toolkit.find_all_arcade_toolkits() for toolkit in toolkits: if toolkit in installed_toolkits: worker.register_toolkit(toolkit) return web_app ``` ### Connect to Arcade Engine [Permalink for this section](https://docs.arcade.dev/home/serve-tools/modal-worker\#connect-to-arcade-engine) To connect the Arcade Engine to your worker, configure the worker URL in the engine’s configuration file. Start the engine with the appropriate configuration. For more details, refer to the [Arcade Engine configuration documentation](https://docs.arcade.dev/home/local-deployment/configure/engine). * * * ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/serve-tools/modal-worker\#next-steps) - Ensure your environment variables (like `ARCADE_WORKER_SECRET`) are set securely for production use. - Explore deploying your worker in different environments supported by Modal. [Docker](https://docs.arcade.dev/home/serve-tools/docker-worker "Docker") [Using Arcade tools](https://docs.arcade.dev/home/langchain/use-arcade-tools "Using Arcade tools") ## Create Tool with Secrets [Home](https://docs.arcade.dev/home "Home") [Build tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Build tools") Create a tool with secrets # Create a tool with secrets In this guide, you’ll learn how to use secrets in your custom Arcade tools. Secrets are sensitive strings like passwords, api-keys, or other tokens that grant access to a protected resource or API. Although you could use secrets to transfer any static information to your tool, such as a parameter needed to call a remote API. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets\#prerequisites) - [Set up Arcade](https://docs.arcade.dev/home/quickstart) - [Create a toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit) - [Understand Tool Context](https://docs.arcade.dev/home/build-tools/tool-context) ### Set the secret in the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets\#set-the-secret-in-the-arcade-dashboard) Go to the [Auth > Secrets section](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ![An image showing how the Arcade UI allows users to manage secrets](https://docs.arcade.dev/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsecrets-dashboard-2.eb90edeb.png&w=3840&q=75&dpl=dpl_7X7SFSaKe9V7iRHd3Et4a6gD5tMs) In the top-right corner, click the **\+ Add Secret** button and enter: - **ID**: `MY_SECRET_INFO` - **Secret Value**: `my-secret-value` - **Description**: optionally add a description Click **Submit** to save the secret. ### Define your tool and access the secret [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets\#define-your-tool-and-access-the-secret) Use the `@tool` decorator to define the secret requirement. The `context` object has a `get_secret` method that you can use to access the secret value. ```nextra-code from arcade_tdk import ToolContext, tool @tool(requires_secrets=["MY_SECRET_INFO"]) def my_tool_using_secret(context: ToolContext) -> str: secret_value = context.get_secret("MY_SECRET_INFO") return f"The secret value is {secret_value}" ``` When your tool is executed, it will return: `"The secret value is my-secret-value"`. In a real world application, you would use this secret to connect to a remote database, API, etc. [Create a tool with auth](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth "Create a tool with auth") [Handle tool errors](https://docs.arcade.dev/home/build-tools/handle-tool-errors "Handle tool errors") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Atlassian Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Atlassian # Atlassian auth provider At this time, Arcade does not offer a default Atlassian Auth Provider. To use Atlassian auth, you must create a custom Auth Provider with your own Atlassian OAuth 2.0 credentials as described below. The Atlassian auth provider enables tools and agents to call the Atlassian API on behalf of a user. Behind the scenes, the Arcade Engine and the Atlassian auth provider seamlessly manage Atlassian OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#whats-documented-here) This page describes how to use and configure Atlassian auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/atlassian#using-atlassian-auth-in-app-code) that needs to call Atlassian APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/atlassian#using-atlassian-auth-in-custom-tools) that need to call Atlassian APIs ## Configuring Atlassian auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#configuring-atlassian-auth) In a production environment, you will most likely want to use your own Atlassian app credentials. This way, your users will see your application’s name requesting permission. You can use your own Atlassian credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Atlassian app credentials, let’s go through the steps to create an Atlassian app. ### Create an Atlassian app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#create-an-atlassian-app) - Create a Atlassian app in the [Atlassian developer console](https://developer.atlassian.com/console/myapps/) - In the Authorization tab, click the “Add” action button and set the Callback URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - In the Permissions tab, enable any permissions you need for your app - In the Settings tab, copy the Client ID and Secret to use below ## Configuring your own Atlassian Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#configuring-your-own-atlassian-auth-provider-in-arcade) There are two ways to configure your Atlassian app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Atlassian Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Atlassian**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-atlassian-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Atlassian app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Atlassian auth using your Arcade account credentials, the Arcade Engine will automatically use this Atlassian OAuth provider. If you have multiple Atlassian providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Atlassian auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#set-environment-variables) Set the following environment variables: ```nextra-code export ATLASSIAN_CLIENT_ID="" export ATLASSIAN_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code ATLASSIAN_CLIENT_SECRET="" ATLASSIAN_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `atlassian` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-atlassian description: "The default Atlassian provider" enabled: true type: oauth2 provider_id: atlassian client_id: ${env:ATLASSIAN_CLIENT_ID} client_secret: ${env:ATLASSIAN_CLIENT_SECRET} ``` ## Using Atlassian auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#using-atlassian-auth-in-app-code) Use the Atlassian auth provider in your own agents and AI apps to get a user token for the Atlassian API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Atlassian API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="atlassian", scopes=["read:me", "read:jira-user", "read:confluence-user"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "atlassian", { scopes: ["read:me", "read:jira-user", "read:confluence-user"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Atlassian auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/atlassian\#using-atlassian-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Atlassian API. Use the `Atlassian()` auth class to specify that a tool requires authorization with Atlassian. The `context.authorization.token` field will be automatically populated with the user’s Atlassian token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Atlassian @tool( requires_auth=Atlassian( scopes=["read:jira-work"], ) ) async def list_projects( context: ToolContext, query: Annotated[\ Optional[str],\ "The query to filter the projects by. Defaults to empty string to list all projects.",\ ] = "", ) -> Annotated[dict, "The list of projects in a user's Jira instance"]: """List a Jira user's projects.""" url = f"https://api.atlassian.com/ex/jira//rest/api/3/project/search?query={query}" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json() ``` [Asana](https://docs.arcade.dev/home/auth-providers/asana "Asana") [Discord](https://docs.arcade.dev/home/auth-providers/discord "Discord") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Engine Configuration [Home](https://docs.arcade.dev/home "Home") [Local Deployment](https://docs.arcade.dev/home/local-deployment/install "Local Deployment") [Configure](https://docs.arcade.dev/home/local-deployment/configure/overview "Configure") Engine # Arcade Engine configuration Arcade Engine’s configuration is a [YAML file](https://yaml.org/) with the following sections: | Section | Description | | --- | --- | | API Configuration | Configures the server for specific protocols | | Auth Configuration | Configures user authorization providers and token storage | | Cache Configuration | Configures the short-lived cache | | Security Configuration | Configures security and encryption | | Storage Configuration | Configures persistent storage | | Telemetry Configuration | Configures telemetry and observability (OTEL) | | Tools Configuration | Configures tools for AI models to use | ## Specify a config file [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#specify-a-config-file) To start the Arcade Engine, pass a config file with `-c` or `--config`: ```nextra-code arcade-engine -c /path/to/config.yaml ``` Ensure you have a worker running before starting the engine. See [arcade serve CLI command](https://docs.arcade.dev/home/arcade-cli#arcade-serve) for how to start a worker via the CLI. ## Dotenv files [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#dotenv-files) Arcade Engine automatically loads environment variables from `.env` files in the directory where it was called. Use the `-e` or `--env` flag to specify a path: ```nextra-code arcade-engine -e .env.dev -c config.yaml ``` ## Secrets [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#secrets) Arcade Engine supports two ways of passing sensitive information like API keys without storing them directly in the config file. Environment variables: ```nextra-code topic: area: - id: primary vendor: api_key: ${env:OPENAI_API_KEY} ``` External files (useful in cloud setups): ```nextra-code topic: area: - id: primary vendor: api_key: ${file:/path/to/secret} ``` ## API configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#api-configuration) HTTP is the supported protocol for Arcade Engine’s API. The following configuration options are available: - `api.development` _(optional, default: `false`)_ \- Enable development mode, with more logging and simple [worker authentication](https://docs.arcade.dev/home/local-deployment/configure/engine#http-worker-configuration) - `api.http.host` _(default: `localhost`)_ \- Address to which Arcade Engine binds its server (e.g., `localhost` or `0.0.0.0`) - `api.http.read_timeout` _(optional, default: `30s`)_ \- Timeout for reading data from clients - `api.http.write_timeout` _(optional, default: `1m`)_ \- Timeout for writing data to clients - `api.http.idle_timeout` _(optional, default: `30s`)_ \- Timeout for idle connections - `api.http.max_request_body_size` _(optional, default: `4Mb`)_ \- Maximum request body size A typical configuration for production looks like: ```nextra-code api: development: false host: localhost port: 9099 ``` For local development, set `api.development = true`. In development mode, Arcade Engine does not require [worker authentication](https://docs.arcade.dev/home/local-deployment/configure/engine#http-worker-configuration). ## Auth configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#auth-configuration) Arcade Engine manages auth for [AI tools](https://docs.arcade.dev/home/auth/auth-tool-calling) and [direct API calls](https://docs.arcade.dev/home/auth/call-third-party-apis-directly). It supports many built-in [auth providers](https://docs.arcade.dev/home/auth-providers), and can also connect to any [OAuth 2.0](https://docs.arcade.dev/home/auth-providers/oauth2) authorization server. The `auth.providers` section defines the providers that users can authorize with. Each provider must have a unique `id` in the array. There are two ways to configure a provider: For [built-in providers](https://docs.arcade.dev/home/auth-providers), use the `provider_id` field to reference the pre-built configuration. For example: ```nextra-code auth: providers: - id: default-github description: The default GitHub provider enabled: true type: oauth2 provider_id: github client_id: ${env:GITHUB_CLIENT_ID} client_secret: ${env:GITHUB_CLIENT_SECRET} ``` For custom OAuth 2.0 providers, specify the full connection details in the `oauth2` sub-section. For full documentation on the custom provider configuration, see the [OAuth 2.0 provider configuration](https://docs.arcade.dev/home/auth-providers/oauth2) page. You can specify a mix of built-in and custom providers. ## Cache configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#cache-configuration) The `cache` section configures the short-lived cache. Configuring the cache is optional. If not configured, the cache will default to an in-memory cache implementation suitable for a single-node Arcade Engine deployment. The `cache` section has the following configuration options: - `api_key_ttl` _(optional, default: `10s`)_ \- The time-to-live for API keys in the cache Two cache implementations are available: - `in_memory` \- _(default)_ An in-memory cache implementation suitable for a single-node Arcade Engine deployment. - `redis` \- A Redis cache implementation suitable for a multi-node Arcade Engine deployment: ```nextra-code cache: api_key_ttl: 10s redis: addr: 'localhost:6379' password: '' db: 0 ``` ## Security configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#security-configuration) The `security` section configures the root encryption keys that the Arcade Engine uses to encrypt and decrypt data at rest. See the [storage configuration](https://docs.arcade.dev/home/local-deployment/configure/engine#storage-configuration) section below to configure where data is stored. A typical configuration looks like this: ```nextra-code security: root_keys: - id: key1 default: true value: ${env:ROOT_KEY_1} ``` Keys should be a long random string of characters. For example: ```nextra-code openssl rand -base64 32 ``` ### Default root key [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#default-root-key) When you [install Arcade Engine locally](https://docs.arcade.dev/home/local-deployment/install/local), an `engine.env` file is created with a default root key: ```nextra-code # Encryption keys (change this when deploying to production) ROOT_KEY_1=default-key-value ``` This default value can only be used in development mode (see [API configuration](https://docs.arcade.dev/home/local-deployment/configure/engine#api-configuration) above). You **must** replace the value of `ROOT_KEY_1` in `engine.env` before deploying to production. ## Storage configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#storage-configuration) The `storage` section configures the storage backend that the Arcade Engine uses to store persistent data. There are three storage implementations available: - `in_memory` \- _(default)_ An in-memory database, suitable for testing. - `sqlite` \- A SQLite file on disk, suitable for local development: ```nextra-code storage: sqlite: # Stores DB in ~/.arcade/arcade-engine.sqlite3 connection_string: '@ARCADE_HOME/arcade-engine.sqlite3' ``` - `postgres` \- A PostgreSQL database, suitable for production: ```nextra-code storage: postgres: user: ${env:POSTGRES_USER} password: ${env:POSTGRES_PASSWORD} host: ${env:POSTGRES_HOST} port: ${env:POSTGRES_PORT} db: ${env:POSTGRES_DB} sslmode: require ``` ## Telemetry configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#telemetry-configuration) Arcade supports logs, metrics, and traces with [OpenTelemetry](https://opentelemetry.io/). If you are using the Arcade Engine locally, you can set the `environment` field to `local`. This will only output logs to the console: ```nextra-code telemetry: environment: local logging: # debug, info, warn, error, fatal level: debug encoding: console ``` To connect to OpenTelemetry compatible collectors, set the necessary [OpenTelemetry environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) in the `engine.env` file. `environment` and `version` are fields that are added to the telemetry attributes, which can be filtered on later. ```nextra-code telemetry: environment: prod logging: level: info encoding: console ``` ### Notes [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#notes) - The Engine service name is set to `arcade_engine` - Traces currently cover the `/v1/health` endpoints, as well as authentication attempts ## Tools configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#tools-configuration) Arcade Engine orchestrates [tools](https://docs.arcade.dev/home/use-tools/tools-overview) that AI models can use. Tools are executed by distributed workers called **workers**, which are grouped into **directors**. The `tools.directors` section configures the workers that are available to service tool calls: ```nextra-code tools: directors: - id: default enabled: true max_tools: 64 workers: - id: local_worker enabled: true http: uri: 'http://localhost:8002' timeout: 30 retry: 3 ``` When a worker is added to an enabled director, all of the tools hosted by that worker will be available to the model and through the Arcade API. ### HTTP worker configuration [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#http-worker-configuration) The `http` sub-section configures the HTTP client used to call the worker’s tools: - `uri` _(required)_ \- The base URL of the worker’s tools - `secret` _(required)_ \- Secret used to authenticate with the worker - `timeout` _(optional, default: `30s`)_ \- Timeout for calling the worker’s tools - `retry` _(optional, default: `3`)_ \- Number of times to retry a failed tool call Workers must be configured with a `secret` that is used to authenticate with the worker. This ensures that workers are not exposed to the public internet without security. If `api.development = true`, the secret will default to `"dev"` for local development **only**. In production, the secret must be set to a random value. ## Config file version history [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/engine\#config-file-version-history) - 1.0: [Full example](https://raw.githubusercontent.com/ArcadeAI/docs/refs/heads/main/examples/code/home/configuration/engine/full_config.1.0.yaml) and [schema](https://raw.githubusercontent.com/ArcadeAI/schemas/refs/heads/main/engine/config/1.0/schema.json) [Overview](https://docs.arcade.dev/home/local-deployment/configure/overview "Overview") [Configuring Arcade Deploy](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy "Configuring Arcade Deploy") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Hubspot Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Hubspot # Hubspot auth provider The Hubspot auth provider enables tools and agents to call Hubspot APIs on behalf of a user. Behind the scenes, the Arcade Engine and the Hubspot auth provider seamlessly manage Hubspot OAuth 2.0 authorization for your users. Want to quickly get started with Hubspot services in your agent or AI app? The pre-built [Arcade Hubspot toolkit](https://docs.arcade.dev/toolkits/sales/hubspot) is what you want! ## What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#whats-documented-here) This page describes how to use and configure Hubspot auth with Arcade. This auth provider is used by: - The [Arcade Hubspot toolkit](https://docs.arcade.dev/toolkits/sales/hubspot), which provides pre-built tools for interacting with Hubspot - Your [app code](https://docs.arcade.dev/home/auth-providers/hubspot#using-hubspot-auth-in-app-code) that needs to call Hubspot APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/hubspot#using-hubspot-auth-in-custom-tools) that need to call Hubspot APIs ## Use Arcade’s Default Hubspot Auth Provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#use-arcades-default-hubspot-auth-provider) Arcade offers a default Hubspot auth provider that you can use in the Arcade Cloud. In this case, your users will see `Arcade` as the name of the application that’s requesting permission. If you choose to use Arcade’s Hubspot auth, you don’t need to configure anything. Follow the [Hubspot toolkit examples](https://docs.arcade.dev/toolkits/sales/hubspot) to get started calling Hubspot tools. ## Use Your Own Hubspot App Credentials [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#use-your-own-hubspot-app-credentials) In a production environment, you will most likely want to use your own Hubspot app credentials. This way, your users will see your application’s name requesting permission. You can use your own Hubspot credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Hubspot app credentials, let’s go through the steps to create a Hubspot app. ## Create a Hubspot App [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#create-a-hubspot-app) Hubspot has two types of apps: Public and Private. You will need to create a Public one. Follow [Hubspot’s tutorial](https://developers.hubspot.com/docs/guides/apps/public-apps/overview) to create your Public App. You will need a [developer account](https://app.hubspot.com/signup-hubspot/developers) to do this. When creating your app, use the following settings: - Under **App Info**, choose a name, description, and logo for your app - Under **Auth**, enter the **Redirect URL**: `https://cloud.arcade.dev/api/v1/oauth/callback` - In the **Scopes** section, click **Add Scope** and add the following scopes with the **Conditionally Required** scope type: - `crm.objects.companies.read` - `crm.objects.contacts.read` - `crm.objects.contacts.write` - `crm.objects.deals.read` - `sales-email-read` Create the app and take note of the **Client ID** and **Client Secret**. You don’t need to follow Hubspot’s instructions to install the app. If you are implementing your own [Hubspot custom\\ tools](https://docs.arcade.dev/home/auth-providers/hubspot#using-hubspot-auth-in-custom-tools), make sure to also add [any extra\\ scopes](https://developers.hubspot.com/docs/guides/apps/authentication/scopes) necessary for the actions your tools need to perform. All extra scopes must be added to the app as `Conditionally Required` or `Optional`, never as `Required`, otherwise the Arcade Hubspot toolkit will not work. Read more about [Hubspot scope\\ types](https://developers.hubspot.com/changelog/advanced-auth-and-scope-settings-for-public-apps). ## Configuring your own Hubspot Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#configuring-your-own-hubspot-auth-provider-in-arcade) There are two ways to configure your Hubspot app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (only possible with a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Hubspot Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Hubspot**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#enter-the-provider-details) - Enter `hubspot` as the **ID** for your provider - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Hubspot app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Hubspot auth using your Arcade account credentials, the Arcade Engine will automatically use this Hubspot OAuth provider. If you have multiple Hubspot providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configure Hubspot Auth Using the Engine Configuration YAML Refer to [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. #### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#set-environment-variables) Set the following environment variables: ```nextra-code export HUBSPOT_CLIENT_ID="" export HUBSPOT_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code HUBSPOT_CLIENT_ID="" HUBSPOT_CLIENT_SECRET="" ``` #### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#edit-the-engine-configuration) To locate the `engine.yaml` file in your OS after installing the Arcade Engine, check the [Engine configuration\\ file](https://docs.arcade.dev/home/local-deployment/configure/overview#engine-configuration-file) documentation. Edit the `engine.yaml` file and add a Hubspot item to the `auth.providers` section: ```nextra-code auth: providers: - id: hubspot description: "Custom Hubspot provider" enabled: true type: oauth2 client_id: ${env:HUBSPOT_CLIENT_ID} client_secret: ${env:HUBSPOT_CLIENT_SECRET} ``` #### Restart the Arcade Engine [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#restart-the-arcade-engine) If the Arcade Engine is already running, you will need to restart it for the changes to take effect. ## Using the Arcade Hubspot Toolkit [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#using-the-arcade-hubspot-toolkit) The [Arcade Hubspot toolkit](https://docs.arcade.dev/toolkits/sales/hubspot) provides tools to interact with various Hubspot objects, such as companies, contacts, deals, and email messages. Refer to the [toolkit documentation and examples](https://docs.arcade.dev/toolkits/sales/hubspot) to learn how to use the toolkit to build agents and AI apps that interact with Hubspot services. ## Using Hubspot auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#using-hubspot-auth-in-app-code) Use the Hubspot auth provider in your own agents and AI apps to get a user-scoped token for the Hubspot API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Hubspot API: PythonJavaScript If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), change the `base_url` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code from arcadepy import Arcade client = Arcade(base_url="https://api.arcade.dev") # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="hubspot", scopes=["oauth", "crm.objects.companies.read"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), change the `baseURL` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade({ baseURL: "https://api.arcade.dev" }); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "hubspot", { scopes: ["oauth", "crm.objects.companies.read"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete const response = await client.auth.waitForCompletion(authResponse); const token = response.context.token; // Do something interesting with the token... ``` You can use the auth token to call [Hubspot Companies endpoints](https://developers.hubspot.com/docs/guides/api/crm/objects/companies) and read information about companies. By changing or adding scopes to the `client.auth.start` call, you can call other Hubspot endpoints. The scopes supported by the Arcade Hubspot auth provider are the ones [listed above](https://docs.arcade.dev/home/auth-providers/hubspot#create-a-hubspot-app). If you created your own Hubspot app, make sure to add the scopes you intend to use in the `client.auth.start` call. ## Using Hubspot auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/hubspot\#using-hubspot-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Hubspot API. Use the `Hubspot()` auth class to specify that a tool requires authorization with Hubspot. The authentication token needed to call the Hubspot API is available in the tool context through the `context.get_auth_token_or_empty()` method. ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Hubspot @tool( requires_auth=Hubspot( scopes=["oauth", "crm.objects.companies.read"], ) ) async def get_company_details( context: ToolContext, company_id: Annotated[\ str,\ "The ID of the company to get the details of.",\ ], ) -> Annotated[dict, "Details of the company"]: """Gets the details of a company.""" url = f"https://api.hubapi.com/crm//v3/objects/companies/{company_id}" headers = {"Authorization": f"Bearer {context.get_auth_token_or_empty()}"} async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json() ``` If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), you will need to restart the Arcade Worker and the Engine for the new tool to be available. Your new tool can be called like demonstrated below: PythonJavaScript If you are self-hosting, change the `base_url` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code from arcadepy import Arcade client = Arcade(base_url="https://api.arcade.dev") # Automatically finds the `ARCADE_API_KEY` env variable USER_ID = "user@example.com" TOOL_NAME = "Hubspot.GetCompanyDetails" auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID) if auth_response.status != "completed": print(f"Click this link to authorize: {auth_response.url}") # Wait for the authorization to complete client.auth.wait_for_completion(auth_response) tool_input = { "company_id": "32134490789", } response = client.tools.execute( tool_name=TOOL_NAME, input=tool_input, user_id=USER_ID, ) print(response.output.value) ``` If you are self-hosting, change the `baseURL` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade({ baseURL: "https://api.arcade.dev" }); // Automatically finds the `ARCADE_API_KEY` env variable const USER_ID = "user@example.com"; const TOOL_NAME = "Hubspot.GetCompanyDetails"; // Start the authorization process const authResponse = await client.tools.authorize({ tool_name: TOOL_NAME, user_id: USER_ID, }); if (authResponse.status !== "completed") { console.log(`Click this link to authorize: ${authResponse.url}`); } // Wait for the authorization to complete await client.auth.waitForCompletion(authResponse); const toolInput = { company_id: "1234567890", }; const response = await client.tools.execute({ tool_name: TOOL_NAME, input: toolInput, user_id: USER_ID, }); console.log(response.output.value); ``` [Google](https://docs.arcade.dev/home/auth-providers/google "Google") [Linkedin](https://docs.arcade.dev/home/auth-providers/linkedin "Linkedin") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Zoom Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Zoom # Zoom auth provider At this time, Arcade does not offer a default Zoom Auth Provider. To use Zoom auth, you must create a custom Auth Provider with your own Zoom OAuth 2.0 credentials as described below. The Zoom auth provider enables tools and agents to call the Zoom API on behalf of a user. Behind the scenes, the Arcade Engine and the Zoom auth provider seamlessly manage Zoom OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#whats-documented-here) This page describes how to use and configure Zoom auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/zoom#using-zoom-auth-in-app-code) that needs to call Zoom APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/zoom#using-zoom-auth-in-custom-tools) that need to call Zoom APIs ## Configuring Zoom auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#configuring-zoom-auth) In a production environment, you will most likely want to use your own Zoom app credentials. This way, your users will see your application’s name requesting permission. You can use your own Zoom credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Zoom app credentials, let’s go through the steps to create a Zoom app. ### Create a Zoom app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#create-a-zoom-app) - Follow Zoom’s guide to [registering an app](https://developers.zoom.us/docs/integrations/create/) on the Zoom marketplace - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` and enable Strict Mode - Enable the Zoom features and permissions (scopes) that your app needs - Copy the client ID and client secret to use below Next, add the Zoom app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Zoom Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#configuring-your-own-zoom-auth-provider-in-arcade) There are two ways to configure your Zoom app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Zoom Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Zoom**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-zoom-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Zoom app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Zoom auth using your Arcade account credentials, the Arcade Engine will automatically use this Zoom OAuth provider. If you have multiple Zoom providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Zoom auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#set-environment-variables) Set the following environment variables: ```nextra-code export ZOOM_CLIENT_ID="" export ZOOM_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code ZOOM_CLIENT_ID="" ZOOM_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `zoom` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-zoom description: "The default Zoom provider" enabled: true type: oauth2 provider_id: zoom client_id: ${env:ZOOM_CLIENT_ID} client_secret: ${env:ZOOM_CLIENT_SECRET} ``` ## Using Zoom auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#using-zoom-auth-in-app-code) Use the Zoom auth provider in your own agents and AI apps to get a user token for the Zoom API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Zoom API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="zoom", scopes=["meeting:read:list_upcoming_meetings"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "zoom", [\ "meeting:read:list_upcoming_meetings",\ ]); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Zoom auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/zoom\#using-zoom-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Zoom API. Use the `Zoom()` auth class to specify that a tool requires authorization with Zoom. The `context.authorization.token` field will be automatically populated with the user’s Zoom token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Zoom @tool( requires_auth=Zoom( scopes=["meeting:read:list_upcoming_meetings"], ) ) async def list_upcoming_meetings( context: ToolContext, user_id: Annotated[\ Optional[str],\ "The user's user ID or email address. Defaults to 'me' for the current user.",\ ] = "me", ) -> Annotated[dict, "List of upcoming meetings within the next 24 hours"]: """List a Zoom user's upcoming meetings within the next 24 hours.""" url = f"https://api.zoom.us/v2/users/{user_id}/upcoming_meetings" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json() ``` [X](https://docs.arcade.dev/home/auth-providers/x "X") [FAQ](https://docs.arcade.dev/home/faq "FAQ") ## Close.io Productivity [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") Close.io # Close.io Coming Soon [Obsidian](https://docs.arcade.dev/toolkits/productivity/obsidian "Obsidian") [Discord](https://docs.arcade.dev/toolkits/social-communication/discord "Discord") ## Web Toolkit Reference [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Developer Tools](https://docs.arcade.dev/toolkits/development/code-sandbox "Developer Tools") WebReference # Reference for Web Toolkit ## Formats [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/reference\#formats) The format of the scraped web page. - **`MARKDOWN`**: Returns the scraped web page in Markdown format. - **`HTML`**: Returns the scraped web page in HTML format. - **`RAW_HTML`**: Returns the raw HTML of the scraped web page. - **`LINKS`**: Returns only the links from the scraped web page. - **`SCREENSHOT`**: Takes a screenshot of the scraped web page. - **`SCREENSHOT_AT_FULL_PAGE`**: Takes a full-page screenshot of the scraped web page. [Reference](https://docs.arcade.dev/toolkits/development/github/reference "Reference") [Web](https://docs.arcade.dev/toolkits/development/web/web "Web") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## OAuth 2.0 Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") OAuth 2.0 # OAuth 2.0 auth provider The OAuth 2.0 auth provider enables tools and agents to authorize with any OAuth 2.0-compatible API on behalf of a user. Behind the scenes, the Arcade Engine and this auth provider seamlessly manage OAuth 2.0 authorization for your users. Arcade has [pre-built integrations](https://docs.arcade.dev/home/auth-providers) with many popular OAuth 2.0 providers. Use this OAuth 2.0 provider to connect to other systems that aren’t pre-built. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#whats-documented-here) This page describes how to configure OAuth 2.0 with Arcade, and use it in: - Your [app code](https://docs.arcade.dev/home/auth-providers/oauth2#using-oauth-20-in-app-code) that needs to call APIs protected by OAuth 2.0 - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/oauth2#using-oauth-20-in-custom-tools) that need to call APIs protected by OAuth 2.0 ### Supported OAuth 2.0 flows [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#supported-oauth-20-flows) The only supported OAuth 2.0 flow is the authorization code grant flow (with or without PKCE). ## Configuring OAuth 2.0 [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#configuring-oauth-20) How you configure the OAuth 2.0 provider depends on whether you use the Arcade Cloud Engine or a [self-hosted Engine](https://docs.arcade.dev/home/local-deployment/install/overview). If you use the Cloud Engine, you must configure your provider in the Dashboard. When configuring your app in the OAuth 2.0 enabled service, you must use `https://cloud.arcade.dev/api/v1/oauth/callback` as the redirect URL (sometimes called callback URL). ### Using the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#using-the-arcade-dashboard) When using the Arcade Cloud, the Dashboard is available at [`https://api.arcade.dev/dashboard`](https://api.arcade.dev/dashboard). If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), by default the Dashboard is available at [`http://localhost:9099/dashboard`](http://localhost:9099/dashboard). Adjust the host and port, if necessary, to match your environment. 1. Navigate to the OAuth section of the Arcade Dashboard and click **Add OAuth Provider**. 2. Select **OAuth 2.0** as the provider. 3. Choose a unique **ID** for your provider (e.g. “my-oauth2-provider”) with an optional **Description**. 4. Enter your **Client ID** and **Client Secret** from your OAuth 2.0 provider. 5. Click **Save**. When you use tools that require OAuth 2.0 authorization using your Arcade account credentials, the Arcade Engine will automatically use this OAuth 2.0 provider. ### Using the `engine.yaml` configuration file [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#using-the-engineyaml-configuration-file) This method is only available when you are [self-hosting the engine](https://docs.arcade.dev/home/local-deployment/install/overview) ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#set-environment-variables) Set the following environment variables. Replace `HOOLI` with the name of the OAuth 2.0 provider you are configuring: ```nextra-code export HOOLI_CLIENT_ID="" export HOOLI_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code HOOLI_CLIENT_ID="" HOOLI_CLIENT_SECRET="" ``` See [configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#edit-the-engine-configuration) To locate the `engine.yaml` file in your OS after installing the Arcade Engine, check the [Engine configuration file](https://docs.arcade.dev/home/local-deployment/configure/overview#engine-configuration-file) documentation. Edit the `engine.yaml` file and add a new item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-github description: The default GitHub provider enabled: true type: oauth2 provider_id: github client_id: ${env:GITHUB_CLIENT_ID} client_secret: ${env:GITHUB_CLIENT_SECRET} - id: hooli description: Hooli OAuth 2.0 provider enabled: true type: oauth2 client_id: ${env:HOOLI_CLIENT_ID} client_secret: ${env:HOOLI_CLIENT_SECRET} oauth2: # For a custom OAuth 2.0 provider, specify the full OAuth configuration: ``` The ID of the provider ( `hooli` in this example) can be any string. It’s used to reference the provider in your app code and must be unique. Each service expects a slightly different set of values in the `oauth2` section. Refer to the configuration reference below, and to your service’s documentation to understand what values are required. If you need help configuring a specific provider, [get in touch with\\ us](mailto:contact@arcade.dev)! ### Configuration reference [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#configuration-reference) For a full example, see the [full configuration example](https://docs.arcade.dev/home/auth-providers/oauth2#full-configuration-example) below. `scope_delimiter` _(optional, defaults to the space character)_: The delimiter to use between scopes. `pkce` _(optional)_: - `enabled` _(optional, default `false`)_: If `true`, PKCE will be used. - `code_challenge_method` _(optional, default `S256`)_: The code challenge method to use. The only supported method is `S256`. This parameter is ignored if PKCE is not enabled. #### `authorize_request` [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#authorize_request) This section configures the initial authorization request. - `endpoint`: The authorization endpoint for your OAuth 2.0 server, e.g. `/oauth2/authorize` - `params`: A map of parameter keys and values to include in the authorization request. These placeholders are available in `params`: - `{{client_id}}`: The configured client ID. - `{{redirect_uri}}`: The redirect URI managed by Arcade. - `{{scopes}}`: The scopes to request, if any - `{{existing_scopes}}`: The scopes that the user has already granted, if any. The `state` parameter is automatically added to the request, and does not need to be included in `params`. If PKCE is enabled, `code_challenge` and `code_challenge_method` are also added automatically. For most providers, `oauth2.authorize_request` will look like: ```nextra-code authorize_request: endpoint: 'https://example.com/oauth2/authorize' params: response_type: code client_id: '{{client_id}}' redirect_uri: '{{redirect_uri}}' scope: '{{scopes}} {{existing_scopes}}' ``` Some providers support additional parameters in the authorization request. These can be added to `params` as well. For example: ```nextra-code authorize_request: endpoint: 'https://example.com/oauth2/authorize' params: response_type: code client_id: '{{client_id}}' redirect_uri: '{{redirect_uri}}' scope: '{{scopes}} {{existing_scopes}}' prompt: consent access_type: offline ``` #### `token_request` [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#token_request) This section configures the code/token exchange request, after the user has approved access to your app. - `endpoint`: The token endpoint for your OAuth 2.0 server, e.g. `/oauth2/token` - `auth_method` _(optional, default none)_: The authentication method to use. Supported values are none (omitted) and `client_secret_basic`. - `params`: A map of parameter keys and values to include in the token request. These placeholders are available in `params`: - `{{client_id}}`: The configured client ID. - `{{client_secret}}`: The configured client secret. - `{{redirect_uri}}`: The redirect URI managed by Arcade. The `code` parameter is automatically added to the request, and does not need to be included in `params`. If PKCE is enabled, the `code_verifier` parameter is also added to the request automatically. For most providers, `oauth2.token_request.params` will look like: ```nextra-code token_request: endpoint: 'https://example.com/oauth2/token' params: grant_type: authorization_code redirect_uri: '{{redirect_uri}}' client_id: '{{client_id}}' client_secret: '{{client_secret}}' # Omit if using PKCE ``` - `response_content_type` _(optional, default `application/json`)_: The expected content type of the response. Supported values are `application/json` and `application/x-www-form-urlencoded`. - `response_map` _(optional)_: A map of keys and values to extract from the response. Supports simple JSONPath expressions. Only applicable if `response_content_type` is `application/json`. See the [JSONPath reference](https://docs.arcade.dev/home/auth-providers/oauth2#jsonpath-expressions-in-response_map) for details on extracting values using JSONPath. #### `refresh_request` [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#refresh_request) This section configures the refresh token request, if your OAuth 2.0 server supports refresh tokens. If not provided, refresh tokens will not be used. - `endpoint`: The refresh token endpoint for your OAuth 2.0 server, e.g. `/oauth2/token` - `auth_method` _(optional, default none)_: The authentication method to use. Supported values are none (omitted), `client_secret_basic`, and `bearer_access_token`. - `params`: A map of parameter keys and values to include in the refresh token request. These placeholders are available in `params`: - `{{refresh_token}}`: The refresh token to use. - `{{client_id}}`: The configured client ID. - `{{client_secret}}`: The configured client secret. For most providers, `oauth2.refresh_request.params` will look like: ```nextra-code refresh_request: endpoint: 'https://example.com/oauth2/token' params: grant_type: refresh_token client_id: '{{client_id}}' client_secret: '{{client_secret}}' ``` - `response_content_type` _(optional, default `application/json`)_: The expected content type of the response. Supported values are `application/json` and `application/x-www-form-urlencoded`. - `response_map` _(optional)_: A map of keys and values to extract from the response. Supports simple JSONPath expressions. Only applicable if `response_content_type` is `application/json`. See the [JSONPath reference](https://docs.arcade.dev/home/auth-providers/oauth2#jsonpath-expressions-in-response_map) for details on extracting values using JSONPath. #### `user_info_request` [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#user_info_request) Some OAuth 2.0 APIs provide a user info endpoint that returns information about the user. Arcade Engine can automatically request user info from servers that support it. If the `user_info_request` section is omitted, user info will not be requested. - `endpoint`: The user info endpoint for your OAuth 2.0 server, e.g. `/oauth2/userinfo` - `auth_method` _(optional, default `bearer_access_token`)_: The authentication method to use. The only supported value is `bearer_access_token`. - `response_content_type` _(optional, default `application/json`)_: The expected content type of the response. The only supported value is `application/json`. - `triggers`: Controls when the user info request is made. - `on_token_grant`: If `true`, the user info request will be made when a token is granted. This is typically only once for each user, unless new scopes are granted. - `on_token_refresh`: If `true`, the user info request will be made every time a token is refreshed. #### `token_introspection_request` [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#token_introspection_request) Some OAuth 2.0 APIs provide a token introspection endpoint that can be used to check the validity of a token and retrieve additional information such as token expiration time. An example of a token introspection request configuration: ```nextra-code auth: providers: - id: custom-provider description: "Custom provider" enabled: true type: oauth2 client_id: ${env:CUSTOM_CLIENT_ID} client_secret: ${env:CUSTOM_CLIENT_SECRET} oauth2: token_introspection_request: enabled: true endpoint: 'https://example.oauth.com/services/oauth2/introspect' method: POST params: token: '{{access_token}}' auth_method: 'client_secret_basic' request_content_type: application/x-www-form-urlencoded response_content_type: application/json response_map: expires_in: '$.exp' scope: '$.scope' expiration_format: absolute_unix_timestamp triggers: on_token_grant: true on_token_refresh: true ``` - `enabled` _(optional, default `false`)_: If `true`, the token introspection request will be made. - `endpoint` _(required)_: The endpoint to use for the token introspection request. - `method` _(optional, default `GET`)_: The HTTP method to use for the token introspection request. - `params` _(optional)_: A map of parameter keys and values to include in the token introspection request. Currently, only mapping a field to the internal `access_token` field is supported. - `auth_method` _(optional, default `client_secret_basic`)_: The authentication method to use for the token introspection request. Supported values are `client_secret_basic` and `bearer_access_token`. - `request_content_type` _(optional, default `application/x-www-form-urlencoded`)_: The content type of the request body. - `response_content_type` _(optional, default `application/json`)_: The content type of the response body. - `response_map` _(required)_: A map of keys and values to extract from the response. Supports simple JSONPath expressions. Supported keys are `access_token`, `expires_in`, `refresh_token`, `scope`, and `token_type`. - `expiration_format` _(optional, default `absolute_unix_timestamp`)_: The format of the expiration time. Supported values are `absolute_unix_timestamp` and `relative_seconds`. - `triggers` _(required)_: Controls when the token introspection request is made. - `on_token_grant`: If `true`, the token introspection request will be made when a token is granted. This is typically only once for each user, unless new scopes are granted. - `on_token_refresh`: If `true`, the token introspection request will be made every time a token is refreshed. #### JSONPath expressions in `response_map` [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#jsonpath-expressions-in-response_map) In the `token_request` and `refresh_request` sections, you can optionally configure a `response_map`. Configuring a response map is useful if your OAuth 2.0 server returns a JSON object with nested properties, or properties with non-standard names. The typical JSON payload that most OAuth 2.0 servers return looks like this: ```nextra-code { "access_token": "...", "refresh_token": "...", "expires_in": 3600, "scope": "scope1 scope2" } ``` If your server returns a payload that looks like this, you don’t need `response_map`. But if your server returns: ```nextra-code { "data": { "access_token": "...", "expires_in": 3600, "refresh_token": "...", "scope": "scope1 scope2" } } ``` Then you need to configure `response_map` to extract the properties from inside the `data` object. Use [JSONPath](https://en.wikipedia.org/wiki/JSONPath) expressions to select the properties you need: ```nextra-code token_request: # or refresh_request response_map: access_token: "$.data.access_token" expires_in: "$.data.expires_in" refresh_token: "$.data.refresh_token" # Only needed if refresh tokens are used scope: "$.data.scope" # Only needed if scopes are used ``` Not all OAuth 2.0 servers support refresh tokens, or use scopes. The only required properties are `access_token` and `expires_in`. #### Handling scope arrays [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#handling-scope-arrays) Most OAuth 2.0 servers return scopes as a delimited string, such as `scope1 scope2` or `scope1,scope2`. If your server follows this convention, configuring the top-level `scope_delimiter` property in the `oauth2` section is all you need to do. Some OAuth 2.0 servers return an array of scopes instead of a delimited string. For example: ```nextra-code { "access_token": "...", "expires_in": 3600, "scope": ["scope1", "scope2"] } ``` In this case, you need to use the `join()` function in `response_map` to join the scopes into a delimited string: ```nextra-code token_request: response_map: access_token: "$.access_token" expires_in: "$.expires_in" scope: "join('$.scope', ' ')" ``` `join()` takes two arguments: - `path`: The JSONPath expression to select the array to join. - `delimiter`: The delimiter to use between array elements. Make sure this matches the `scope_delimiter` setting in the `oauth2` section. #### Extracting values from JWTs [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#extracting-values-from-jwts) Some OAuth 2.0 servers return JWT tokens that contain claims you might need to extract. For example, the token might contain scopes or other information about the user. You can use the `jwt_decode()` function in `response_map` to extract values from JWT tokens: ```nextra-code token_request: response_map: access_token: "$.access_token" expires_in: "$.expires_in" scope: "jwt_decode('$.access_token', '$.scope')" ``` `jwt_decode()` takes two arguments: - `token_path`: The JSONPath expression to select the JWT token. - `claim_path`: The JSONPath expression to select the claim within the decoded JWT payload. If the claim is an array (like scopes often are), you can combine `jwt_decode()` with `join()` to extract and format the values: ```nextra-code token_request: response_map: access_token: "$.access_token" expires_in: "$.expires_in" scope: "join(jwt_decode('$.access_token', '$.scp'), ' ')" ``` This is particularly useful when the JWT token contains scopes in an array format (like `scp: ["scope1", "scope2"]`) and you need to convert them to a space-delimited string. You can also extract nested claims from the JWT payload using dot notation in the claim path: ```nextra-code token_request: response_map: access_token: "$.access_token" expires_in: "$.expires_in" scope: "jwt_decode('$.access_token', '$.nested.scopes')" ``` #### Full configuration example [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#full-configuration-example) Here’s a full example of the YAML configuration for a custom OAuth 2.0 provider: Click to view example ## Using OAuth 2.0 in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#using-oauth-20-in-app-code) Use the OAuth 2.0 auth provider in your own agents and AI apps to get a user token for any OAuth 2.0-compatible APIs. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get an access token: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="hooli", scopes=["scope1", "scope2"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # TODO: Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "hooli", [\ "scope1",\ "scope2",\ ]); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // TODO: Do something interesting with the token... ``` ## Using OAuth 2.0 in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/oauth2\#using-oauth-20-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with any OAuth 2.0-compatible APIs. Use the `OAuth2()` auth class to specify that a tool requires OAuth 2.0 authorization. In your tool function, `context.authorization` will be automatically populated with the following properties: - `context.authorization.token` contains the user’s access token. - If `oauth2.user_info_request` is configured, the user info will be fetched and placed in `context.authorization.user_info`. The data payload is specific to each provider. ```nextra-code from typing import Annotated from arcade_tdk import ToolContext, tool from arcade_tdk.auth import OAuth2 @tool( requires_auth=OAuth2( provider_id="hooli", scopes=["scope1", "scope2"], ) ) async def reticulate_splines( context: ToolContext, num_splines: Annotated[int, "The number of splines to reticulate"], ): """Reticulate the specified number of splines.""" # Get an access token to call an API token = context.authorization.token # Get user info (if configured and supported by the OAuth 2.0 server): user_id = context.authorization.user_info.get("sub") ``` [Notion](https://docs.arcade.dev/home/auth-providers/notion "Notion") [Reddit](https://docs.arcade.dev/home/auth-providers/reddit "Reddit") ## Connect Claude Desktop [Home](https://docs.arcade.dev/home "Home") IDEs and desktop clientsUse Arcade with Claude Desktop # Use Arcade with Claude Desktop In this guide, you’ll learn how to connect Claude Desktop to a local Arcade server. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/mcp-desktop-clients/claude-desktop-client\#prerequisites) 1. Create an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=claude-desktop-client) 2. Get an [Arcade API key](https://docs.arcade.dev/home/api-keys) 3. Install **Python 3.10** or higher Verify your Python version by running `python --version` or `python3 --version` in your terminal. ### Install Dependencies [Permalink for this section](https://docs.arcade.dev/home/mcp-desktop-clients/claude-desktop-client\#install-dependencies) ```nextra-code pip install arcade-ai pip install arcade-google ``` See [Arcade’s Integrations](https://docs.arcade.dev/toolkits) for more toolkits that can be installed. ### Set up Claude Desktop [Permalink for this section](https://docs.arcade.dev/home/mcp-desktop-clients/claude-desktop-client\#set-up-claude-desktop) 1. Download and open [Claude Desktop](https://claude.ai/download) 2. Claude Menu —> “Settings” —> “Developer” —> “Edit Config” 3. This will create a configuration file at: - On Mac: `~/Library/Application Support/Claude/claude_desktop_config.json` - On Windows: `%APPDATA%\Claude\claude_desktop_config.json` 4. Open the configuration file and replace the file contents with this: Replace `YOUR_ARCADE_API_KEY_HERE` with your actual Arcade API key and `/path/to/python` with the path to your Python interpreter and `/path/to/arcade` with the path to the Arcade package. ```nextra-code { "mcpServers": { "arcade-stdio": { "command": "bash", "args": [\ "-c",\ "export ARCADE_API_KEY=YOUR_ARCADE_API_KEY_HERE && /path/to/python /path/to/arcade serve --mcp"\ ] } } } ``` 5. Restart Claude Desktop. Upon restarting, you should have access to the Arcade toolkits you installed. [MCP Overview](https://docs.arcade.dev/home/mcp-overview "MCP Overview") [Use Arcade in Visual Studio Code](https://docs.arcade.dev/home/mcp-desktop-clients/vscode-client "Use Arcade in Visual Studio Code") ## Tool Authorization Status [Home](https://docs.arcade.dev/home "Home") [Authorization](https://docs.arcade.dev/home/auth/how-arcade-helps "Authorization") Checking Authorization Status # Checking Tool Authorization Status Before executing tools that require authorization, you can check their authorization status to understand what permissions are needed and whether they’re currently available for a user. This is useful for: - Displaying authorization requirements in your UI - Pre-checking tool availability before execution - Understanding which tools need user approval - Debugging authorization issues ### Initialize the client [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#initialize-the-client) Import the Arcade client in a Python/Javascript script. PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable ``` ```nextra-code import Arcade from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable ``` ### Check authorization status for all tools [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#check-authorization-status-for-all-tools) You can get a list of all available tools and check their authorization status for a specific user: PythonJavaScript ```nextra-code USER_ID = "you@example.com" # Get all tools for the user tools = client.tools.list(user_id=USER_ID) for tool in tools: print(f"Tool: {tool.name}") if tool.requirements: # Check if all requirements are met print(f"Requirements met: {tool.requirements.met}") # Check authorization status if tool.requirements.authorization: print(f"Authorization status: {tool.requirements.authorization.status}") print(f"Token status: {tool.requirements.authorization.token_status}") # Check secret requirements if tool.requirements.secrets: for secret in tool.requirements.secrets: print(f"Secret '{secret.key}' met: {secret.met}") if not secret.met and secret.status_reason: print(f"Reason: {secret.status_reason}") print("---") ``` ```nextra-code const userId = "you@example.com"; // Get all tools for the user const tools = await client.tools.list({ user_id: userId }); tools.items.forEach(tool => { console.log(`Tool: ${tool.name}`); if (tool.requirements) { // Check if all requirements are met console.log(`Requirements met: ${tool.requirements.met}`); // Check authorization status if (tool.requirements.authorization) { console.log(`Authorization status: ${tool.requirements.authorization.status}`); console.log(`Token status: ${tool.requirements.authorization.token_status}`); } // Check secret requirements if (tool.requirements.secrets) { tool.requirements.secrets.forEach(secret => { console.log(`Secret '${secret.key}' met: ${secret.met}`); if (!secret.met && secret.status_reason) { console.log(`Reason: ${secret.status_reason}`); } }); } } console.log("---"); }); ``` If a username is not provided, the Token Status will be excluded and only the requirements for the provider will be shown. ### Check authorization status for a specific tool [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#check-authorization-status-for-a-specific-tool) You can also check the authorization status for a specific tool by name: PythonJavaScript ```nextra-code USER_ID = "you@example.com" TOOL_NAME = "Google.ListEmails" # Get specific tool details tool = client.tools.get(tool_name=TOOL_NAME, user_id=USER_ID) print(f"Tool: {tool.name}") print(f"Description: {tool.description}") if tool.requirements: print(f"All requirements met: {tool.requirements.met}") if tool.requirements.authorization: auth = tool.requirements.authorization print(f"Authorization required: {auth.provider_type}") print(f"Authorization status: {auth.status}") print(f"Token status: {auth.token_status}") if auth.status_reason: print(f"Status reason: {auth.status_reason}") if tool.requirements.secrets: print("Secret requirements:") for secret in tool.requirements.secrets: status = "✓" if secret.met else "✗" print(f" {status} {secret.key}") ``` ```nextra-code const userId = "you@example.com"; const toolName = "Google.ListEmails"; // Get specific tool details const tool = await client.tools.get(toolName, { user_id: userId }); console.log(`Tool: ${tool.name}`); console.log(`Description: ${tool.description}`); if (tool.requirements) { console.log(`All requirements met: ${tool.requirements.met}`); if (tool.requirements.authorization) { const auth = tool.requirements.authorization; console.log(`Authorization required: ${auth.provider_type}`); console.log(`Authorization status: ${auth.status}`); console.log(`Token status: ${auth.token_status}`); if (auth.status_reason) { console.log(`Status reason: ${auth.status_reason}`); } } if (tool.requirements.secrets) { console.log("Secret requirements:"); tool.requirements.secrets.forEach(secret => { const status = secret.met ? "✓" : "✗"; console.log(` ${status} ${secret.key}`); }); } } ``` ### Understanding the status values [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#understanding-the-status-values) #### Authorization Status [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#authorization-status) - `active`: If the provider is configured and enabled - `inactive`: Authorization is not found or is disabled #### Token Status [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#token-status) - `not_started`: Authorization process hasn’t begun - `pending`: Authorization is in progress (user needs to approve) - `completed`: Authorization is complete and tokens are available - `failed`: Authorization process failed #### Requirements Met [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#requirements-met) - `true`: All requirements for the tool are satisfied - `false`: Some requirements are missing (authorization, secrets, etc.) #### Secret Met [Permalink for this section](https://docs.arcade.dev/home/auth/tool-auth-status\#secret-met) - `true`: The secret exists for the tool - `false`: The secret does not exist for the tool [Authorized Tool Calling](https://docs.arcade.dev/home/auth/auth-tool-calling "Authorized Tool Calling") [Direct Third-Party API Call](https://docs.arcade.dev/home/auth/call-third-party-apis-directly "Direct Third-Party API Call") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Docker Installation [Home](https://docs.arcade.dev/home "Home") Local Deployment [Install](https://docs.arcade.dev/home/local-deployment/install/overview "Install") Docker # Docker Installation ## Engine [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/docker\#engine) ### Pulling the Engine Image [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/docker\#pulling-the-engine-image) The Arcade Engine is stateless and the docker image is designed to scale horizontally for production environments. The docker image for the engine can be pulled with ```nextra-code docker pull ghcr.io/arcadeai/engine:latest ``` ### Running the Engine [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/docker\#running-the-engine) The engine can be run with: ```nextra-code docker run -d -p 9099:9099 -v ./engine.yaml:/bin/engine.yaml ghcr.io/arcadeai/engine:latest ``` where config.yaml is the path to the [configuration file](https://docs.arcade.dev/home/local-deployment/configure/templates). ## Worker [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/docker\#worker) Arcade now provides a base Worker image that you can use to build your custom Worker image. Follow the [Build custom worker images with docker](https://docs.arcade.dev/home/serve-tools/docker-worker) guide to create your own Worker image using Arcade’s base Worker image. [Local](https://docs.arcade.dev/home/local-deployment/install/local "Local") [Toolkits](https://docs.arcade.dev/home/local-deployment/install/toolkits "Toolkits") ## Walmart Product Search [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Walmart # Walmart Search **Description:** Enable agents to search for products with Walmart. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Walmart Search toolkit provides a pre-built set of tools for interacting with Walmart. These tools make it easy to build agents and AI apps that can: - Search for products listed on Walmart stores; - Get details about a product. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/walmart\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchWalmartProducts | Search for products listed on Walmart stores. | | Search.GetWalmartProductDetails | Get details about a product listed on Walmart. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.SearchWalmartProducts [Permalink for this section](https://docs.arcade.dev/toolkits/search/walmart\#searchsearchwalmartproducts) See Example > Search for products listed on Walmart stores. **Parameters** - **keywords** _(string, required)_ Keywords to search for. E.g. ‘apple iphone’ or ‘samsung galaxy’ - **sort\_by** _(enum [WalmartSortBy](https://docs.arcade.dev/toolkits/search/reference#walmartsortby), optional, Defaults to `WalmartSortBy.RELEVANCE`)_ Sort the results by the specified criteria. Defaults to `WalmartSortBy.RELEVANCE`. - **min\_price** _(float, optional, Defaults to `None`)_ Minimum price to filter the results. - **max\_price** _(float, optional, Defaults to `None`)_ Maximum price to filter the results. - **next\_day\_delivery** _(bool, optional, Defaults to `False`)_ Whether to filter the results by next day delivery. Defaults to False (returns all products, regardless of delivery status). - **page** _(int, optional, Defaults to `1`)_ Page number to fetch. Defaults to 1 (first page of results). The maximum page value is 100. ## Search.GetWalmartProductDetails [Permalink for this section](https://docs.arcade.dev/toolkits/search/walmart\#searchgetwalmartproductdetails) See Example > Get details about a product listed on Walmart. **Parameters** - **item\_id** _(string, required)_ Item ID. E.g. ‘414600577’. This can be retrieved from the search results of the `SearchWalmartProducts` tool. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/walmart\#auth) The Arcade Walmart Search toolkit uses the [SerpAPI](https://serpapi.com/) to get product information from Walmart. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/search/reference "Reference") [Youtube](https://docs.arcade.dev/toolkits/search/youtube "Youtube") ## Get Tool Definitions [Home](https://docs.arcade.dev/home "Home") [Tool Calling](https://docs.arcade.dev/home/use-tools/tools-overview "Tool Calling") Tool formats # Get Formatted Tool Definitions When calling tools directly, it can be useful to get tool definitions in a specific model provider’s format. The Arcade Client provides methods for getting a tool’s definition and also for listing the definitions of multiple tools in a specific model provider’s format. ## Get a single tool definition formatted for a model [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#get-a-single-tool-definition-formatted-for-a-model) It can be useful to get a tool’s definition in a specific model provider’s format. For example, you may want to get the `Github.SetStarred` tool’s definition in OpenAI’s format. To do this, you can use the `client.tools.formatted.get` method and specify the tool name and format. PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Get a specific tool formatted for OpenAI github_star_repo = client.tools.formatted.get(name="Github.SetStarred", format="openai") print(github_star_repo) ``` ```nextra-code import Arcade from "@arcadeai/arcadejs"; const client = new Arcade(); // Get a specific tool formatted for OpenAI const githubStarRepo = await client.tools.formatted.get("Github.SetStarred", { format: "openai", }); console.log(githubStarRepo); ``` See output ## Get all tool definitions in a toolkit formatted for a model [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#get-all-tool-definitions-in-a-toolkit-formatted-for-a-model) It can be useful to list tool definitions for a toolkit in a specific model provider’s format. For example, you may want to get the definitions of tools in the `Github` toolkit in OpenAI’s format. To do this, you can use the `client.tools.formatted.list` method and specify the toolkit and format. Since this method returns an iterator of pages, you can cast to a list to get all the tools. PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Get all tools in the Github toolkit formatted for OpenAI github_tools = list(client.tools.formatted.list(format="openai", toolkit="github")) # Print the number of tools in the Github toolkit print(len(github_tools)) ``` ```nextra-code import Arcade from "@arcadeai/arcadejs"; const client = new Arcade(); // Get all tools in the Github toolkit formatted for OpenAI const githubTools = await client.tools.formatted.list({ format: "openai", toolkit: "github", }); // Print the number of tools in the Github toolkit console.log(githubTools.total_count); ``` ## Get all tool definitions formatted for a model [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#get-all-tool-definitions-formatted-for-a-model) To get all tools formatted for OpenAI, you can use the `client.tools.formatted.list` method without specifying a toolkit. PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Get all tools formatted for OpenAI all_tools = list(client.tools.formatted.list(format="openai")) # Print the number of tools print(len(all_tools)) ``` ```nextra-code import Arcade from "@arcadeai/arcadejs"; const client = new Arcade(); // Get all tools formatted for OpenAI const allTools = await client.tools.formatted.list({ format: "openai" }); // Print the number of tools console.log(allTools.total_count); ``` ## Get Zod Tool Definitions [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#get-zod-tool-definitions) [Zod](https://zod.dev/) is a TypeScript-first schema validation library that helps you define and validate data structures. The [Arcade JS](https://github.com/ArcadeAI/arcade-js) client offers methods to convert Arcade tool definitions into Zod schemas, providing type safety and validation while enabling seamless integration with AI frameworks like LangChain, Vercel AI SDK, and Mastra AI. Using Zod with Arcade provides: 1. **Type Safety**: Runtime validation of tool inputs and outputs against their defined types 2. **TypeScript Integration**: Provides excellent TypeScript support with automatic type inference 3. **Framework Compatibility**: Direct integration with LangChain, Vercel AI SDK, and Mastra AI ### Convert to Zod Format [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#convert-to-zod-format) Arcade offers three ways to convert your tools into Zod schemas, each for different use cases: #### 1\. Convert to array of Zod tools [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#1-convert-to-array-of-zod-tools) This method returns an array of tools with Zod validation. ```nextra-code import { toZod } from "@arcadeai/arcadejs/lib" const googleToolkit = await arcade.tools.list({ limit: 20, toolkit: "google", }); const tools = toZod({ tools: googleToolkit.items, client: arcade, userId: "", }) ``` #### 2\. Convert to object of Zod tools [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#2-convert-to-object-of-zod-tools) This method returns an object with tool names as keys, allowing direct access to tools by name: ```nextra-code import { toZodToolSet } from "@arcadeai/arcadejs/lib" const googleToolkit = await arcade.tools.list({ limit: 20, toolkit: "google", }); const tools = toZodToolSet({ tools: googleToolkit.items, client: arcade, userId: "", }) const emails = await tools.Google_ListEmails.execute({ limit: 10, }); ``` #### 3\. Convert a single tool [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#3-convert-a-single-tool) When you only need to work with a specific tool, use this method to convert just that tool to a Zod schema: ```nextra-code import { createZodTool } from "@arcadeai/arcadejs/lib" const listEmails = await arcade.tools.get("Google_ListEmails"); const listEmailsTool = createZodTool({ tool: listEmails, client: arcade, userId: "", }); const emails = await listEmailsTool.execute({ limit: 10, }); ``` ### Handle Authorization [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#handle-authorization) When working with tools that require user authorization (like Gmail, GitHub, Slack, etc.), Arcade provides two approaches to handle the authorization flow when using Zod-converted tools: #### Option 1: Manual handling [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#option-1-manual-handling) When you convert Arcade tools to Zod without adding an `executeFactory`, Arcade will try to run tools directly. For tools that need permission (like Google or Slack), you’ll see a `PermissionDeniedError` if the user hasn’t given access yet. This approach gives you complete control over the authorization flow, making it perfect for custom UI implementations or complex workflows. You’ll have full flexibility to design your own user experience, but you’ll need to handle authorization flows and error states manually in your code. ```nextra-code import { PermissionDeniedError } from "@arcadeai/arcadejs" const tools = toZodToolSet({ tools: googleToolkit.items, client: arcade, userId: "", }) try { const result = await tools.Google_ListEmails.execute({ limit: 10, }); console.log(result); } catch (error) { if (error instanceof PermissionDeniedError) { // You can use the `arcade.tools.authorize` method to get an authorization URL for the user const authorizationResponse = await arcade.tools.authorize({ tool_name: "Google.ListEmails", user_id: "", }); console.log(authorizationResponse.url); } else { console.error("Error executing tool:", error); } } ``` #### Option 2: Execute and authorize tool [Permalink for this section](https://docs.arcade.dev/home/use-tools/get-tool-definitions\#option-2-execute-and-authorize-tool) Arcade offers a more convenient way to handle tool execution and initial authorization steps. When converting tools to Zod, you can add the `executeOrAuthorizeZodTool` helper to the `executeFactory`. With this helper, your code no longer needs to catch a `PermissionDeniedError` for tools requiring permissions (as shown in Option 1). Instead, if the user hasn’t yet granted access, the `execute` method will return an `ToolAuthorizationResponse` object that contains the authorization URL. This approach simplifies your code by: 1. Attempting to execute the tool. 2. If permissions are missing, it returns an object containing the authorization URL. This eliminates the need for both a `try...catch` block for `PermissionDeniedError` and a separate call (like `arcade.tools.authorize`) just to retrieve this URL. 3. If the tool is already authorized, it executes directly. Arcade remembers user authorizations, so once a user approves access, subsequent calls using this helper will execute the tool without prompting for authorization again. While this helper streamlines obtaining the authorization URL, you are still responsible for presenting this URL to the user. It’s particularly useful for straightforward implementations where you want to reduce boilerplate. ```nextra-code import { executeOrAuthorizeZodTool } from "@arcadeai/arcadejs" const tools = toZodToolSet({ tools: googleToolkit.items, client: arcade, userId: "", executeFactory: executeOrAuthorizeZodTool, // Automatically handles tool authorization flows, including generating auth URLs }); const result = await tools.Google_ListEmails.execute({ limit: 10, }); if ("authorization_required" in result && result.authorization_required) { console.log( `Please visit ${result.authorization_response.url} to authorize the tool`, ); } else { console.log(result); } ``` [Introduction](https://docs.arcade.dev/home/use-tools/tools-overview "Introduction") [How Arcade Helps](https://docs.arcade.dev/home/auth/how-arcade-helps "How Arcade Helps") ## Evaluate Tool Effectiveness [Home](https://docs.arcade.dev/home "Home") Evaluate toolsWhy evaluate tools? # Why evaluate tools? When deploying language models with tool-calling capabilities in production environments, it’s essential to ensure their effectiveness and reliability. This evaluation process goes beyond traditional testing and focuses on two key aspects: 1. **Tool Utilization**: Assessing how efficiently the language model uses the available tools. 2. **Intent Understanding**: Evaluating the language model’s ability to comprehend user intents and select the appropriate tools to fulfill those intents. Arcade’s Evaluation Framework provides a comprehensive approach to assess and validate the tool-calling capabilities of language models, ensuring they meet the high standards required for real-world applications. [iframe](https://www.youtube.com/embed/EJCpZclFzdg?si=mT6y94rkJ5I5mQNp) ## Why Evaluate Tool Calling by Task? [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#why-evaluate-tool-calling-by-task) Language models augmented with tool-use capabilities can perform complex tasks by invoking external tools or APIs. However, without proper evaluation, these models might: - **Misinterpret user intents**, leading to incorrect tool selection. - **Provide incorrect arguments** to tools, causing failures or undesired outcomes. - **Fail to execute the necessary sequence of tool calls**, especially in tasks requiring multiple steps. Evaluating tool calling by task ensures that the language model can handle specific scenarios reliably, providing confidence in its performance in production settings. ## Evaluation Scoring [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#evaluation-scoring) Scoring in the evaluation framework is based on comparing the model’s actual tool calls with the expected ones for each evaluation case. The total score for a case depends on: 1. **Tool Selection**: Whether the model selected the correct tools for the task. 2. **Tool Call Arguments**: The correctness of the arguments provided to the tools, evaluated by critics. 3. **Evaluation Rubric**: Each aspect of the evaluation is weighted according to the rubric, affecting its impact on the final score. The evaluation result includes: - **Score**: A normalized value between 0.0 and 1.0. - **Result**: - _Passed_: Score is above the fail threshold. - _Failed_: Score is below the fail threshold. - _Warned_: Score is between the warning and fail thresholds. ## Critics: Types and Usage [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#critics-types-and-usage) Critics are essential for evaluating the correctness of tool call arguments. Different types of critics serve various evaluation needs: ### BinaryCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#binarycritic) `BinaryCritic` s check for exact matches between expected and actual values after casting. - **Use Case**: When exact values are required (e.g., specific numeric parameters). - **Example**: Ensuring the model provides the exact user ID in a function call. ### NumericCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#numericcritic) `NumericCritic` evaluates numeric values within a specified range, allowing for acceptable deviations. - **Use Case**: When values can be approximate but should be within a certain threshold. - **Example**: Accepting approximate results in mathematical computations due to floating-point precision. ### SimilarityCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#similaritycritic) `SimilarityCritic` measures the similarity between expected and actual string values using metrics like cosine similarity. - **Use Case**: When the exact wording isn’t critical, but the content should be similar. - **Example**: Evaluating if the message content in a communication tool is similar to the expected message. ### DatetimeCritic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#datetimecritic) `DatetimeCritic` evaluates the closeness of datetime values within a specified tolerance. - **Use Case**: When datetime values should be within a certain range of the expected time. - **Example**: Verifying if a scheduled event time is close enough to the intended time. ### Choosing the Right Critic [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#choosing-the-right-critic) - **Exact Matches Needed**: Use **BinaryCritic** for strict equality. - **Numeric Ranges**: Use **NumericCritic** when a tolerance is acceptable. - **Textual Similarity**: Use **SimilarityCritic** for comparing messages or descriptions. - **Datetime Tolerance**: Use **DatetimeCritic** when a tolerance is acceptable for datetime comparisons. Critics are defined with fields such as `critic_field`, `weight`, and parameters specific to their types (e.g., `similarity_threshold` for `SimilarityCritic`). ## Rubrics and Setting Thresholds [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#rubrics-and-setting-thresholds) An **EvalRubric** defines the evaluation criteria and thresholds for determining pass/fail outcomes. Key components include: - **Fail Threshold**: The minimum score required to pass the evaluation. - **Warn Threshold**: The score threshold for issuing a warning. - **Weights**: Assigns importance to different aspects of the evaluation (e.g., tool selection, argument correctness). ### Setting Up a Rubric [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#setting-up-a-rubric) - **Define Fail and Warn Thresholds**: Choose values between 0.0 and 1.0 to represent acceptable performance levels. - **Assign Weights**: Allocate weights to tool selection and critics to reflect their importance in the overall evaluation. - **Configure Failure Conditions**: Set flags like `fail_on_tool_selection` to enforce strict criteria. ### Example Rubric Configuration: [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#example-rubric-configuration) A rubric that requires a score of at least 0.85 to pass and issues a warning if the score is between 0.85 and 0.95: - Fail Threshold: 0.85 - Warn Threshold: 0.95 - Fail on Tool Selection: True - Tool Selection Weight: 1.0 ```nextra-code rubric = EvalRubric( fail_threshold=0.85, warn_threshold=0.95, fail_on_tool_selection=True, tool_selection_weight=1.0, ) ``` ## Building an Evaluation Suite [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#building-an-evaluation-suite) An **EvalSuite** orchestrates the running of multiple evaluation cases. Here’s how to build one: 1. **Initialize EvalSuite**: Provide a name, system message, tool catalog, and rubric. 2. **Add Evaluation Cases**: Use `add_case` or `extend_case` to include various scenarios. 3. **Specify Expected Tool Calls**: Define the tools and arguments expected for each case. 4. **Assign Critics**: Attach critics relevant to each case to evaluate specific arguments. 5. **Run the Suite**: Execute the suite using the Arcade CLI to collect results. ### Example: Math Tools Evaluation Suite [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#example-math-tools-evaluation-suite) An evaluation suite for math tools might include cases such as: - **Adding Two Large Numbers**: - **User Message**: “Add 12345 and 987654321” - **Expected Tool Call**: `add(a=12345, b=987654321)` - **Critics**: - `BinaryCritic` for arguments `a` and `b` - **Calculating Square Roots**: - **User Message**: “What is the square root of 3224990521?” - **Expected Tool Call**: `sqrt(a=3224990521)` - **Critics**: - `BinaryCritic` for argument `a` ### Example: Slack Messaging Tools Evaluation Suite [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools\#example-slack-messaging-tools-evaluation-suite) An evaluation suite for Slack messaging tools might include cases such as: - **Sending a Direct Message**: - **User Message**: “Send a direct message to johndoe saying ‘Hello, can we meet at 3 PM?’” - **Expected Tool Call**: `send_dm_to_user(user_name='johndoe', message='Hello, can we meet at 3 PM?')` - **Critics**: - `BinaryCritic` for `user_name` - `SimilarityCritic` for `message` - **Posting a Message to a Channel**: - **User Message**: “Post ‘The new feature is now live!’ in the #announcements channel” - **Expected Tool Call**: `send_message_to_channel(channel_name='announcements', message='The new feature is now live!')` - **Critics**: - `BinaryCritic` for `channel_name` - `SimilarityCritic` for `message` [Retry tools with improved prompt](https://docs.arcade.dev/home/build-tools/retry-tools-with-improved-prompt "Retry tools with improved prompt") [Create an evaluation suite](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite "Create an evaluation suite") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Code Sandbox [Integrations](https://docs.arcade.dev/toolkits "Integrations") Developer ToolsCode Sandbox # Code Sandbox **Description:** Enable agents to run code in a sandboxed environment. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/code_sandbox) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_code_sandbox)](https://pypi.org/project/arcade_code_sandbox/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_code_sandbox)](https://pypi.org/project/arcade_code_sandbox/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_code_sandbox)](https://pypi.org/project/arcade_code_sandbox/)[![Downloads](https://img.shields.io/pypi/dm/arcade_code_sandbox)](https://pypi.org/project/arcade_code_sandbox/) The Arcade Code Sandbox toolkit provides a pre-built set of tools for running code in a sandboxed environment. These tools make it easy to build agents and AI apps that can: - Run code in a sandboxed environment - Create a static matplotlib chart ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/development/code-sandbox\#available-tools) These tools are currently available in the Arcade Code Sandbox toolkit. | Tool Name | Description | | --- | --- | | CodeSandbox.RunCode | Run code in a sandboxed environment. | | CodeSandbox.CreateStaticMatplotlibChart | Create a static matplotlib chart. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## CodeSandbox.RunCode [Permalink for this section](https://docs.arcade.dev/toolkits/development/code-sandbox\#codesandboxruncode) See Example > Run code in a sandbox and return the output. **Auth:** - **Environment Variables Required:** - `E2B_API_KEY`: Your API key for authentication. **Parameters** - **`code`** _(string, required)_ The code to run. - **`language`** _(string, optional)_ The language of the code. Valid values are ‘python’, ‘js’, ‘r’, ‘java’, ‘bash’. Defaults to ‘python’. * * * ## CodeSandbox.CreateStaticMatplotlibChart [Permalink for this section](https://docs.arcade.dev/toolkits/development/code-sandbox\#codesandboxcreatestaticmatplotlibchart) See Example > Run the provided Python code to generate a static matplotlib chart. The resulting chart is returned as a base64 encoded image. **Auth:** - **Environment Variables Required:** - `E2B_API_KEY`: Your API key for authentication. **Parameters** - **`code`** _(string, required)_ The Python code to run. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/development/code-sandbox\#auth) The Arcade Code Sandbox toolkit uses [E2B](https://e2b.dev/) to run code in a sandboxed environment. **Global Environment Variables:** - `E2B_API_KEY`: Your [E2B](https://e2b.dev/) API key. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade-code-sandbox\\ ```](https://docs.arcade.dev/home/hosting-overview) [Twitch](https://docs.arcade.dev/toolkits/entertainment/twitch "Twitch") [GitHub](https://docs.arcade.dev/toolkits/development/github/github "GitHub") ## Outlook Mail Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Microsoft](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar "Microsoft") Outlook Mail # Outlook Mail **Description:** Enable agents to read, write, and send emails with Outlook. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/microsoft) **Auth:** User authorizationvia the [Microsoft auth provider](https://docs.arcade.dev/home/auth-providers/microsoft) [![PyPI Version](https://img.shields.io/pypi/v/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/)[![Downloads](https://img.shields.io/pypi/dm/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/) The Arcade Outlook Mail toolkit provides pre-built tools for working with emails using the Outlook API. Use these tools to: - Read emails - Write emails - Send emails ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#available-tools) These tools are currently available in the Arcade Sheets toolkit. | Tool Name | Description | | --- | --- | | Microsoft.CreateDraftEmail | Compose a new draft email in Outlook | | Microsoft.UpdateDraftEmail | Update an existing draft email in Outlook | | Microsoft.SendDraftEmail | Send an existing draft email in Outlook | | Microsoft.CreateAndSendEmail | Create and immediately send a new email in Outlook to the specified recipients | | Microsoft.ReplyToEmail | Reply only to the sender of an existing email in Outlook. | | Microsoft.ReplyAllToEmail | Reply to all recipients of an existing email in Outlook. | | Microsoft.ListEmails | List emails in the user's mailbox across all folders. | | Microsoft.ListEmailsInFolder | List the user's emails in the specified folder. | | Microsoft.ListEmailsByProperty | List emails in the user's mailbox across all folders filtering by a property. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Microsoft.CreateDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftcreatedraftemail) Compose a new draft email in Outlook. **Parameters** - **`subject`** _(string, required)_: The subject of the email to create. - **`body`** _(string, required)_: The body of the email to create. - **`to_recipients`** _(list of strings, required)_: The email addresses that will be the recipients of the draft email. - **`cc_recipients`** _(list of strings, optional)_: The email addresses that will be the CC recipients of the draft email. - **`bcc_recipients`** _(list of strings, optional)_: The email addresses that will be the BCC recipients of the draft email. See Example > * * * ## Microsoft.UpdateDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftupdatedraftemail) Update an existing draft email in Outlook. This tool overwrites the subject and body of a draft email (if provided), and modifies its recipient lists by selectively adding or removing email addresses. This tool can update any un-sent email: - draft - reply-draft - reply-all draft - forward draft **Parameters** - **`message_id`** _(string, required)_: The ID of the draft email to update. - **`subject`** _(string, optional)_: The new subject of the draft email. If provided, the existing subject will be overwritten. - **`body`** _(string, optional)_: The new body of the draft email. If provided, the existing body will be overwritten - **`to_add`** _(list of strings, optional)_: Email addresses to add as ‘To’ recipients. - **`to_remove`** _(list of strings, optional)_: Email addresses to remove from the current ‘To’ recipients. - **`cc_add`** _(list of strings, optional)_: Email addresses to add as ‘CC’ recipients. - **`cc_remove`** _(list of strings, optional)_: Email addresses to remove from the current ‘CC’ recipients. - **`bcc_add`** _(list of strings, optional)_: Email addresses to add as ‘BCC’ recipients. - **`bcc_remove`** _(list of strings, optional)_: Email addresses to remove from the current ‘BCC’ recipients. See Example > * * * ## Microsoft.SendDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftsenddraftemail) Send an existing draft email in Outlook This tool can send any un-sent email: - draft - reply-draft - reply-all draft - forward draft **Parameters** - **`message_id`** (string, required): The ID of the draft email to send See Example > * * * ## Microsoft.CreateAndSendEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftcreateandsendemail) Create and immediately send a new email in Outlook to the specified recipients **Parameters** - **`subject`** (string, required): The subject of the email to create - **`body`** (string, required): The body of the email to create - **`to_recipients`** (list\[str\], required): The email addresses that will be the recipients of the email - **`cc_recipients`** (list\[str\], optional): The email addresses that will be the CC recipients of the email. - **`bcc_recipients`** (list\[str\], optional): The email addresses that will be the BCC recipients of the email. See Example > * * * ## Microsoft.ReplyToEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftreplytoemail) Reply to an existing email in Outlook. Use this tool to reply to the sender or all recipients of the email. Specify the reply\_type to determine the scope of the reply. **Parameters** - **`message_id`** (string, required): The ID of the email to reply to - **`body`** (string, required): The body of the reply to the email - **`reply_type`** (enum ( [ReplyType](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail#replytype)), required): Specify “reply” to reply only to the sender or “reply\_all” to reply to all recipients. See Example > * * * ## Microsoft.ListEmails [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftlistemails) List emails in the user’s mailbox across all folders. Since this tool lists email across all folders, it may return sent items, drafts, and other items that are not in the inbox. **Parameters** - **`limit`** (int, optional): The number of messages to return. Max is 100. Defaults to 5. - **`pagination_token`** (str, optional): The pagination token to continue a previous request See Example > * * * ## Microsoft.ListEmailsInFolder [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftlistemailsinfolder) List the user’s emails in the specified folder. Exactly one of `well_known_folder_name` or `folder_id` MUST be provided. **Parameters** - **`well_known_folder_name`** (enum ( [WellKnownFolderNames](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail#wellknownfoldernames)), optional): The name of the folder to list emails from. Defaults to None. - **`folder_id`** (str, optional): The ID of the folder to list emails from if the folder is not a well-known folder. Defaults to None. - **`limit`** (int, optional): The number of messages to return. Max is 100. Defaults to 5. - **`pagination_token`** (str, optional): The pagination token to continue a previous request See Example > * * * ## Microsoft.ListEmailsByProperty [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#microsoftlistemailsbyproperty) List emails in the user’s mailbox across all folders filtering by a property. **Parameters** - **`property`** (enum ( [EmailFilterProperty](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail#emailfilterproperty)), required): The property to filter the emails by. - **`operator`** (enum ( [FilterOperator](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail#filteroperator)), required): The operator to use for the filter - **`value`** (string, required): The value to filter the emails by. - **`limit`** (int, optional): The number of messages to return. Max is 100. Defaults to 5. - **`pagination_token`** (str, optional): The pagination token to continue a previous request See Example > * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#auth) The Arcade Outlook Mail toolkit uses the [Microsoft auth provider](https://docs.arcade.dev/home/auth-providers/microsoft) to connect to users’ Microsoft accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Microsoft auth provider](https://docs.arcade.dev/home/auth-providers/microsoft#configuring-microsoft-auth) with your own Microsoft app credentials. * * * ## Reference [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#reference) ### WellKnownFolderNames [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#wellknownfoldernames) Well-known folder names that are created for users by default. Instead of using the ID of these folders, you can use the well-known folder names. - **`DELETED_ITEMS`** _(string: “deleteditems”)_ - **`DRAFTS`** _(string: “drafts”)_ - **`INBOX`** _(string: “inbox”)_ - **`JUNK_EMAIL`** _(string: “junkemail”)_ - **`SENT_ITEMS`** _(string: “sentitems”)_ - **`STARRED`** _(string: “starred”)_ - **`TODO`** _(string: “tasks”)_ ### ReplyType [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#replytype) The type of reply to send to an email. - **`REPLY`** _(string: “reply”)_ - **`REPLY_ALL`** _(string: “reply\_all”)_ ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_microsoft\\ ```](https://docs.arcade.dev/home/hosting-overview) ### EmailFilterProperty [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#emailfilterproperty) The property to filter the emails by. - **`SUBJECT`** _(string: “subject”)_ - **`CONVERSATION_ID`** _(string: “conversationId”)_ - **`RECEIVED_DATE_TIME`** _(string: “receivedDateTime”)_ - **`SENDER`** _(string: “sender/emailAddress/address”)_ ### FilterOperator [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail\#filteroperator) The operator to use for the filter. - **`EQUAL`** _(string: “eq”)_ - **`NOT_EQUAL`** _(string: “ne”)_ - **`GREATER_THAN`** _(string: “gt”)_ - **`GREATER_THAN_OR_EQUAL_TO`** _(string: “ge”)_ - **`LESS_THAN`** _(string: “lt”)_ - **`LESS_THAN_OR_EQUAL_TO`** _(string: “le”)_ - **`STARTS_WITH`** _(string: “startsWith”)_ - **`ENDS_WITH`** _(string: “endsWith”)_ - **`CONTAINS`** _(string: “contains”)_ [Outlook Calendar](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar "Outlook Calendar") [Notion](https://docs.arcade.dev/toolkits/productivity/notion "Notion") ## Hybrid Worker Deployment [Home](https://docs.arcade.dev/home "Home") Hybrid DeploymentHybrid Worker # Hybrid Worker A hybrid deployment allows you to execute tools in your own environment while still leveraging Arcade’s cloud Engine infrastructure. This gives you the flexibility to access private resources, maintain data security, and customize your worker environment while leveraging Arcade’s Engine and management capabilities. ## How hybrid workers work [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#how-hybrid-workers-work) The hybrid worker model uses a bidirectional connection between your local environment and Arcade’s cloud engine: 1. You run the Arcade worker in your environment (on-premises, private cloud, etc.) 2. Your worker is exposed to Arcade’s cloud engine using a public URL 3. The Arcade cloud engine routes tool calls to your worker 4. Your worker processes the requests and returns responses to the engine ## Benefits of hybrid workers [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#benefits-of-hybrid-workers) - **Resource access**: Access private databases, APIs, or other resources not accessible from Arcade’s cloud - **Data control**: Keep sensitive data within your environment while still using Arcade’s capabilities - **Custom environments**: Use specific dependencies or configurations required by your tools - **Compliance**: Meet regulatory requirements by keeping data processing within your infrastructure ## Setting up a hybrid worker [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#setting-up-a-hybrid-worker) ### Setup your toolkits [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#setup-your-toolkits) Follow the [Creating a Toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit) guide to create your toolkits. Alternatively, you can install an Arcade Toolkit: ```nextra-code pip install arcade-math ``` ### Start your local worker [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#start-your-local-worker) Run your Arcade worker locally with a secret that you generate in some secure way: ```nextra-code export ARCADE_WORKER_SECRET=your-secret arcade serve ``` Verify your worker is running by visiting [http://localhost:8002/worker/health](http://localhost:8002/worker/health). ### Create a public URL [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#create-a-public-url) To allow the Arcade cloud engine to connect to your locally running worker, you need a public URL. Here are a few options: ngrokCloudflareTailscale ```nextra-code ngrok http 8002 ``` ```nextra-code cloudflared tunnel --url http://localhost:8002 ``` ```nextra-code tailscale funnel 8002 ``` ### Register your worker in Arcade [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#register-your-worker-in-arcade) 1. Navigate to the [Workers](https://api.arcade.dev/dashboard/workers) page in your Arcade dashboard 2. Click **Add Worker** 3. Fill in the form: - **ID**: Choose a unique identifier (e.g., `my-hybrid-worker`) - **Worker Type**: Select `Arcade` - **URL**: Enter your public URL from Step 3 - **Secret**: Enter the secret for your worker (or use `dev` for testing) - **Timeout** and **Retry**: Configure as needed for your use case 4. Click **Create** ### Test the connection to your worker [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#test-the-connection-to-your-worker) You can now test your worker by making requests through the Arcade API or using the Playground: 1. Go to the [Playground](https://api.arcade.dev/dashboard/playground) 2. Select a tool from your toolkit and execute it 3. Verify that the response is correct and you see request logs in your worker ## Best practices [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#best-practices) - **Persistent URLs**: For production use, set up a persistent public URL rather than ephemeral ones - **TLS**: Use a TLS-enabled URL for production use - **Security**: Use strong secrets for worker authentication - **Monitoring**: Set up monitoring for your hybrid workers to ensure availability - **Scaling**: For high-load scenarios, consider running multiple workers behind a load balancer ## Troubleshooting [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#troubleshooting) - **Connection issues**: Ensure your public URL is accessible and that your local worker is running - **Authentication failures**: Verify that the worker secret matches what’s configured in the Arcade dashboard - **Timeout errors**: If your worker takes too long to respond, increase the timeout value in the worker configuration ## Next steps [Permalink for this section](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker\#next-steps) - [Create custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) for your hybrid worker - [Set up authentication](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth) for secure access to resources - [Configure secrets](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets) for your worker [Overview](https://docs.arcade.dev/home/hosting-overview "Overview") [Overview](https://docs.arcade.dev/home/local-deployment/install/overview "Overview") ## Google Contacts Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Google](https://docs.arcade.dev/toolkits/productivity/google/calendar "Google") Contacts # Calendar **Description:** Enable agents to interact with Google Contacts. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/google) **Auth:** User authorizationvia the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) [![PyPI Version](https://img.shields.io/pypi/v/arcade_google)](https://pypi.org/project/arcade_google/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_google)](https://pypi.org/project/arcade_google/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_google)](https://pypi.org/project/arcade_google/)[![Downloads](https://img.shields.io/pypi/dm/arcade_google)](https://pypi.org/project/arcade_google/) The Arcade Contacts toolkit provides a pre-built set of tools for interacting with Google Contacts. These tools make it easy to build agents and AI apps that can: - Create new contacts - Search for contacts by name or email ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/contacts\#available-tools) These tools are currently available in the Arcade Contacts toolkit. | Tool Name | Description | | --- | --- | | Google.SearchContactsByEmail | Search the user's contacts in Google Contacts by email address. | | Google.SearchContactsByName | Search the user's contacts in Google Contacts by name. | | Google.CreateContact | Create a new contact record in Google Contacts. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Google.SearchContactsByEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/contacts\#googlesearchcontactsbyemail) Search the user’s contacts in Google Contacts by email address. See Example > **Parameters** - **`email`** _(string, required)_: The email address to search for. - **`limit`** _(integer, optional)_: The maximum number of contacts to return (30 is the max allowed by the Google API). * * * ## Google.SearchContactsByName [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/contacts\#googlesearchcontactsbyname) Search the user’s contacts in Google Contacts by name. See Example > **Parameters** - **`name`** _(string, required)_: The full name to search for. - **`limit`** _(integer, optional)_: The maximum number of contacts to return (30 is the max allowed by the Google API). * * * ## Google.CreateContact [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/contacts\#googlecreatecontact) Create a new contact record in Google Contacts. See Example > **Parameters** - **`given_name`** _(string, required)_: The given name of the contact. - **`family_name`** _(string, optional)_: The optional family name of the contact. - **`email`** _(string, optional)_: The optional email address of the contact. * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/contacts\#auth) The Arcade Contacts toolkit uses the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) to connect to users’ Google accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Google auth provider](https://docs.arcade.dev/home/auth-providers/google#configuring-google-auth) with your own Google app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_google\\ ```](https://docs.arcade.dev/home/hosting-overview) [Calendar](https://docs.arcade.dev/toolkits/productivity/google/calendar "Calendar") [Docs](https://docs.arcade.dev/toolkits/productivity/google/docs "Docs") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## User Authorization Guide [Home](https://docs.arcade.dev/home "Home") [OpenAI Agents](https://docs.arcade.dev/home/oai-agents/overview "OpenAI Agents") Managing user authorization ## User authorization with OpenAI Agents [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#user-authorization-with-openai-agents) In this guide, you will learn how to handle user authorization for Arcade tools in your OpenAI Agents application. When a tool requires authorization, the agent will raise an `AuthorizationError` with a URL for the user to visit and grant permissions. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Install the required packages [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#install-the-required-packages) Set up your environment with the following installations: PythonJavaScript ```nextra-code pip install agents-arcade arcadepy ``` ```nextra-code npm install @openai/agents @arcadeai/agents-arcade ``` ### Configure your Arcade environment [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#configure-your-arcade-environment) Make sure you have set your Arcade API key in the environment, or assign it directly in the code: > Need an Arcade API key? Visit the [Get an API key](https://docs.arcade.dev/home/api-keys) page to create one. PythonJavaScript ```nextra-code import os from arcadepy import AsyncArcade from agents import Agent, Runner from agents_arcade import get_arcade_tools from agents_arcade.errors import AuthorizationError # Set your API key os.environ["ARCADE_API_KEY"] = "YOUR_ARCADE_API_KEY" # Initialize the Arcade client client = AsyncArcade() ``` Add your API key to your environment variables: ```nextra-code # In your .env file ARCADE_API_KEY=YOUR_ARCADE_API_KEY ``` ```nextra-code import Arcade from '@arcadeai/arcadejs'; import { isAuthorizationRequiredError, toZod } from "@arcadeai/arcadejs/lib"; import { Agent, run, tool } from '@openai/agents'; const client = new Arcade(); ``` ### Fetch Arcade tools [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#fetch-arcade-tools) Get the tools you need for your agent. In this example, we’ll use GitHub tools: PythonJavaScript ```nextra-code # Get GitHub tools for this example tools = await get_arcade_tools(client, toolkits=["github"]) # Create an agent with GitHub tools github_agent = Agent( name="GitHub agent", instructions="You are a helpful assistant that can assist with GitHub API calls.", model="gpt-4o-mini", tools=tools, ) ``` ```nextra-code const githubToolkit = await client.tools.list({ toolkit: "github", limit: 30 }); const arcadeTools = toZod({ tools: githubToolkit.items, client, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) }) ``` ### Handle authorization errors [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#handle-authorization-errors) PythonJavaScript When a user needs to authorize access to a tool, the agent will raise an `AuthorizationError`. You can handle it like this: ```nextra-code try: result = await Runner.run( starting_agent=github_agent, input="Star the arcadeai/arcade-ai repo", # Pass a unique user_id for authentication context={"user_id": "user@example.com"}, ) print("Final output:\n\n", result.final_output) except AuthorizationError as e: # Display the authorization URL to the user print(f"Please Login to GitHub: {e}") # The error contains the authorization URL that the user should visit ``` Choose how to handle authorization errors based on your needs: **Default behavior (throws errors):** ```nextra-code const arcadeTools = toZod({ tools: githubToolkit.items, client, userId: "", // Replace with your user ID }); ``` Use this when you want to handle authorization flow yourself with custom logic. **Auto-handle authorization (recommended):** ```nextra-code import { executeOrAuthorizeZodTool } from "@arcadeai/arcadejs/lib"; const arcadeTools = toZod({ tools: githubToolkit.items, client, userId: "", // Replace with your user ID executeFactory: executeOrAuthorizeZodTool, }); ``` This automatically returns authorization URLs instead of throwing errors. **Custom error handling:** ```nextra-code import { isAuthorizationRequiredError } from "@arcadeai/arcadejs/lib"; const tools = arcadeTools.map((arcadeTool) => { return tool({ ...arcadeTool, errorFunction: async (_, error) => { if (error instanceof Error && isAuthorizationRequiredError(error)) { const response = await client.tools.authorize({ tool_name: arcadeTool.name, user_id: "", }); return `Please login to Google: ${response.url}`; } return "Error executing tool" } }) }); ``` ### Wait for authorization completion [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#wait-for-authorization-completion) You can also wait for the user to complete the authorization before continuing: PythonJavaScript ```nextra-code from arcadepy import AsyncArcade import asyncio client = AsyncArcade() async def handle_auth_flow(auth_id): # Display a message to the user print("Please visit the authorization URL in your browser") # Wait for the user to authenticate await client.auth.wait_for_completion(auth_id) # Check if authorization was successful if await is_authorized(auth_id): print("Authorization successful! You can now use the tool.") return True else: print("Authorization failed or timed out.") return False # In your main function try: # Run agent code # ... except AuthorizationError as e: auth_id = e.auth_id if await handle_auth_flow(auth_id): # Try running the agent again result = await Runner.run( starting_agent=github_agent, input="Star the arcadeai/arcade-ai repo", context={"user_id": "user@example.com"}, ) print("Final output:\n\n", result.final_output) ``` To wait for authorization completion, follow this approach: 1. Throw the error to the agent 2. Catch and handle the error while waiting for completion ```nextra-code const tools = arcadeTools.map((arcadeTool) => { return tool({ ...arcadeTool, errorFunction: (_, error) => { throw error } // Throw the error to the agent for handling }) }); while (true) { try { const result = await run(googleAgent, "What are my latest emails?"); console.log(result.finalOutput); } catch (error) { // Catch the authorization error and wait for completion if (error instanceof Error && isAuthorizationRequiredError(error)) { const response = await client.tools.authorize({ tool_name: "Google_ListEmails", user_id: "", }); if (response.status !== "completed") { console.log(`Please complete the authorization challenge in your browser: ${response.url}`); } // Wait for the authorization to complete await client.auth.waitForCompletion(response); console.log("Authorization completed, retrying..."); } } } ``` ### Complete example [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#complete-example) Here’s a full example that demonstrates the authorization flow with waiting for authentication: PythonJavaScript ```nextra-code from arcadepy.auth import wait_for_authorization_completion import time from agents import Agent, Runner from arcadepy import AsyncArcade from agents_arcade import get_arcade_tools from agents_arcade.errors import AuthorizationError async def main(): client = AsyncArcade() # Use the "github" toolkit for this example tools = await get_arcade_tools(client, toolkits=["github"]) github_agent = Agent( name="GitHub agent", instructions="You are a helpful assistant that can assist with GitHub API calls.", model="gpt-4o-mini", tools=tools, ) user_id = "user@example.com" # Make sure to use a unique user ID while True: try: result = await Runner.run( starting_agent=github_agent, input="Star the arcadeai/arcade-ai repo", # Pass the user_id for auth context={"user_id": user_id}, ) print("Final output:\n\n", result.final_output) break # Exit the loop if successful except AuthorizationError as e: auth_url = str(e) print(f"{auth_url}. Please authenticate to continue.") # Wait for the user to authenticate await client.auth.wait_for_completion(e.result.id) if __name__ == "__main__": import asyncio asyncio.run(main()) ``` Check out the complete working example in our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/tree/main/examples/openai-agents-ts/src/waitForCompletion.ts). ```nextra-code import Arcade from '@arcadeai/arcadejs'; import { isAuthorizationRequiredError, toZod } from "@arcadeai/arcadejs/lib"; import { Agent, run, tool } from '@openai/agents'; async function main() { // 1) Initialize Arcade client const client = new Arcade(); // 2) Fetch Google toolkit from Arcade and prepare tools for OpenAI Agents const googleToolkit = await client.tools.list({ toolkit: "google", limit: 30 }); const tools = toZod({ tools: googleToolkit.items, client, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) }).map(tool); // 3) Create a new agent with the Google toolkit const googleAgent = new Agent({ name: "Google agent", instructions: "You are a helpful assistant that can assist with Google API calls.", model: "gpt-4o-mini", tools }); // 4) Run the agent, if authorization is required, wait for it to complete and retry while (true) { try { const result = await run(googleAgent, "What are my latest emails?"); console.log(result.finalOutput); break; // Exit the loop if the result is successful } catch (error) { if (error instanceof Error && isAuthorizationRequiredError(error)) { const response = await client.tools.authorize({ tool_name: "Google_ListEmails", user_id: "", }); if (response.status !== "completed") { console.log(`Please complete the authorization challenge in your browser: ${response.url}`); } // Wait for the authorization to complete await client.auth.waitForCompletion(response); console.log("Authorization completed, retrying..."); } } } } main(); ``` This example handles the authentication flow by: 1. Attempting to run the agent 2. Catching any AuthorizationError 3. Open the authentication URL in a browser 4. Waiting for the user to complete authentication 5. Retrying the operation after a wait period ## Authentication persistence [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#authentication-persistence) Once a user authorizes an integration, Arcade will remember the authorization for that specific user\_id and toolkit. You don’t need to re-authorize each time you run the agent. Key points to remember: - Always use a consistent and unique `user_id` for each user - Store the `user_id` securely in your application - Different toolkits require separate authorization flows - Authorization tokens are managed by Arcade, not your application ## Next steps [Permalink for this section](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts\#next-steps) - Build a user interface to handle authorization flows smoothly - Explore other Arcade toolkits like Google, LinkedIn, or X - Create multi-step workflows with multiple tools and authorizations - Learn to build your own custom tools with the Arcade Tool SDK By handling Arcade’s authorization flow correctly, you can build AI-driven applications that securely integrate with various services while respecting user permissions. Have fun exploring Arcade! [Using Arcade tools](https://docs.arcade.dev/home/oai-agents/use-arcade-tools "Using Arcade tools") [Using Arcade tools](https://docs.arcade.dev/home/vercelai/use-arcade-tools "Using Arcade tools") ## Using Arcade Tools [Home](https://docs.arcade.dev/home "Home") CrewAIUsing Arcade tools ## Use CrewAI with Arcade [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#use-crewai-with-arcade) In this guide, we will explore how to integrate Arcade tools into your CrewAI application. Follow the step-by-step instructions below. If a tool requires authorization, an authorization URL will appear in the console, waiting for your approval. This process ensures that only the tools you choose to authorize are executed. To tailor the tool authorization flow to meet your application’s specific needs, check out the [Custom Auth Flow with CrewAI](https://docs.arcade.dev/home/crewai/custom-auth-flow) guide. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Set up your environment [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#set-up-your-environment) Install the required package, and ensure your environment variables are set with your Arcade and OpenAI API keys: ```nextra-code pip install crewai-arcade ``` ### Configure API keys [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#configure-api-keys) Provide your Arcade and OpenAI API keys. You can store them in environment variables like so: ```nextra-code export ARCADE_API_KEY="your_arcade_api_key" export OPENAI_API_KEY="your_openai_api_key" ``` ### Get Arcade tools [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#get-arcade-tools) Use the `ArcadeToolManager` to initialize, add, and get Arcade tools: ```nextra-code from crewai_arcade import ArcadeToolManager manager = ArcadeToolManager(default_user_id="user@example.com") """ Retrieves the provided tools and/or toolkits as CrewAI StructuredTools. """ tools = manager.get_tools(tools=["Google.ListEmails"], toolkits=["Slack"]) ``` ### Use tools in your CrewAI agent team [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#use-tools-in-your-crewai-agent-team) Create a Crew that uses your tools. When the tool is called, you will be prompted to go visit an authorization page to authorize the tool before it executes. ```nextra-code from crewai import Agent, Crew, Task from crewai.llm import LLM crew_agent = Agent( role="Main Agent", backstory="You are a helpful assistant", goal="Help the user with their requests", tools=tools, allow_delegation=False, verbose=True, llm=LLM(model="gpt-4o"), ) task = Task( description="Get the 5 most recent emails from the user's inbox and summarize them and recommend a response for each.", expected_output="A bulleted list with a one sentence summary of each email and a recommended response to the email.", agent=crew_agent, tools=crew_agent.tools, ) crew = Crew( agents=[crew_agent], tasks=[task], verbose=True, memory=True, ) result = crew.kickoff() print("\n\n\n ------------ Result ------------ \n\n\n") print(result) ``` Click to view a full example ## Tips for selecting tools [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#tips-for-selecting-tools) - **Relevance**: Pick only the tools you need. Avoid using all tools at once. - **Avoid conflicts**: Be mindful of duplicate or overlapping functionality. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/crewai/use-arcade-tools\#next-steps) Now that you have integrated Arcade tools into your CrewAI agent team, you can: - Experiment with different toolkits, such as “Math” or “Search.” - Customize the agent’s prompts for specific tasks. - Customize the tool authorization and execution flow to meet your application’s requirements. [Authorizing existing tools](https://docs.arcade.dev/home/langchain/auth-langchain-tools "Authorizing existing tools") [Custom auth flow](https://docs.arcade.dev/home/crewai/custom-auth-flow "Custom auth flow") ## Microsoft Outlook Calendar [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") MicrosoftOutlook Calendar # Outlook Calendar **Description:** Enable agents to create and list events in Outlook Calendar. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/microsoft) **Auth:** User authorizationvia the [Microsoft auth provider](https://docs.arcade.dev/home/auth-providers/microsoft) [![PyPI Version](https://img.shields.io/pypi/v/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/)[![Downloads](https://img.shields.io/pypi/dm/arcade_microsoft)](https://pypi.org/project/arcade_microsoft/) The Arcade Outlook Calendar toolkit provides pre-built tools for working with calendar events using the Outlook API. Use these tools to: - Create events - List events - Get an event ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar\#available-tools) These tools are currently available in the Arcade Sheets toolkit. | Tool Name | Description | | --- | --- | | Microsoft.CreateEvent | Create an event in the authenticated user's default calendar | | Microsoft.GetEvent | Get an event by its ID from the user's calendar | | Microsoft.ListEventsInTimeRange | ist events in the user's calendar in a specific time range | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Microsoft.CreateEvent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar\#microsoftcreateevent) Create an event in the authenticated user’s default calendar. Ignores timezone offsets provided in the start\_date\_time and end\_date\_time parameters. Instead, uses the user’s default calendar timezone to filter events. If the user has not set a timezone for their calendar, then the timezone will be UTC. **Parameters** - **`subject`** _(string, required)_: The text of the event’s subject (title) line. - **`body`** _(string, required)_: The body of the event. - **`start_date_time`** _(datetime, required)_: The datetime of the event’s start, represented in ISO 8601 format. Timezone offset is ignored. For example, 2025-04-25T13:00:00 - **`end_date_time`** _(datetime, required)_: The datetime of the event’s end, represented in ISO 8601 format. Timezone offset is ignored. For example, 2025-04-25T13:30:00 - **`location`** _(string, optional)_: The location of the event. - **`attendee_emails`** _(list of strings, optional)_: The email addresses of the attendees of the event. Must be valid email addresses e.g., [username@domain.com](mailto:username@domain.com). - **`is_online_meeting`** _(bool, optional)_: Whether the event is an online meeting. Defaults to False See Example > * * * ## Microsoft.GetEvent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar\#microsoftgetevent) Get an event by its ID from the user’s calendar. **Parameters** - **`event_id`** _(string, required)_: The ID of the event to get. See Example > * * * ## Microsoft.ListEventsInTimeRange [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar\#microsoftlisteventsintimerange) List events in the user’s calendar in a specific time range. Ignores timezone offsets provided in the start\_date\_time and end\_date\_time parameters. Instead, uses the user’s default calendar timezone to filter events. If the user has not set a timezone for their calendar, then the timezone will be UTC. **Parameters** - **`start_date_time`** (datetime, required): The start date and time of the time range, represented in ISO 8601 format. Timezone offset is ignored. For example, 2025-04-24T19:00:00 - **`end_date_time`** (datetime, required): The end date and time of the time range, represented in ISO 8601 format. Timezone offset is ignored. For example, 2025-04-24T19:30:00 - **`limit`** (int, optional): The maximum number of events to return. Max 1000. Defaults to 10. See Example > * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar\#auth) The Arcade Outlook Calendar toolkit uses the [Microsoft auth provider](https://docs.arcade.dev/home/auth-providers/microsoft) to connect to users’ Microsoft accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Microsoft auth provider](https://docs.arcade.dev/home/auth-providers/microsoft#configuring-microsoft-auth) with your own Microsoft app credentials. * * * ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_microsoft\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/productivity/jira/reference "Reference") [Outlook Mail](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_mail "Outlook Mail") ## Arcade Obsidian Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") Obsidian # Arcade Obsidian Toolkit The Arcade Obsidian Toolkit is a community contributed toolkit verified by the Arcade team. To learn more about the toolkit, please visit the [Arcade Obsidian GitHub repository](https://github.com/spartee/arcade-obsidian). [Notion](https://docs.arcade.dev/toolkits/productivity/notion "Notion") [Close.io](https://docs.arcade.dev/toolkits/productivity/closeio "Close.io") ## Retryable Tool Error [Home](https://docs.arcade.dev/home "Home") [Build tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Build tools") Retry tools with improved prompt # RetryableToolError in Arcade Sometimes you may want to retry a tool call with additional context to improve the tool call’s input parameters predicted by the model and try again. You can do this by raising a `RetryableToolError` within the tool. ### Understanding RetryableToolError [Permalink for this section](https://docs.arcade.dev/home/build-tools/retry-tools-with-improved-prompt\#understanding-retryabletoolerror) Raising the `RetryableToolError` is useful when you want to retry the tool call and give the model that is generating the tool call’s input parameters additional context to improve the parameters for the next tool call. ### When to Use RetryableToolError [Permalink for this section](https://docs.arcade.dev/home/build-tools/retry-tools-with-improved-prompt\#when-to-use-retryabletoolerror) A RetryableToolError should be raised from within a tool if additional prompt content would likely improve the tool call outcome. ### Example: Sending a Direct Message in Slack [Permalink for this section](https://docs.arcade.dev/home/build-tools/retry-tools-with-improved-prompt\#example-sending-a-direct-message-in-slack) Below is an example of a tool that sends a direct message to a user in Slack: 1. If the specified user is not found, the tool retrieves a list of all valid inputs for the `user_name` parameter. 2. The tool then raises a `RetryableToolError` with the list of valid inputs. 3. This allows the model to generate a valid input for the `user_name` parameter in the next tool call iteration. ```nextra-code from typing import Annotated from slack_sdk import WebClient from arcade_tdk.errors import RetryableToolError from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Slack @tool( requires_auth=Slack( scopes=[\ "chat:write",\ "im:write",\ "users.profile:read",\ "users:read",\ ], ) ) def send_dm_to_user( context: ToolContext, user_name: Annotated[\ str,\ "The Slack username of the person you want to message. Slack usernames are ALWAYS lowercase.",\ ], message: Annotated[str, "The message you want to send"], ) -> Annotated[str, "A confirmation message that the DM was sent"]: """Send a direct message to a user in Slack.""" slackClient = WebClient(token=context.authorization.token) # Step 1: Retrieve the user's Slack ID based on their username userListResponse = slackClient.users_list() user_id = None for user in userListResponse["members"]: if user["name"].lower() == user_name.lower(): user_id = user["id"] break # If the user is not found, raise a RetryableToolError with a # list of all valid inputs for the user_name parameter if not user_id: raise RetryableToolError( "User not found", developer_message=f"User with username '{user_name}' not found.", additional_prompt_content=f"Valid values for user_name input param: {userListResponse}", retry_after_ms=500, ) # Step 2: Retrieve the DM channel ID with the user im_response = slackClient.conversations_open(users=[user_id]) dm_channel_id = im_response["channel"]["id"] # Step 3: Send the DM slackClient.chat_postMessage(channel=dm_channel_id, text=message) return "DM sent successfully" ``` [Handle tool errors](https://docs.arcade.dev/home/build-tools/handle-tool-errors "Handle tool errors") [Why evaluate tools?](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools "Why evaluate tools?") ## Auth Providers Overview [Home](https://docs.arcade.dev/home "Home") Customizing AuthOverview # Auth Providers Auth providers enable users to seamlessly and securely allow Arcade tools to access their data. Arcade has several auth providers available in the Arcade cloud so you don’t have to configure your own. However, using Arcade’s auth providers means that your users will see the Arcade brand (name and logo) on the auth screen and your authentications will share any rate limits from those providers with other Arcade customers. It can be useful to configure your own auth provider for the following reasons: - You want to use your own brand on the auth screen - You want to isolate your rate limits from other Arcade customers - You want to use a provider that Arcade [does not have a built-in integration for](https://docs.arcade.dev/home/auth-providers/oauth2) After adding an auth provider used by an Arcade tool, executing the tool will automatically use your auth provider. Even in the Arcade Cloud, your auth provider will take precedence over the arcade-provided auth provider. Adding multiple providers of the same type, not including the arcade-provided ones, can cause Arcade’s tool authorization to fail, see [Using multiple providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ## Catalog of providers [Permalink for this section](https://docs.arcade.dev/home/auth-providers\#catalog-of-providers) For more information on how to customize your auth provider, select an auth provider from the list below: [![Asana logo](https://docs.arcade.dev/images/icons/asana.svg)\\ \\ **Asana**\\ \\ **Auth** \\ \\ Authorize tools and agents with Asana](https://docs.arcade.dev/home/auth-providers/asana) [![Atlassian logo](https://docs.arcade.dev/images/icons/atlassian.png)\\ \\ **Atlassian**\\ \\ **Auth** \\ \\ Authorize tools and agents with Atlassian](https://docs.arcade.dev/home/auth-providers/atlassian) [![Discord logo](https://docs.arcade.dev/images/icons/discord.png)\\ \\ **Discord**\\ \\ **Auth** \\ \\ Authorize tools and agents with Discord in a user's context](https://docs.arcade.dev/home/auth-providers/discord) [![Dropbox logo](https://docs.arcade.dev/images/icons/dropbox.png)\\ \\ **Dropbox**\\ \\ **Auth** \\ \\ Authorize tools and agents with Dropbox in a user's context](https://docs.arcade.dev/home/auth-providers/dropbox) [![GitHub logo](https://docs.arcade.dev/images/icons/github.png)\\ \\ **GitHub**\\ \\ **Auth** \\ \\ Authorize tools and agents with GitHub, including private repositories](https://docs.arcade.dev/home/auth-providers/github) [![Google logo](https://docs.arcade.dev/images/icons/google.png)\\ \\ **Google**\\ \\ **Auth** \\ \\ Authorize tools and agents with Google: Gmail, Calendar, YouTube, Drive, and more](https://docs.arcade.dev/home/auth-providers/google) [![HubSpot logo](https://docs.arcade.dev/images/icons/hubspot.png)\\ \\ **HubSpot**\\ \\ **Auth** \\ \\ Authorize tools and agents with HubSpot](https://docs.arcade.dev/home/auth-providers/hubspot) [![LinkedIn logo](https://docs.arcade.dev/images/icons/linkedin.png)\\ \\ **LinkedIn**\\ \\ **Auth** \\ \\ Authorize tools and agents with LinkedIn](https://docs.arcade.dev/home/auth-providers/linkedin) [![Microsoft logo](https://docs.arcade.dev/images/icons/msft.png)\\ \\ **Microsoft**\\ \\ **Auth** \\ \\ Authorize tools and agents with Microsoft Graph](https://docs.arcade.dev/home/auth-providers/microsoft) [![Notion logo](https://docs.arcade.dev/images/icons/notion.png)\\ \\ **Notion**\\ \\ **Auth** \\ \\ Authorize tools and agents with Notion](https://docs.arcade.dev/home/auth-providers/notion) [![Reddit logo](https://docs.arcade.dev/images/icons/reddit.png)\\ \\ **Reddit**\\ \\ **Auth** \\ \\ Authorize tools and agents with Reddit](https://docs.arcade.dev/home/auth-providers/reddit) [![Slack logo](https://docs.arcade.dev/images/icons/slack.png)\\ \\ **Slack**\\ \\ **Auth** \\ \\ Authorize tools and agents with Slack](https://docs.arcade.dev/home/auth-providers/slack) [![Spotify logo](https://docs.arcade.dev/images/icons/spotify.png)\\ \\ **Spotify**\\ \\ **Auth** \\ \\ Authorize tools and agents with Spotify](https://docs.arcade.dev/home/auth-providers/spotify) [![Twitch logo](https://docs.arcade.dev/images/icons/twitch.png)\\ \\ **Twitch**\\ \\ **Auth** \\ \\ Authorize tools and agents with Twitch](https://docs.arcade.dev/home/auth-providers/twitch) [![X logo](https://docs.arcade.dev/images/icons/twitter.png)\\ \\ **X**\\ \\ **Auth** \\ \\ Authorize tools and agents with X (Twitter)](https://docs.arcade.dev/home/auth-providers/x) [![Zoom logo](https://docs.arcade.dev/images/icons/zoom_fav.svg)\\ \\ **Zoom**\\ \\ **Auth** \\ \\ Authorize tools and agents with Zoom](https://docs.arcade.dev/home/auth-providers/zoom) [![OAuth 2.0 logo](https://docs.arcade.dev/images/icons/oauth2.png)\\ \\ **OAuth 2.0**\\ \\ **Auth** \\ \\ Authorize tools and agents with any OAuth 2.0-compatible provider](https://docs.arcade.dev/home/auth-providers/oauth2) If the auth provider you need is not listed, try the [OAuth 2.0](https://docs.arcade.dev/home/auth-providers/oauth2) provider, or [get in touch](mailto:contact@arcade.dev) with us! ## Using multiple providers of the same type [Permalink for this section](https://docs.arcade.dev/home/auth-providers\#using-multiple-providers-of-the-same-type) You can create multiple auth providers of the same type, for example, you can have multiple Google auth providers, each with their own client ID and secret. This might be useful if you want separate Google clients to handle calendar and email scopes, for example. However, Arcade’s tools are configured to select an auth provider by the type. This means that if you have multiple auth providers of the same type, Arcade will not know which one to use and authorizing the tool will fail. To work around this, you can fork Arcade’s tools and modify them to specify your own auth provider by the unique ID that you give each of them. For example, if you have two Google auth providers, `acme-google-calendar` and `acme-google-email`, you can modify Arcade’s Google.ListEmails tool like this: ```nextra-code @tool( requires_auth=Google( id="acme-google-email", # This is the unique ID you gave your auth provider scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) ) async def list_emails( # ... ``` This is similar to the pattern used in the generic OAuth2 provider, but instead of using the `OAuth2` class, you use the `Google` class and specify the `id` of the auth provider you want to use. See the docs about [Authoring Tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) for more information on how to create and serve a toolkit. [Configuration Templates](https://docs.arcade.dev/home/local-deployment/configure/templates "Configuration Templates") [Asana](https://docs.arcade.dev/home/auth-providers/asana "Asana") ## Google Calendar Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") GoogleCalendar # Calendar **Description:** Enable agents to interact with Google Calendar events. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/google) **Auth:** User authorizationvia the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) [![PyPI Version](https://img.shields.io/pypi/v/arcade_google)](https://pypi.org/project/arcade_google/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_google)](https://pypi.org/project/arcade_google/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_google)](https://pypi.org/project/arcade_google/)[![Downloads](https://img.shields.io/pypi/dm/arcade_google)](https://pypi.org/project/arcade_google/) The Arcade Calendar toolkit provides a pre-built set of tools for interacting with Google Calendar. These tools make it easy to build agents and AI apps that can: - Create, update, list, and delete events ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#available-tools) These tools are currently available in the Arcade Calendar toolkit. | Tool Name | Description | | --- | --- | | Google.ListCalendars | List the calendars that the user can see. | | Google.CreateEvent | Create a new event in Google Calendar. | | Google.ListEvents | List events from Google Calendar. | | Google.UpdateEvent | Update an existing event in Google Calendar. | | Google.DeleteEvent | Delete an event from Google Calendar. | | Google.FindTimeSlotsWhenEveryoneIsFree | Provides time slots when everyone is free within a given date range and time boundaries. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Google.ListCalendars [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#googlelistcalendars) See Example > List the calendars that the user can access. **Parameters** - **`max_results`** _(int, optional)_ The maximum number of calendars to return. Up to 250 calendars, defaults to 10. - **`show_deleted`** _(boolean, optional)_ Whether to show deleted calendars. Defaults to False. - **`show_hidden`** _(boolean, optional)_ Whether to show hidden calendars. Defaults to False. - **`next_page_token`** _(string, optional)_ The token to retrieve the next page of calendars. Optional. * * * ## Google.CreateEvent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#googlecreateevent) See Example > Create a new event in the specified calendar. **Parameters** - **`summary`** _(string, required)_ The title of the event - **`start_datetime`** _(string, required)_ The datetime when the event starts in ISO 8601 format, e.g., ‘2024-12-31T15:30:00’. - **`end_datetime`** _(string, required)_ The datetime when the event ends in ISO 8601 format, e.g., ‘2024-12-31T17:30:00’. - **`calendar_id`** _(string, optional, Defaults to `'primary'`)_ The ID of the calendar to create the event in, usually ‘primary’. - **`description`** _(string, optional)_ The description of the event - **`location`** _(string, optional)_ The location of the event - **`visibility`** _(string, optional)_ The visibility of the event - **`attendee_emails`** _(array, optional)_ The list of attendee emails. Must be valid email addresses e.g., `username@domain.com`. * * * ## Google.ListEvents [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#googlelistevents) See Example > List events from the specified calendar within the given datetime range. min\_end\_datetime serves as the lower bound (exclusive) for an event’s end time. max\_start\_datetime serves as the upper bound (exclusive) for an event’s start time. For example: If min\_end\_datetime is set to 2024-09-15T09:00:00 and max\_start\_datetime is set to 2024-09-16T17:00:00, the function will return events that: 1. End after 09:00 on September 15, 2024 (exclusive) 2. Start before 17:00 on September 16, 2024 (exclusive) This means an event starting at 08:00 on September 15 and ending at 10:00 on September 15 would be included, but an event starting at 17:00 on September 16 would not be included. **Parameters** - **`min_end_datetime`** _(string, required)_ Filter by events that end on or after this datetime in ISO 8601 format, e.g., ‘2024-09-15T09:00:00’. - **`max_start_datetime`** _(string, required)_ Filter by events that start before this datetime in ISO 8601 format, e.g., ‘2024-09-16T17:00:00’. - **`calendar_id`** _(string, optional)_ The ID of the calendar to list events from - **`max_results`** _(integer, optional)_ The maximum number of events to return * * * ## Google.UpdateEvent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#googleupdateevent) See Example > Update an existing event in the specified calendar with the provided details. Only the provided fields will be updated; others will remain unchanged. `updated_start_datetime` and `updated_end_datetime` are independent and can be provided separately. **Parameters** - **`event_id`** _(string, required)_ The ID of the event to update - **`updated_start_datetime`** _(string, optional)_ The updated datetime that the event starts in ISO 8601 format, e.g., ‘2024-12-31T15:30:00’. - **`updated_end_datetime`** _(string, optional)_ The updated datetime that the event ends in ISO 8601 format, e.g., ‘2024-12-31T17:30:00’. - **`updated_calendar_id`** _(string, optional)_ The updated ID of the calendar containing the event. - **`updated_summary`** _(string, optional)_ The updated title of the event - **`updated_description`** _(string, optional)_ The updated description of the event - **`updated_location`** _(string, optional)_ The updated location of the event - **`updated_visibility`** _(enum ( [EventVisibility](https://docs.arcade.dev/toolkits/productivity/google/reference#eventvisibility)), optional)_ The visibility of the event - **`attendee_emails_to_add`** _(array, optional)_ The list of attendee emails to add. Must be valid email addresses e.g., `username@domain.com`. - **`attendee_emails_to_remove`** _(array, optional)_ The list of attendee emails to remove. Must be valid email addresses e.g., `username@domain.com`. - **`send_updates`** _(enum ( [SendUpdatesOptions](https://docs.arcade.dev/toolkits/productivity/google/reference#sendupdatesoptions)), optional, Defaults to `'all'`)_ Should attendees be notified of the update? (none, all, external\_only) * * * ## Google.DeleteEvent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#googledeleteevent) See Example > Delete an event from Google Calendar. **Parameters** - **`event_id`** _(string, required)_ The ID of the event to delete - **`calendar_id`** _(string, optional, Defaults to `'primary'`)_ The ID of the calendar containing the event - **`send_updates`** _(enum ( [SendUpdatesOptions](https://docs.arcade.dev/toolkits/productivity/google/reference#sendupdatesoptions)), optional, Defaults to `'all'`)_ Specifies which attendees to notify about the deletion ## Google.FindTimeSlotsWhenEveryoneIsFree [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#googlefindtimeslotswheneveryoneisfree) See Example > Provides time slots when everyone is free within a given date range and time boundaries. **Parameters** - **`email_addresses`** _(list of strings, defaults to `None`)_ The list of email addresses from people in the same organization domain (apart from the currently logged in user) to search for free time slots. Defaults to None, which will return free time slots for the current user only. - **`start_date`** _(string, optional, Defaults to `None`)_ The start date to search for time slots in the format ‘YYYY-MM-DD’. Defaults to today’s date. It will search starting from this date at the time 00:00:00. - **`end_date`** _(string, optional, Defaults to `None`)_ The end date to search for time slots in the format ‘YYYY-MM-DD’. Defaults to seven days from the start date. It will search until this date at the time 23:59:59. - **`start_time_boundary`** _(string, defaults to “08:00”)_ Will return free slots in any given day starting from this time in the format ‘HH:MM’. Defaults to ‘08:00’, which is a usual business hour start time. - **`end_time_boundary`** _(string, defaults to “18:00”)_ Will return free slots in any given day ending at this time in the format ‘HH:MM’. Defaults to ‘18:00’, which is a usual business hour end time. * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/calendar\#auth) The Arcade Calendar toolkit uses the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) to connect to users’ Google accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Google auth provider](https://docs.arcade.dev/home/auth-providers/google#configuring-google-auth) with your own Google app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_google\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/productivity/dropbox/reference "Reference") [Contacts](https://docs.arcade.dev/toolkits/productivity/google/contacts "Contacts") ## Arcade Quickstart Guide [Home](https://docs.arcade.dev/home "Home") Quickstart # Arcade Quickstart This guide will walk you through the process of getting started with Arcade.dev. First, we will go over Direct Tool Calling, a simple way to call tools directly from your agent. Direct tool calling is useful in situations where you already know what tool is needed or when there is no prompt for an LLM to interpret and decide on the tool calling. It also gives you full control over what is executed by the Arcade Engine and how. [iframe](https://www.youtube.com/embed/USoqJOOUP6c?si=ontrjjatjmqMfTHN) ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/quickstart?lang=typescript\#prerequisites) 1. Create an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=call-tools-directly) 2. Get an [Arcade API key](https://docs.arcade.dev/home/api-keys) and take note, you’ll need it in the next steps. ### Install the Arcade client [Permalink for this section](https://docs.arcade.dev/home/quickstart?lang=typescript\#install-the-arcade-client) PythonJavaScript ```nextra-code pip install arcadepy ``` ```nextra-code npm install @arcadeai/arcadejs ``` ### Instantiate and use the client [Permalink for this section](https://docs.arcade.dev/home/quickstart?lang=typescript\#instantiate-and-use-the-client) PythonJavaScript Create a new script called `example.py`: ```nextra-code from arcadepy import Arcade # You can also set the `ARCADE_API_KEY` environment variable instead of passing it as a parameter. client = Arcade(api_key="arcade_api_key") # Arcade needs a unique identifier for your application user (this could be an email address, a UUID, etc). # In this example, simply use your email address as the user ID: user_id = "user@example.com" # Let's use the `Math.Sqrt` tool from the Arcade Math toolkit to get the square root of a number. response = client.tools.execute( tool_name="Math.Sqrt", input={"a": '625'}, user_id=user_id, ) print(f"The square root of 625 is {response.output.value}") # Now, let's use a tool that requires authentication to star a GitHub repository auth_response = client.tools.authorize( tool_name="GitHub.SetStarred", user_id=user_id, ) if auth_response.status != "completed": print(f"Click this link to authorize: `{auth_response.url}`. The process will continue once you have authorized the app." ) # Wait for the user to authorize the app client.auth.wait_for_completion(auth_response.id); response = client.tools.execute( tool_name="GitHub.SetStarred", input={ "owner": "ArcadeAI", "name": "arcade-ai", "starred": True, }, user_id=user_id, ) print(response.output.value) ``` Create a new script called `example.mjs`: ```nextra-code import Arcade from "@arcadeai/arcadejs"; // You can also set the `ARCADE_API_KEY` environment variable instead of passing it as a parameter. const client = new Arcade({ apiKey: "arcade_api_key", }); // Arcade needs a unique identifier for your application user (this could be an email address, a UUID, etc). // In this example, simply use your email address as the user ID: let userId = "you@example.com"; // Let's use the `Math.Sqrt` tool from the Arcade Math toolkit to get the square root of a number. const response_sqrt = await client.tools.execute({ tool_name: "Math.Sqrt", input: { a: "625" }, user_id: userId, }); console.log(response_sqrt.output.value); // Now, let's use a tool that requires authentication const authResponse = await client.tools.authorize({ tool_name: "GitHub.SetStarred", user_id: userId, }); if (authResponse.status !== "completed") { console.log( `Click this link to authorize: \`${authResponse.url}\`. The process will continue once you have authorized the app.`, ); // Wait for the user to authorize the app await client.auth.waitForCompletion(authResponse.id); } const response_github = await client.tools.execute({ tool_name: "GitHub.SetStarred", input: { owner: "ArcadeAI", name: "arcade-ai", starred: true, }, user_id: userId, }); console.log(response_github.output.value); ``` ### Run the code [Permalink for this section](https://docs.arcade.dev/home/quickstart?lang=typescript\#run-the-code) PythonJavaScript ```nextra-code python3 example.py > The square root of 625 is 25 > Successfully starred the repository ArcadeAI/arcade-ai ``` ```nextra-code node example.mjs > The square root of 625 is 25 > Successfully starred the repository ArcadeAI/arcade-ai ``` ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/quickstart?lang=typescript\#next-steps) In this simple example, we call the tool methods directly. In your real applications and agents, you’ll likely be letting the LLM decide which tools to call - lean more about using Arcade with Frameworks in the [Frameworks](https://docs.arcade.dev/home/langchain/use-arcade-tools) section, or [how to build your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). [Contact us](https://docs.arcade.dev/home/contact-us "[object Object]") [Get an API key](https://docs.arcade.dev/home/api-keys "Get an API key") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Engine Configuration [Home](https://docs.arcade.dev/home "Home") [Local Deployment](https://docs.arcade.dev/home/local-deployment/install "Local Deployment") ConfigureOverview # Configuration Overview Arcade uses configuration files to manage engine settings and default values. When you install the Arcade Engine, two files are created: - The `engine.yaml` file for engine configuration. - The `engine.env` file for environment variables. Let’s explore each file to understand their purpose and how to locate them. ## Engine configuration file [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/overview\#engine-configuration-file) The `engine.yaml` file controls Arcade Engine settings. It supports variable expansion so you can integrate secrets and environment values seamlessly. You can customize this file to suit your setup. For more details, check the [Engine Configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) page. Choose your installation method to view the default location of `engine.yaml`: macOS (Homebrew)Ubuntu/Debian (APT)Manual Download ```nextra-code $HOMEBREW_REPOSITORY/etc/arcade-engine/engine.yaml ``` ```nextra-code /etc/arcade-ai/engine.yaml ``` ```nextra-code $HOME/.arcade/engine.yaml ``` To manually download the engine.yaml, you can get an example from the [Configuration Templates](https://docs.arcade.dev/home/local-deployment/configure/templates#engineyaml) and add it to `$HOME/.arcade/engine.yaml`. ## Engine environment file [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/overview\#engine-environment-file) The `engine.env` file contains default environment variables that power Arcade Engine. You can override these defaults by exporting your own variables or by editing the file directly. Select your installation method below to see the default path for `engine.env`: macOS (Homebrew)Ubuntu/Debian (APT)Manual Download ```nextra-code $HOMEBREW_REPOSITORY/etc/arcade-engine/engine.env ``` ```nextra-code /etc/arcade-ai/engine.env ``` ```nextra-code $HOME/.arcade/engine.env ``` To manually download the `engine.env`, refer to the [Configuration Templates](https://docs.arcade.dev/home/local-deployment/configure/templates#engineenv). [Toolkits](https://docs.arcade.dev/home/local-deployment/install/toolkits "Toolkits") [Engine](https://docs.arcade.dev/home/local-deployment/configure/engine "Engine") ## Handle Tool Errors [Home](https://docs.arcade.dev/home "Home") [Build tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Build tools") Handle tool errors # Tool errors in Arcade When working with Arcade’s Tool SDK, you may encounter various types of errors. This guide will help you understand and handle these errors effectively. ## Handling errors in your tools [Permalink for this section](https://docs.arcade.dev/home/build-tools/handle-tool-errors\#handling-errors-in-your-tools) In most cases, you don’t need to raise errors explicitly in your tools. The `@tool` decorator takes care of proper error propagation and handling. When an unexpected error occurs during tool execution, Arcade’s `ToolExecutor` and `@tool` decorator will raise a `ToolExecutionError` with the necessary context and traceback information. However, if you want to retry the tool call with additional content to improve the tool call’s input parameters, you can raise a [RetryableToolError](https://docs.arcade.dev/home/build-tools/retry-tools-with-improved-prompt) within the tool. ## Common error scenarios [Permalink for this section](https://docs.arcade.dev/home/build-tools/handle-tool-errors\#common-error-scenarios) Let’s explore some common error scenarios you might encounter: ### 1\. Output type mismatch [Permalink for this section](https://docs.arcade.dev/home/build-tools/handle-tool-errors\#1-output-type-mismatch) This occurs when the expected output type of a tool does not match the actual output type when executed. ```nextra-code { "name": "tool_call_error", "message": "tool call failed - Example.Hello failed: Failed to serialize tool output" } ``` For example, the following tool will raise the above error because the tool’s definition specifies that the output should be a string, but the tool returns a list: ```nextra-code from typing import Annotated from arcade_tdk import tool @tool def hello(name: Annotated[str, "The name of the friend to greet"]) -> str: """ Says hello to a friend """ return ["hello", name] ``` ### 2\. Input parameter type error [Permalink for this section](https://docs.arcade.dev/home/build-tools/handle-tool-errors\#2-input-parameter-type-error) This occurs when the input parameter of a tool is of an unsupported type. ```nextra-code Type error encountered while adding tool list_org_repositories from arcade_github.tools.repositories. Reason: issubclass() arg 1 must be a class ``` For example, the following tool will raise the above error because the tool input parameter is of an unsupported type: ```nextra-code from typing import Annotated from arcade_tdk import tool @tool def hello(names: Annotated[tuple[str, str, str], "The names of the friends to greet"]) -> str: """ Says hello to a list of friends """ return f"Hello, {names[0]}, {names[1]}, and {names[2]}!" ``` ### 3\. Unexpected HTTP error during tool execution [Permalink for this section](https://docs.arcade.dev/home/build-tools/handle-tool-errors\#3-unexpected-http-error-during-tool-execution) This occurs when the tool makes an HTTP request and receives a non-2xx response. Specifically for the example below, the authenticated user did not have permission to access the private organization’s repositories. ```nextra-code { "name": "tool_call_error", "message": "tool call failed - Github.ListOrgRepositories failed: Error accessing 'https://api.github.com/orgs/a-private-org/repos': Failed to process request. Status code: 401" } ``` [Create a tool with secrets](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets "Create a tool with secrets") [Retry tools with improved prompt](https://docs.arcade.dev/home/build-tools/retry-tools-with-improved-prompt "Retry tools with improved prompt") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Tool Calling Overview [Home](https://docs.arcade.dev/home "Home") Tool CallingIntroduction # What are tools? Language models excel at text generation but struggle with tasks like calculations, data retrieval, or interacting with external systems. To make an analogy, these models have impressive _brains_ or reasoning capabilities, but lack the _hands_ to interact with the digital world. To solve this, many AI models support tool calling (sometimes referred to as ‘function calling’). ## The use case for tool-calling [Permalink for this section](https://docs.arcade.dev/home/use-tools/tools-overview\#the-use-case-for-tool-calling) Say a colleague shares a document with you on Google Drive, and you’d like an LLM to help you analyze it. You could go to your Drive, open the document, copy its contents, and paste it into your chat. But what if the LLM could do this for you? The Arcade Drive toolkit provides a [`SearchAndRetrieveDocuments`](https://docs.arcade.dev/toolkits/productivity/google/drive#searchandretrievedocuments) tool. By calling it, the LLM can find and read the document without you having to do anything. After analyzing the document, you decide that a meeting is needed with your colleague. You can ask the LLM to schedule a meeting and it will use the [Calendar toolkit](https://docs.arcade.dev/toolkits/productivity/google/calendar) to do it without you needing to leave the chat. Or you could ask the LLM to send a summary of the analysis to your colleague by email and it would use the [Gmail toolkit](https://docs.arcade.dev/toolkits/productivity/google/gmail) for that. ## Possibilities for Application and AI Agent developers [Permalink for this section](https://docs.arcade.dev/home/use-tools/tools-overview\#possibilities-for-application-and-ai-agent-developers) Tool-calling combines the reasoning power of LLMs with virtually any action available through APIs or code execution. With the Arcade SDKs, it is easy to build applications and AI Agents that can leverage tool-calling in order to provide an LLM-powered experience to users in a secure and privacy-forward way. ## How tool calling works [Permalink for this section](https://docs.arcade.dev/home/use-tools/tools-overview\#how-tool-calling-works) AI models that support tool calling can determine when and how to use specific tools to fulfill a user’s request. The developer decides which tools to make available to the model, whether existing tools or tools they’ve built themselves. In the example above, when the user asks: “ _help me analyze the ‘Project XYZ’ document shared by John on Google Drive_”, the LLM can use its reasoning capabilities to: 1. Recognize that it needs to access external data; 2. Evaluate that the `Drive.SearchAndRetrieveDocuments` tool is the best way to get that data; 3. Call the tool with the appropriate parameters; 4. Read the document content and use it to answer the user’s questions. ## The authorization problem [Permalink for this section](https://docs.arcade.dev/home/use-tools/tools-overview\#the-authorization-problem) One challenge to make all that happen is authorization. How do you give the LLM permission to access someone’s Google Drive and Gmail in a secure and convenient way? Arcade solves this problem by providing a standardized [interface for authorization](https://docs.arcade.dev/home/auth/how-arcade-helps), as well as pre-built integrations with [popular services](https://docs.arcade.dev/home/auth-providers) such as Google, Dropbox, GitHub, Notion, and many more. Our SDK also [allows you to integrate](https://docs.arcade.dev/home/auth-providers/oauth2) LLMs with any OAuth 2.0-compliant API. ## Tool Augmented Generation (TAG) [Permalink for this section](https://docs.arcade.dev/home/use-tools/tools-overview\#tool-augmented-generation-tag) Similar to Retrieval Augmented Generation (RAG), tool calling allows the AI to use external data to answer questions. Unlike RAG, tool calling is more flexible and allows the AI to use tools that are much more diverse than text or vector search alone. The following is a diagram of how tool calling is used to provide context to a language model similar to RAG. ![Tool calling diagram 1](https://docs.arcade.dev/images/tool-call-diagrams/tool-call-1.png) First, a language model is given a user’s request. The model then determines if it needs to use a tool to fulfill the request. If so, the model selects the appropriate tool from the tools listed in the request. The model then predicts the parameters of that tool and passes these parameters back to the client application. ![Tool calling diagram 2](https://docs.arcade.dev/images/tool-call-diagrams/tool-call-2.png) Now that the tool has been executed, the model can use the output to generate a response. ![Tool calling diagram 3](https://docs.arcade.dev/images/tool-call-diagrams/tool-call-3.png) This process shows the general outline of the Tool Augmented Generation (TAG) process at a high level. ### Next steps [Permalink for this section](https://docs.arcade.dev/home/use-tools/tools-overview\#next-steps) - Explore the [Toolkits](https://docs.arcade.dev/toolkits) available on Arcade - Build your own [custom toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit) [Use Arcade in Visual Studio Code](https://docs.arcade.dev/home/mcp-desktop-clients/vscode-client "Use Arcade in Visual Studio Code") [Tool formats](https://docs.arcade.dev/home/use-tools/get-tool-definitions "Tool formats") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Zoom Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") Zoom # Zoom **Description:** Enable agents to interact with Zoom by retrieving meeting information and invitations. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/zoom) **Auth:** User authorizationvia the [Zoom auth provider](https://docs.arcade.dev/home/auth-providers/zoom) [![PyPI Version](https://img.shields.io/pypi/v/arcade_zoom)](https://pypi.org/project/arcade_zoom/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_zoom)](https://pypi.org/project/arcade_zoom/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_zoom)](https://pypi.org/project/arcade_zoom/)[![Downloads](https://img.shields.io/pypi/dm/arcade_zoom)](https://pypi.org/project/arcade_zoom/) The Arcade Zoom toolkit provides tools for interacting with Zoom. With these tools, you can build agents and AI applications that can: - List upcoming meetings - Retrieve meeting invitation details ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom\#available-tools) These tools are currently available in the Arcade Zoom toolkit. | Tool Name | Description | | --- | --- | | Zoom.ListUpcomingMeetings | List a Zoom user's upcoming meetings within the next 24 hours. | | Zoom.GetMeetingInvitation | Retrieve the invitation note for a specific Zoom meeting. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your own\\ tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Zoom auth\\ provider](https://docs.arcade.dev/home/auth-providers/zoom#using-zoom-auth-in-custom-tools). ## Zoom.ListUpcomingMeetings [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom\#zoomlistupcomingmeetings) List a Zoom user’s upcoming meetings within the next 24 hours. **Parameters** - **`user_id`** _(string, optional)_ The user’s user ID or email address. Defaults to ‘me’ for the current user. * * * ## Zoom.GetMeetingInvitation [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom\#zoomgetmeetinginvitation) Retrieve the invitation note for a specific Zoom meeting. **Parameters** - **`meeting_id`** _(string, required)_ The meeting’s numeric ID (as a string). * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom\#auth) The Arcade Zoom toolkit uses the [Zoom auth provider](https://docs.arcade.dev/home/auth-providers/zoom) to connect to users’ Zoom accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade ` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Zoom auth provider](https://docs.arcade.dev/home/auth-providers/zoom#configuring-zoom-auth) with your own Zoom app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_zoom\\ ```](https://docs.arcade.dev/home/hosting-overview) [X](https://docs.arcade.dev/toolkits/social-communication/x "X") [Reddit](https://docs.arcade.dev/toolkits/social-communication/reddit "Reddit") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Deploy Configuration [Home](https://docs.arcade.dev/home "Home") [Local Deployment](https://docs.arcade.dev/home/local-deployment/install "Local Deployment") [Configure](https://docs.arcade.dev/home/local-deployment/configure/overview "Configure") Configuring Arcade Deploy # Configuring Arcade Deploy The `arcade deploy` command deploys your worker to the cloud. ## Requirements [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy\#requirements) - **Python 3.10** or higher Verify your Python version by running `python --version` or `python3 --version` in your terminal. - **Arcade Account**: Sign up for an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=custom-tools) if you haven’t already. - **Arcade CLI**: Install the Arcade CLI with `pip install arcade-ai`. ## Deployment Config [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy\#deployment-config) The `worker.toml` file is used to configure your worker. Running `arcade deploy` will use the `worker.toml` file in the current directory or you can specify a different file with the `-d` flag. Running the CLI command `arcade new` will automatically create an example `worker.toml` file for the created toolkit. ```nextra-code # worker.toml # Arcade Deploy supports configuring multiple workers in a single file. # Configurations below each [[worker]] block will be deployed as a separate worker. [[worker]] # (Required) The worker configuration [worker.config] # (Required) The unique identifier for the worker. id = "my-example-worker" # (Optional) Whether the worker is enabled. enabled = true # (Optional) The timeout for the worker for requests to the worker. timeout = 30 # (Optional) The number of times to retry a connection to the worker before giving up. retries = 3 # (Required) The secret for the worker. # The default "dev" secret or empty string is not allowed. # Environment variables can also be used by setting the secret with the format "${env:YOUR_VARIABLE_NAME}" secret = # (Optional) Localy packages to deploy with the worker. # You can specify a list of directories that contain a toolkit. # The directory must contain a pyproject.toml file or a setup.py file. [worker.local_source] packages = [ "./my_toolkit1", "./my_toolkit2"] # (Optional) Pypi packages to install for the worker. [worker.pypi_source] packages = [ "arcade-math", "my-pypi-package"] ``` ## Secrets [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy\#secrets) You can use a secret from the environment to configure the worker with the `${env: MY_SECRET}` syntax. ```nextra-code [[worker]] [worker.config] secret = "${env: MY_ENVIRONMENT_SECRET}" ``` ## Using with a local engine [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy\#using-with-a-local-engine) To register the worker with your local engine, you can use the host and port flags. ```nextra-code arcade deploy -h localhost -p 9099 --no-tls ``` ## Logs [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy\#logs) To see the logs for the worker, you can use the `arcade logs` command. ```nextra-code arcade logs my-example-worker ``` [Engine](https://docs.arcade.dev/home/local-deployment/configure/engine "Engine") [Configuration Templates](https://docs.arcade.dev/home/local-deployment/configure/templates "Configuration Templates") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Discord Auth Configuration [Integrations](https://docs.arcade.dev/toolkits "Integrations") Social & CommunicationDiscord # Discord auth provider The Discord auth provider enables tools and agents to call the Discord API on behalf of a user. Behind the scenes, the Arcade Engine and the Discord auth provider seamlessly manage Discord OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#whats-documented-here) This page describes how to use and configure Discord auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/toolkits/social-communication/discord#using-discord-auth-in-app-code) that needs to call Discord APIs - Or, your [custom tools](https://docs.arcade.dev/toolkits/social-communication/discord#using-discord-auth-in-custom-tools) that need to call Discord APIs ## Configuring Discord auth [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#configuring-discord-auth) ### Create a Discord app [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#create-a-discord-app) - Create a Discord Application in the [Discord developer portal](https://discord.com/developers/applications) - In the OAuth2 tab, set the redirect URI to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the Client ID and Client Secret (you may need to reset the secret to see it) Next, add the Discord app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ### Configuring Discord auth with the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#configuring-discord-auth-with-the-arcade-dashboard) 1. Navigate to the OAuth section of the Arcade Dashboard and click **Add OAuth Provider**. 2. Select **Discord** as the provider. 3. Choose a unique **ID** for your provider (e.g. “my-discord-provider”) with an optional **Description**. 4. Enter your **Client ID** and **Client Secret** from your Discord app. 5. Click **Save**. When you use tools that require Discord auth using your Arcade account credentials, the Arcade Engine will automatically use this Discord OAuth provider. ### Configuring Discord auth in self-hosted Arcade Engine configuration [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#configuring-discord-auth-in-self-hosted-arcade-engine-configuration) ### Set environment variables [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#set-environment-variables) Set the following environment variables: ```nextra-code export DISCORD_CLIENT_ID="" export DISCORD_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code DISCORD_CLIENT_SECRET="" DISCORD_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `discord` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-discord description: "The default Discord provider" enabled: true type: oauth2 provider_id: discord client_id: ${env:DISCORD_CLIENT_ID} client_secret: ${env:DISCORD_CLIENT_SECRET} ``` ## Using Discord auth in app code [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#using-discord-auth-in-app-code) Use the Discord auth provider in your own agents and AI apps to get a user token for the Discord API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Discord API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="discord", scopes=["identify", "email", "guilds", "guilds.join"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "discord", { scopes: ["identify", "email", "guilds", "guilds.join"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Discord auth in custom tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/discord\#using-discord-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Discord API. Use the `Discord()` auth class to specify that a tool requires authorization with Discord. The `context.authorization.token` field will be automatically populated with the user’s Discord token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Discord @tool( requires_auth=Discord( scopes=["guilds"], ) ) async def list_servers( context: ToolContext, user_id: Annotated[\ Optional[str],\ "The user's user ID. Defaults to '@me' for the current user.",\ ] = "@me", ) -> Annotated[dict, "List of servers the user is a member of"]: """List a Discord user's servers they are a member of.""" url = f"https://discord.com/api/users/{user_id}/guilds" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json() ``` [Close.io](https://docs.arcade.dev/toolkits/productivity/closeio "Close.io") [LinkedIn](https://docs.arcade.dev/toolkits/social-communication/linkedin "LinkedIn") ## Arcade Hosting Overview [Home](https://docs.arcade.dev/home "Home") Overview # Hosting Options The best way to use Arcade is to use our cloud service. However, if you need to run Arcade locally to either connect your tools to local-only resources (e.g. a local database or filesystem), or your policies require it, Arcade has you covered! ## Customizing Auth [Permalink for this section](https://docs.arcade.dev/home/hosting-overview\#customizing-auth) You don’t have to host Arcade to customize your auth experiences. Arcade’s cloud service supports a number of auth providers out of the box, but you can always provide your own OAuth app credentials. We recommend doing this for any production use so that you can have isolated rate limits with the OAuth service provider and give your users a consistent experience when they go through an auth flow. You can still use the same tools when you customize your auth, no code changes are required. See [Customizing Auth](https://docs.arcade.dev/home/auth-providers) for more information. ## Hybrid Deployments [Permalink for this section](https://docs.arcade.dev/home/hosting-overview\#hybrid-deployments) Hybrid deployments combine the benefits of running Arcade locally with the benefits of using our cloud service. You can use our cloud service to manage your users and authentication, but run your tools locally. See [Hybrid Deployment](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker) for more information. ## Local Deployments [Permalink for this section](https://docs.arcade.dev/home/hosting-overview\#local-deployments) Local deployments involve running all of the Arcade services locally. This is more complex than a hybrid deployment, but it does give you the flexibility to run Arcade anywhere. See [Local Deployment](https://docs.arcade.dev/home/local-deployment/install/overview) for more information. [Arcade Clients](https://docs.arcade.dev/home/arcade-clients "Arcade Clients") [Hybrid Worker](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker "Hybrid Worker") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Asana Toolkit Reference [Integrations](https://docs.arcade.dev/toolkits "Integrations") Productivity & Docs [Asana](https://docs.arcade.dev/toolkits/productivity/asana "Asana") Reference # Asana Reference Below is a reference of enumerations used by some tools in the Asana toolkit: ## TagColor [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana/reference\#tagcolor) - **DARK\_GREEN**: `'dark-green'` - **DARK\_RED**: `'dark-red'` - **DARK\_BLUE**: `'dark-blue'` - **DARK\_PURPLE**: `'dark-purple'` - **DARK\_PINK**: `'dark-pink'` - **DARK\_ORANGE**: `'dark-orange'` - **DARK\_TEAL**: `'dark-teal'` - **DARK\_BROWN**: `'dark-brown'` - **DARK\_WARM\_GRAY**: `'dark-warm-gray'` - **LIGHT\_GREEN**: `'light-green'` - **LIGHT\_RED**: `'light-red'` - **LIGHT\_BLUE**: `'light-blue'` - **LIGHT\_PURPLE**: `'light-purple'` - **LIGHT\_PINK**: `'light-pink'` - **LIGHT\_ORANGE**: `'light-orange'` - **LIGHT\_TEAL**: `'light-teal'` - **LIGHT\_BROWN**: `'light-brown'` - **LIGHT\_WARM\_GRAY**: `'light-warm-gray'` ## TaskSortBy [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana/reference\#tasksortby) - **DUE\_DATE**: `'due_date'` - **CREATED\_AT**: `'created_at'` - **COMPLETED\_AT**: `'completed_at'` - **MODIFIED\_AT**: `'modified_at'` - **LIKES**: `'likes'` ## SortOrder [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana/reference\#sortorder) - **ASCENDING**: `'ascending'` - **DESCENDING**: `'descending'` [Asana](https://docs.arcade.dev/toolkits/productivity/asana "Asana") [Confluence](https://docs.arcade.dev/toolkits/productivity/confluence "Confluence") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Tools with Vercel AI [Home](https://docs.arcade.dev/home "Home") Vercel AIUsing Arcade tools ## Use Arcade with Vercel AI SDK [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#use-arcade-with-vercel-ai-sdk) The [Vercel AI SDK](https://sdk.vercel.ai/) is an open-source library that simplifies the process of building AI-powered applications. It provides a consistent interface for working with various AI providers and includes several useful features: - Streaming AI responses for real-time interactions - Framework-agnostic support for React, Next.js, Vue, Nuxt, and SvelteKit. - Easy switching between AI providers with a single line of code Let’s supercharge your Vercel AI SDK applications with Arcade’s tools. You’ll get instant access to production-ready tools for working with Google, Slack, GitHub, LinkedIn, and many other popular services, all with built-in authentication. Browse our [complete toolkit catalog](https://docs.arcade.dev/toolkits) to discover what you can build. In this guide, we’ll show you how to use Arcade’s Google toolkit to create an AI agent that can read and summarize emails. You can find the complete code in our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/tree/main/examples/ai-sdk) or follow along below. ## Getting started [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#getting-started) ### Install the required dependencies [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#install-the-required-dependencies) We’ll use the `@ai-sdk/openai` package in this example, but you can use any AI provider supported by the Vercel AI SDK. See the [full list of providers](https://ai-sdk.dev/docs/foundations/providers-and-models#ai-sdk-providers). pnpmnpmyarn ```nextra-code pnpm add ai @ai-sdk/openai @arcadeai/arcadejs ``` ```nextra-code npm install ai @ai-sdk/openai @arcadeai/arcadejs ``` ```nextra-code yarn install ai @ai-sdk/openai @arcadeai/arcadejs ``` ### Get your API keys and set up environment variables [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#get-your-api-keys-and-set-up-environment-variables) You’ll need two API keys: - **OpenAI API key** from [OpenAI dashboard](https://platform.openai.com/api-keys) - **Arcade API key** from our [Getting your API key guide](https://docs.arcade.dev/home/api-keys) Add them to your environment: ```nextra-code OPENAI_API_KEY= ARCADE_API_KEY= ``` ### Import Libraries and Initialize Arcade [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#import-libraries-and-initialize-arcade) ```nextra-code import { openai } from "@ai-sdk/openai" import { generateText } from "ai" import { Arcade } from "@arcadeai/arcadejs" import { toZodToolSet, executeOrAuthorizeZodTool } from "@arcadeai/arcadejs/lib" const arcade = new Arcade() ``` ### Get tools from Arcade’s Google toolkit and convert them to Zod [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#get-tools-from-arcades-google-toolkit-and-convert-them-to-zod) Arcade offers methods to convert tools into Zod schemas, which is essential since the Vercel AI SDK defines tools using Zod. The `toZodToolSet` method is particularly useful, as it simplifies this integration and makes it easier to use Arcade’s tools with the Vercel AI SDK. Learn more about Arcade’s Zod integration options [here](https://docs.arcade.dev/home/use-tools/get-tool-definitions#get-zod-tool-definitions). ```nextra-code // Get Arcade's google toolkit const googleToolkit = await arcade.tools.list({ toolkit: "google", limit: 30 }) const googleTools = toZodToolSet({ tools: googleToolkit.items, client: arcade, userId: "", // Your app's internal ID for the user (an email, UUID, etc). It's used internally to identify your user in Arcade executeFactory: executeOrAuthorizeZodTool, // Checks if tool is authorized and executes it, or returns authorization URL if needed }) ``` ### Generate text with the tools [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#generate-text-with-the-tools) ```nextra-code const result = await generateText({ model: openai("gpt-4o-mini"), prompt: "Read my last email and summarize it in a few sentences", tools: googleTools, maxSteps: 5, }) console.log(result.text) ``` On your first run, you’ll get an authorization message with a link to connect your Google account. Open it in your browser to complete the setup. That’s all you need to do! Arcade will remember your approval for future requests. You can see the full code in our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/ai-sdk/generateText.js). ## Stream the response [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#stream-the-response) Vercel AI SDK supports streaming responses. This creates a more engaging, chat-like experience as the responses appear progressively instead of waiting for the complete answer. To enable streaming, make these key changes: 1. Import `streamText` instead of `generateText` 2. Use `streamText` to create a streamable response 3. Process the response chunk by chunk ```nextra-code import { streamText } from "ai" const { textStream } = streamText({ model: openai("gpt-4o-mini"), prompt: "Read my last email and summarize it in a few sentences", tools: googleTools, maxSteps: 5, }) for await (const chunk of textStream) { process.stdout.write(chunk) } ``` You can see the full code in our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/ai-sdk/index.js). ## How to use other toolkits [Permalink for this section](https://docs.arcade.dev/home/vercelai/use-arcade-tools\#how-to-use-other-toolkits) You just need to change the toolkit parameter in the `list` method. For example, to use Slack tools: ```nextra-code const slackToolkit = await arcade.tools.list({ toolkit: "slack", limit: 30 }) ``` Browse our [complete toolkit catalog](https://docs.arcade.dev/toolkits) to see all available toolkits and their capabilities. Each toolkit comes with pre-built tools that are ready to use with your AI applications. Arcade also is the best way to create your own custom tools and toolkits - learn more [here](https://docs.arcade.dev/home/build-tools/create-a-toolkit). [Managing user authorization](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts "Managing user authorization") [MCP Overview](https://docs.arcade.dev/home/mcp-overview "MCP Overview") ## Search Toolkit Reference [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Reference # Reference for Search Toolkit ## GoogleMapsDistanceUnit [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googlemapsdistanceunit) Distance unit to use in the Google Maps search. - **`KM`**: Kilometers. - **`MI`**: Miles. ## GoogleMapsTravelMode [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googlemapstravelmode) Travel mode to use in the Google Maps search. - **`BEST`**: Best mode. - **`DRIVING`**: Driving mode. - **`MOTORCYCLE`**: Motorcycle mode. - **`PUBLIC_TRANSPORTATION`**: Public transportation mode. - **`WALKING`**: Walking mode. - **`BICYCLE`**: Bicycling mode. - **`FLIGHT`**: Flight mode. ## GoogleFinanceWindow [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googlefinancewindow) Defines the time window for fetching stock data from Google Finance. - **`ONE_DAY`**: Represents a 1-day time window. - **`FIVE_DAYS`**: Represents a 5-day time window. - **`ONE_MONTH`**: Represents a 1-month time window. - **`SIX_MONTHS`**: Represents a 6-month time window. - **`YEAR_TO_DATE`**: Represents the time from the start of the year to the current date. - **`ONE_YEAR`**: Represents a 1-year time window. - **`FIVE_YEARS`**: Represents a 5-year time window. - **`MAX`**: Represents the maximum available time window. ## GoogleFlightsMaxStops [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googleflightsmaxstops) Defines the maximum number of stops for flights. - **`ANY`**: Any number of stops is allowed. - **`NONSTOP`**: Only nonstop flights are allowed. - **`ONE`**: Only flights with one stop are allowed. - **`TWO`**: Only flights with two stops are allowed. ## GoogleFlightsSortBy [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googleflightssortby) Defines the sorting options for flight search results. - **`TOP_FLIGHTS`**: Sort by the best available flights. - **`PRICE`**: Sort by the lowest price. - **`DEPARTURE_TIME`**: Sort by the earliest departure time. - **`ARRIVAL_TIME`**: Sort by the earliest arrival time. - **`DURATION`**: Sort by the shortest flight duration. - **`EMISSIONS`**: Sort by the lowest carbon emissions. ## GoogleFlightsTravelClass [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googleflightstravelclass) Defines the travel class options for flights. - **`ECONOMY`**: Economy class. - **`PREMIUM_ECONOMY`**: Premium economy class. - **`BUSINESS`**: Business class. - **`FIRST`**: First class. ## GoogleHotelsSortBy [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#googlehotelssortby) Defines the sorting options for hotel search results. - **`RELEVANCE`**: Sort by the most relevant results. - **`LOWEST_PRICE`**: Sort by the lowest price available. - **`HIGHEST_RATING`**: Sort by the highest customer ratings. - **`MOST_REVIEWED`**: Sort by the most reviewed hotels. ## LanguageCodes [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#languagecodes) - **`ar`**: Arabic - **`bn`**: Bengali - **`da`**: Danish - **`de`**: German - **`el`**: Greek - **`en`**: English - **`es`**: Spanish - **`fi`**: Finnish - **`fr`**: French - **`hi`**: Hindi - **`hu`**: Hungarian - **`id`**: Indonesian - **`it`**: Italian - **`ja`**: Japanese - **`ko`**: Korean - **`ms`**: Malay - **`nl`**: Dutch - **`no`**: Norwegian - **`pcm`**: Nigerian Pidgin - **`pl`**: Polish - **`pt`**: Portuguese - **`pt-br`**: Portuguese (Brazil) - **`pt-pt`**: Portuguese (Portugal) - **`ru`**: Russian - **`sv`**: Swedish - **`tl`**: Filipino - **`tr`**: Turkish - **`uk`**: Ukrainian - **`zh`**: Chinese - **`zh-cn`**: Chinese (Simplified) - **`zh-tw`**: Chinese (Traditional) ## CountryCodes [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#countrycodes) - **`af`**: Afghanistan - **`al`**: Albania - **`dz`**: Algeria - **`as`**: American Samoa - **`ad`**: Andorra - **`ao`**: Angola - **`ai`**: Anguilla - **`aq`**: Antarctica - **`ag`**: Antigua and Barbuda - **`ar`**: Argentina - **`am`**: Armenia - **`aw`**: Aruba - **`au`**: Australia - **`at`**: Austria - **`az`**: Azerbaijan - **`bs`**: Bahamas - **`bh`**: Bahrain - **`bd`**: Bangladesh - **`bb`**: Barbados - **`by`**: Belarus - **`be`**: Belgium - **`bz`**: Belize - **`bj`**: Benin - **`bm`**: Bermuda - **`bt`**: Bhutan - **`bo`**: Bolivia - **`ba`**: Bosnia and Herzegovina - **`bw`**: Botswana - **`bv`**: Bouvet Island - **`br`**: Brazil - **`io`**: British Indian Ocean Territory - **`bn`**: Brunei Darussalam - **`bg`**: Bulgaria - **`bf`**: Burkina Faso - **`bi`**: Burundi - **`kh`**: Cambodia - **`cm`**: Cameroon - **`ca`**: Canada - **`cv`**: Cape Verde - **`ky`**: Cayman Islands - **`cf`**: Central African Republic - **`td`**: Chad - **`cl`**: Chile - **`cn`**: China - **`cx`**: Christmas Island - **`cc`**: Cocos (Keeling) Islands - **`co`**: Colombia - **`km`**: Comoros - **`cg`**: Congo - **`cd`**: Congo, the Democratic Republic of the - **`ck`**: Cook Islands - **`cr`**: Costa Rica - **`ci`**: Cote D’ivoire - **`hr`**: Croatia - **`cu`**: Cuba - **`cy`**: Cyprus - **`cz`**: Czech Republic - **`dk`**: Denmark - **`dj`**: Djibouti - **`dm`**: Dominica - **`do`**: Dominican Republic - **`ec`**: Ecuador - **`eg`**: Egypt - **`sv`**: El Salvador - **`gq`**: Equatorial Guinea - **`er`**: Eritrea - **`ee`**: Estonia - **`et`**: Ethiopia - **`fk`**: Falkland Islands (Malvinas) - **`fo`**: Faroe Islands - **`fj`**: Fiji - **`fi`**: Finland - **`fr`**: France - **`gf`**: French Guiana - **`pf`**: French Polynesia - **`tf`**: French Southern Territories - **`ga`**: Gabon - **`gm`**: Gambia - **`ge`**: Georgia - **`de`**: Germany - **`gh`**: Ghana - **`gi`**: Gibraltar - **`gr`**: Greece - **`gl`**: Greenland - **`gd`**: Grenada - **`gp`**: Guadeloupe - **`gu`**: Guam - **`gt`**: Guatemala - **`gg`**: Guernsey - **`gn`**: Guinea - **`gw`**: Guinea-Bissau - **`gy`**: Guyana - **`ht`**: Haiti - **`hm`**: Heard Island and Mcdonald Islands - **`va`**: Holy See (Vatican City State) - **`hn`**: Honduras - **`hk`**: Hong Kong - **`hu`**: Hungary - **`is`**: Iceland - **`in`**: India - **`id`**: Indonesia - **`ir`**: Iran, Islamic Republic of - **`iq`**: Iraq - **`ie`**: Ireland - **`im`**: Isle of Man - **`il`**: Israel - **`it`**: Italy - **`je`**: Jersey - **`jm`**: Jamaica - **`jp`**: Japan - **`jo`**: Jordan - **`kz`**: Kazakhstan - **`ke`**: Kenya - **`ki`**: Kiribati - **`kp`**: Korea, Democratic People’s Republic of - **`kr`**: Korea, Republic of - **`kw`**: Kuwait - **`kg`**: Kyrgyzstan - **`la`**: Lao People’s Democratic Republic - **`lv`**: Latvia - **`lb`**: Lebanon - **`ls`**: Lesotho - **`lr`**: Liberia - **`ly`**: Libyan Arab Jamahiriya - **`li`**: Liechtenstein - **`lt`**: Lithuania - **`lu`**: Luxembourg - **`mo`**: Macao - **`mk`**: Macedonia, the Former Yugosalv Republic of - **`mg`**: Madagascar - **`mw`**: Malawi - **`my`**: Malaysia - **`mv`**: Maldives - **`ml`**: Mali - **`mt`**: Malta - **`mh`**: Marshall Islands - **`mq`**: Martinique - **`mr`**: Mauritania - **`mu`**: Mauritius - **`yt`**: Mayotte - **`mx`**: Mexico - **`fm`**: Micronesia, Federated States of - **`md`**: Moldova, Republic of - **`mc`**: Monaco - **`mn`**: Mongolia - **`me`**: Montenegro - **`ms`**: Montserrat - **`ma`**: Morocco - **`mz`**: Mozambique - **`mm`**: Myanmar - **`na`**: Namibia - **`nr`**: Nauru - **`np`**: Nepal - **`nl`**: Netherlands - **`an`**: Netherlands Antilles - **`nc`**: New Caledonia - **`nz`**: New Zealand - **`ni`**: Nicaragua - **`ne`**: Niger - **`ng`**: Nigeria - **`nu`**: Niue - **`nf`**: Norfolk Island - **`mp`**: Northern Mariana Islands - **`no`**: Norway - **`om`**: Oman - **`pk`**: Pakistan - **`pw`**: Palau - **`ps`**: Palestinian Territory, Occupied - **`pa`**: Panama - **`pg`**: Papua New Guinea - **`py`**: Paraguay - **`pe`**: Peru - **`ph`**: Philippines - **`pn`**: Pitcairn - **`pl`**: Poland - **`pt`**: Portugal - **`pr`**: Puerto Rico - **`qa`**: Qatar - **`re`**: Reunion - **`ro`**: Romania - **`ru`**: Russian Federation - **`rw`**: Rwanda - **`sh`**: Saint Helena - **`kn`**: Saint Kitts and Nevis - **`lc`**: Saint Lucia - **`pm`**: Saint Pierre and Miquelon - **`vc`**: Saint Vincent and the Grenadines - **`ws`**: Samoa - **`sm`**: San Marino - **`st`**: Sao Tome and Principe - **`sa`**: Saudi Arabia - **`sn`**: Senegal - **`rs`**: Serbia - **`sc`**: Seychelles - **`sl`**: Sierra Leone - **`sg`**: Singapore - **`sk`**: Slovakia - **`si`**: Slovenia - **`sb`**: Solomon Islands - **`so`**: Somalia - **`za`**: South Africa - **`gs`**: South Georgia and the South Sandwich Islands - **`es`**: Spain - **`lk`**: Sri Lanka - **`sd`**: Sudan - **`sr`**: Suriname - **`sj`**: Svalbard and Jan Mayen - **`sz`**: Swaziland - **`se`**: Sweden - **`ch`**: Switzerland - **`sy`**: Syrian Arab Republic - **`tw`**: Taiwan, Province of China - **`tj`**: Tajikistan - **`tz`**: Tanzania, United Republic of - **`th`**: Thailand - **`tl`**: Timor-Leste - **`tg`**: Togo - **`tk`**: Tokelau - **`to`**: Tonga - **`tt`**: Trinidad and Tobago - **`tn`**: Tunisia - **`tr`**: Turkiye - **`tm`**: Turkmenistan - **`tc`**: Turks and Caicos Islands - **`tv`**: Tuvalu - **`ug`**: Uganda - **`ua`**: Ukraine - **`ae`**: United Arab Emirates - **`uk`**: United Kingdom - **`gb`**: United Kingdom - **`us`**: United States - **`um`**: United States Minor Outlying Islands - **`uy`**: Uruguay - **`uz`**: Uzbekistan - **`vu`**: Vanuatu - **`ve`**: Venezuela - **`vn`**: Viet Nam - **`vg`**: Virgin Islands, British - **`vi`**: Virgin Islands, U.S. - **`wf`**: Wallis and Futuna - **`eh`**: Western Sahara - **`ye`**: Yemen - **`zm`**: Zambia - **`zw`**: Zimbabwe ## WalmartSortBy [Permalink for this section](https://docs.arcade.dev/toolkits/search/reference\#walmartsortby) - **`RELEVANCE`**: `'relevance_according_to_keywords_searched'` \- Sort by relevance. - **`PRICE_LOW_TO_HIGH`**: `'lowest_price_first'` \- Sort by price from low to high. - **`PRICE_HIGH_TO_LOW`**: `'highest_price_first'` \- Sort by price from high to low. - **`BEST_SELLING`**: `'best_selling_products_first'` \- Sort by best selling. - **`RATING_HIGH`**: `'highest_rating_first'` \- Sort by rating from high to low. - **`NEW_ARRIVALS`**: `'new_arrivals_first'` \- Sort by new arrivals. [Google Shopping](https://docs.arcade.dev/toolkits/search/google_shopping "Google Shopping") [Walmart](https://docs.arcade.dev/toolkits/search/walmart "Walmart") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Google # Google auth provider The Google auth provider enables tools and agents to call Google/Google Workspace APIs on behalf of a user. Behind the scenes, the Arcade Engine and the Google auth provider seamlessly manage Google OAuth 2.0 authorization for your users. Want to quickly get started with Google services in your agent or AI app? The pre-built [Arcade Google toolkit](https://docs.arcade.dev/toolkits/productivity/google/gmail) is what you want! ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#whats-documented-here) This page describes how to use and configure Google auth with Arcade. This auth provider is used by: - The [Arcade Google toolkit](https://docs.arcade.dev/toolkits/productivity/google/gmail), which provides pre-built tools for interacting with Google services - Your [app code](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-app-code) that needs to call Google APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools) that need to call Google APIs ## Configuring Google auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#configuring-google-auth) In a production environment, you will most likely want to use your own Google app credentials. This way, your users will see your application’s name requesting permission. You can use your own Google credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Google app credentials, let’s go through the steps to create a Google app. ### Create a Google app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#create-a-google-app) - Follow Google’s guide to [setting up OAuth credentials](https://support.google.com/cloud/answer/6158849?hl=en) - Choose the [scopes](https://developers.google.com/identity/protocols/oauth2/scopes) (permissions) you need for your app - At a minimum, you must enable these scopes: - `https://www.googleapis.com/auth/userinfo.email` - `https://www.googleapis.com/auth/userinfo.profile` - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the client ID and client secret to use below Next, add the Google app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Google Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#configuring-your-own-google-auth-provider-in-arcade) There are two ways to configure your Google app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Google Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Google**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-google-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Google app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Google auth using your Arcade account credentials, the Arcade Engine will automatically use this Google OAuth provider. If you have multiple Google providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Google auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#set-environment-variables) Set the following environment variables: ```nextra-code export GOOGLE_CLIENT_ID="" export GOOGLE_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code GOOGLE_CLIENT_ID="" GOOGLE_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `google` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-google description: "The default Google provider" enabled: true type: oauth2 provider_id: google client_id: ${env:GOOGLE_CLIENT_ID} client_secret: ${env:GOOGLE_CLIENT_SECRET} ``` ## Using Google auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#using-google-auth-in-app-code) Use the Google auth provider in your own agents and AI apps to get a user token for Google APIs. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for Google APIs: PythonJavaScript ```nextra-code from arcadepy import Arcade from google.oauth2.credentials import Credentials from googleapiclient.discovery import build client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" """ In this example, we will use Arcade to authenticate with Google and retrieve Gmail messages. There is a tool for that in the Arcade SDK, which simplifies the process for you to retrieve email messages either through our Python or JavaScript SDKs or via LLM tool calling. Below we are just showing how to use Arcade as an auth provider, if you ever need to. """ # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="google", scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token if not token: raise ValueError("No token found in auth response") credentials = Credentials(token) gmail = build("gmail", "v1", credentials=credentials) email_messages = ( gmail.users().messages().list(userId="me").execute().get("messages", []) ) print(email_messages) ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; /* In this example, we will use Arcade to authenticate with Google and retrieve Gmail messages. There is a tool for that in the Arcade SDK, which simplifies the process for you to retrieve email messages either through our Python or JavaScript SDKs or via LLM tool calling. Below we are just showing how to use Arcade as an auth provider, if you ever need to. */ // Start the authorization process let authResponse = await client.auth.start(userId, "google", { scopes: ["https://www.googleapis.com/auth/gmail.readonly"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); if (!authResponse.context.token) { throw new Error("No token found in auth response"); } const token = authResponse.context.token; // Use the Google Gmail API const response = await fetch( "https://gmail.googleapis.com/gmail/v1/users/me/messages", { headers: { Authorization: `Bearer ${token}`, }, }, ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); const emailMessages = data.messages || []; // Return a list of ids and thread ids console.log(emailMessages); ``` ## Using Google auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/google\#using-google-auth-in-custom-tools) You can use the pre-built [Arcade Google toolkit](https://docs.arcade.dev/toolkits/productivity/google/gmail) to quickly build agents and AI apps that interact with Google services like Gmail, Calendar, Drive, and more. If the pre-built tools in the Google toolkit don’t meet your needs, you can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with Google APIs. Use the `Google()` auth class to specify that a tool requires authorization with Google. The `context.authorization.token` field will be automatically populated with the user’s Google token: ```nextra-code from typing import Annotated from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Google from google.oauth2.credentials import Credentials from googleapiclient.discovery import build @tool( requires_auth=Google( scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) ) async def list_emails( context: ToolContext, subject: Annotated[str, "The subject of the email"], body: Annotated[str, "The body of the email"], recipient: Annotated[str, "The recipient of the email"], ) -> Annotated[str, "A confirmation message with the sent email ID and URL"]: """ Send an email using the Gmail API. """ if not context.authorization or not context.authorization.token: raise ValueError("No token found in context") credentials = Credentials(context.authorization.token) gmail = build("gmail", "v1", credentials=credentials) email_messages = ( gmail.users().messages().list(userId="me").execute().get("messages", []) ) return email_messages ``` [GitHub](https://docs.arcade.dev/home/auth-providers/github "GitHub") [Hubspot](https://docs.arcade.dev/home/auth-providers/hubspot "Hubspot") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Jobs Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google Jobs # Google Jobs **Description:** Enable agents to search for job openings with Google Jobs. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google Jobs toolkit provides a pre-built set of tools for interacting with Google Jobs. These tools make it easy to build agents and AI apps that can: - Search for job openings with Google Jobs. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_jobs\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchJobs | Search for job openings with Google Jobs. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.SearchJobs [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_jobs\#searchsearchjobs) See Example > Search for job openings with Google Jobs. **Parameters** - **`query`** _(string, required)_ Search query. Provide a job title, company name, and/or any keywords in general representing what kind of jobs the user is looking for. - **`location`** _(string, optional, Defaults to `None`)_ Location to search for jobs. E.g. ‘United States’ or ‘New York, NY’. Defaults to None. - **`language`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to use in the Google Jobs search. - **`limit`** _(int, optional, Defaults to 10)_ Maximum number of results to retrieve. Defaults to 10 (max supported by the API). - **`next_page_token`** _(string, optional, Defaults to `None`)_ Next page token to paginate results. Defaults to None (start from the first page). ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_jobs\#auth) The Arcade Google Jobs toolkit uses the [SerpAPI](https://serpapi.com/) to get job data from Google Jobs. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Default parameters [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_jobs\#default-parameters) Language is configurable through environment variables. When set, they will be used as default for Google Jobs tools. Providing a different value as `language` argument in a tool call will override the default value. **Language** The language code is a 2-character code that determines the language in which the API will search and return news articles. There are two environment variables: - `ARCADE_GOOGLE_LANGUAGE`: a default value for all Google search tools. If not set, defaults to ‘en’ (English). - `ARCADE_GOOGLE_JOBS_LANGUAGE`: a default value for the jobs search tools. If not set, defaults to `ARCADE_GOOGLE_LANGUAGE`. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google Hotels](https://docs.arcade.dev/toolkits/search/google_hotels "Google Hotels") [Google Maps](https://docs.arcade.dev/toolkits/search/google_maps "Google Maps") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Gmail Integration Tools [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Google](https://docs.arcade.dev/toolkits/productivity/google/calendar "Google") Gmail # Gmail **Description:** Enable agents to send, read, and manage emails in Gmail. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/google) **Auth:** User authorizationvia the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) [![PyPI Version](https://img.shields.io/pypi/v/arcade_google)](https://pypi.org/project/arcade_google/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_google)](https://pypi.org/project/arcade_google/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_google)](https://pypi.org/project/arcade_google/)[![Downloads](https://img.shields.io/pypi/dm/arcade_google)](https://pypi.org/project/arcade_google/) The Arcade Gmail toolkit provides a pre-built set of tools for interacting with Gmail. These tools make it easy to build agents and AI apps that can: - Send, read, and manage emails - Compose and update draft emails - Delete emails - Search for emails by header - List emails in the user’s mailbox ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#available-tools) These tools are currently available in the Arcade Gmail toolkit. | Tool Name | Description | | --- | --- | | Google.SendEmail | Send an email using the Gmail API. | | Google.SendDraftEmail | Send a draft email using the Gmail API. | | Google.WriteDraftEmail | Compose a new email draft using the Gmail API. | | Google.UpdateDraftEmail | Update an existing email draft. | | Google.DeleteDraftEmail | Delete a draft email using the Gmail API. | | Google.TrashEmail | Move an email to the trash folder. | | Google.ListDraftEmails | List draft emails in the user's mailbox. | | Google.ListEmailsByHeader | Search for emails by header using the Gmail API. | | Google.ListEmails | Read emails and extract plain text content. | | Google.SearchThreads | Search for threads in the user's mailbox. | | Google.ListThreads | List threads in the user's mailbox. | | Google.GetThread | Get the specified thread by ID. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Google.SendEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlesendemail) See Example > Send an email using the Gmail API. **Parameters** - **`subject`** _(string, required)_ The subject of the email. - **`body`** _(string, required)_ The body of the email. - **`recipient`** _(string, required)_ The recipient of the email. - **`cc`** _(array, optional, Defaults to None)_ CC recipients of the email. - **`bcc`** _(array, optional, Defaults to None)_ BCC recipients of the email. * * * ## Google.SendDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlesenddraftemail) See Example > Send a draft email using the Gmail API. **Parameters** - **`email_id`** _(string, required)_ The ID of the draft to send. * * * ## Google.WriteDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlewritedraftemail) See Example > Compose a new email draft using the Gmail API. **Parameters** - **`subject`** _(string, required)_ The subject of the draft email. - **`body`** _(string, required)_ The body of the draft email. - **`recipient`** _(string, required)_ The recipient of the draft email. - **`cc`** _(array, optional, Defaults to None)_ CC recipients of the draft email. - **`bcc`** _(array, optional, Defaults to None)_ BCC recipients of the draft email. * * * ## Google.UpdateDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googleupdatedraftemail) See Example > Update an existing email draft. **Parameters** - **`draft_email_id`** _(string, required)_ The ID of the draft email to update. - **`subject`** _(string, required)_ The subject of the draft email. - **`body`** _(string, required)_ The body of the draft email. - **`recipient`** _(string, required)_ The recipient of the draft email. - **`cc`** _(array, optional, Defaults to None)_ CC recipients of the draft email. - **`bcc`** _(array, optional, Defaults to None)_ BCC recipients of the draft email. * * * ## Google.DeleteDraftEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googledeletedraftemail) See Example > Delete a draft email using the Gmail API. **Parameters** - **`draft_email_id`** _(string, required)_ The ID of the draft email to delete. * * * ## Google.TrashEmail [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googletrashemail) The `TrashEmail` tool is currently only available on a self-hosted instance of the Arcade Engine. To learn more about self-hosting, see the [self-hosting documentation](https://docs.arcade.dev/home/local-deployment/install/local#install-the-engine). See Example > Move an email to the trash folder. **Parameters** - **`email_id`** _(string, required)_ The ID of the email to trash. * * * ## Google.ListDraftEmails [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlelistdraftemails) See Example > List draft emails in the user’s mailbox. **Parameters** - **`n_drafts`** _(integer, optional, Defaults to 5)_ Number of draft emails to read. * * * ## Google.ListEmailsByHeader [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlelistemailsbyheader) See Example > Search for emails by header using the Gmail API. _At least one of the following parameters must be provided: `sender`, `recipient`, `subject`, `body`._ **Parameters** - **`sender`** _(string, optional, Defaults to None)_ The name or email address of the sender. - **`recipient`** _(string, optional, Defaults to None)_ The name or email address of the recipient. - **`subject`** _(string, optional, Defaults to None)_ Words to find in the subject of the email. - **`body`** _(string, optional, Defaults to None)_ Words to find in the body of the email. - **`date_range`** _(string, optional, Defaults to None)_ The date range of the emails. - **`limit`** _(integer, optional, Defaults to 25)_ The maximum number of emails to return. * * * ## Google.ListEmails [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlelistemails) See Example > Read emails from a Gmail account and extract plain text content. **Parameters** - **`n_emails`** _(integer, optional, Defaults to 5)_ Number of emails to read. * * * ## Google.SearchThreads [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlesearchthreads) See Example > Search for threads in the user’s mailbox **Parameters** - **`page_token`** _(string, optional)_ Page token to retrieve a specific page of results in the list. - **`max_results`** _(integer, optional, Defaults to `10`)_ The maximum number of threads to return. - **`include_spam_trash`** _(boolean, optional)_ Whether to include spam and trash in the results. - **`label_ids`** _(array, optional)_ The IDs of labels to filter by. - **`sender`** _(string, optional)_ The name or email address of the sender of the email. - **`recipient`** _(string, optional)_ The name or email address of the recipient. - **`subject`** _(string, optional)_ Words to find in the subject of the email. - **`body`** _(string, optional)_ Words to find in the body of the email. - **`date_range`** _(string, optional)_ The date range of the email. Valid values are ‘today’, ‘yesterday’, ‘last\_7\_days’, ‘last\_30\_days’, ‘this\_month’, ‘last\_month’, ‘this\_year’. * * * ## Google.ListThreads [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlelistthreads) See Example > List threads in the user’s mailbox. **Parameters** - **`page_token`** _(string, optional)_ Page token to retrieve a specific page of results in the list. - **`max_results`** _(integer, optional, Defaults to `10`)_ The maximum number of threads to return. - **`include_spam_trash`** _(boolean, optional)_ Whether to include spam and trash in the results. * * * ## Google.GetThread [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#googlegetthread) See Example > Get the specified thread by ID. **Parameters** - **`thread_id`** _(string, required)_ The ID of the thread to retrieve. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/gmail\#auth) The Arcade Gmail toolkit uses the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) to connect to users’ Google accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Google auth provider](https://docs.arcade.dev/home/auth-providers/google#configuring-google-auth) with your own Google app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_google\\ ```](https://docs.arcade.dev/home/hosting-overview) [Drive](https://docs.arcade.dev/toolkits/productivity/google/drive "Drive") [Sheets](https://docs.arcade.dev/toolkits/productivity/google/sheets "Sheets") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Twitch Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Twitch # Twitch auth provider At this time, Arcade does not offer a default Twitch Auth Provider. To use Twitch auth, you must create a custom Auth Provider with your own Twitch OAuth 2.0 credentials as described below. The Twitch auth provider enables tools and agents to call the Twitch API on behalf of a user. Behind the scenes, the Arcade Engine and the Twitch auth provider seamlessly manage Twitch OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#whats-documented-here) This page describes how to use and configure Twitch auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/twitch#using-twitch-auth-in-app-code) that needs to call Twitch APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/twitch#using-twitch-auth-in-custom-tools) that need to call Twitch APIs ## Configuring Twitch auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#configuring-twitch-auth) In a production environment, you will most likely want to use your own Twitch app credentials. This way, your users will see your application’s name requesting permission. You can use your own Twitch credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Twitch app credentials, let’s go through the steps to create a Twitch app. ### Create a Twitch app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#create-a-twitch-app) - Twitch requires that you have two-factor authentication enabled for your account. Enable in your [account security seetings](https://www.twitch.tv/settings/security) - Create a Twitch Application in the [Twitch App Console](https://dev.twitch.tv/console/apps) - Set the OAuth Redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Select your Application category - Select the ‘Confidential’ Client Type - Copy the App key (Client ID) and App secret (Client Secret), which you’ll need below Next, add the Twitch app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Twitch Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#configuring-your-own-twitch-auth-provider-in-arcade) There are two ways to configure your Twitch app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Twitch Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Twitch**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-twitch-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Twitch app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Twitch auth using your Arcade account credentials, the Arcade Engine will automatically use this Twitch OAuth provider. If you have multiple Twitch providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Twitch auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#set-environment-variables) The Client ID is the Twitch “App key” and the Client Secret is the Twitch “App secret”. Set the following environment variables: ```nextra-code export TWITCH_CLIENT_ID="" export TWITCH_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code TWITCH_CLIENT_SECRET="" TWITCH_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `twitch` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-twitch description: "The default Twitch provider" enabled: true type: oauth2 provider_id: twitch client_id: ${env:TWITCH_CLIENT_ID} client_secret: ${env:TWITCH_CLIENT_SECRET} ``` ## Using Twitch auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#using-twitch-auth-in-app-code) Use the Twitch auth provider in your own agents and AI apps to get a user-scoped token for the Twitch API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Twitch API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="twitch", scopes=["channel:manage:polls"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "twitch", { scopes: ["channel:manage:polls"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Twitch auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/twitch\#using-twitch-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Twitch API. Use the `Twitch()` auth class to specify that a tool requires authorization with Twitch. The `context.authorization.token` field will be automatically populated with the user’s Twitch token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Twitch @tool( requires_auth=Twitch( scopes=["channel:manage:polls"], ) ) async def create_poll( context: ToolContext, broadcaster_id: Annotated[\ str,\ "The ID of the broadcaster to create the poll for.",\ ], title: Annotated[\ str,\ "The title of the poll.",\ ], choices: Annotated[\ list[str],\ "The choices of the poll.",\ ], duration: Annotated[\ int,\ "The duration of the poll in seconds.",\ ], ) -> Annotated[dict, "The poll that was created"]: """Create a poll for a Twitch channel.""" url = "https://api.twitch.tv/helix/polls" headers = { "Authorization": f"Bearer {context.authorization.token}", "Client-Id": "your_client_id", "Content-Type": "application/json", } payload = { "broadcaster_id": broadcaster_id, "title": title, "choices": [{"title": choice} for choice in choices], "duration": duration, } async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, json=payload) response.raise_for_status() return response.json() ``` [Spotify](https://docs.arcade.dev/home/auth-providers/spotify "Spotify") [X](https://docs.arcade.dev/home/auth-providers/x "X") ## Contact Arcade Support # Contact Us We’re here to help you succeed with Arcade! Choose the support channel that best fits your needs. ### Status [Permalink for this section](https://docs.arcade.dev/home/contact-us\#-status) Learn about the current status of Arcade’s services at [status.arcade.dev](https://status.arcade.dev/). ### Discord Discord Community [Permalink for this section](https://docs.arcade.dev/home/contact-us\#-discord-community) Our active Discord community is the fastest way to get help: - Get real-time assistance from the Arcade team - Connect with fellow developers - Stay updated on latest features [Join our Discord Server →](https://discord.gg/GUZEMpEZ9p) ### GitHub GitHub Issues [Permalink for this section](https://docs.arcade.dev/home/contact-us\#-github-issues) For technical issues, feature requests, and contributions: - Report bugs with detailed reproduction steps - Request new features and enhancements - Contribute to documentation improvements [Open a GitHub Issue →](https://github.com/ArcadeAI/arcade-ai/issues/new/choose) ### Resources [Permalink for this section](https://docs.arcade.dev/home/contact-us\#-resources) Before reaching out, you might find your answer in our resources: - [Documentation](https://docs.arcade.dev/) \- Comprehensive guides and API references - [Blog](https://blog.arcade.dev/) \- Latest updates and technical articles - [Examples](https://github.com/ArcadeAI/arcade-ai/tree/main/examples) \- Examples and guides for using arcade-ai ### Email [Permalink for this section](https://docs.arcade.dev/home/contact-us\#-email) For general inquiries and support: - [Contact us via email](mailto:support@arcade.dev) Email responses are not guaranteed within a specific timeframe. For faster assistance, we recommend joining our Discord community. ### Security Research Program [Permalink for this section](https://docs.arcade.dev/home/contact-us\#-security-research-program) At Arcade.dev, security is fundamental to our mission of building safe and reliable tools. We recognize that the security research community plays a valuable role in identifying potential vulnerabilities. #### Scope [Permalink for this section](https://docs.arcade.dev/home/contact-us\#scope) Our program covers security issues in: - Arcade.dev production services and APIs - Agent authentication and authorization mechanisms - Data handling and storage systems - Published open-source components #### What We’re Looking For [Permalink for this section](https://docs.arcade.dev/home/contact-us\#what-were-looking-for) We’re interested in reports about: - Authentication or authorization bypasses - Data exposure or leakage - Injection vulnerabilities - Logic flaws affecting agent behavior - Issues that could compromise user data or agent integrity #### Reporting Process [Permalink for this section](https://docs.arcade.dev/home/contact-us\#reporting-process) Please email [security@arcade.dev](mailto:security@arcade.dev) with: - A clear description of the issue - Steps to reproduce - Potential impact assessment - Any relevant proof-of-concept code (please be responsible) We’ll acknowledge receipt within 72 hours and aim to provide an initial assessment within one week. #### Guidelines [Permalink for this section](https://docs.arcade.dev/home/contact-us\#guidelines) - Please allow us reasonable time to address issues before public disclosure - Avoid automated scanning that could impact service availability - Do not access or modify other users’ data - Keep any discovered vulnerabilities confidential until resolved #### Recognition [Permalink for this section](https://docs.arcade.dev/home/contact-us\#recognition) While we’re a small team with limited resources, we appreciate the effort researchers put into improving our security. We’ll credit researchers (with permission) in our security updates and may provide modest rewards for significant findings on a case-by-case basis. For questions about this program, please contact [security@arcade.dev](mailto:security@arcade.dev). ## Notion Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Notion # Notion auth provider The Notion auth provider enables tools and agents to call [Notion APIs](https://developers.notion.com/reference/intro) on behalf of a user. Behind the scenes, the Arcade Engine and the Notion auth provider seamlessly manage Notion OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#whats-documented-here) This page describes how to use and configure Notion auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/notion#using-notion-auth-in-app-code) that needs to call the Notion API - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/notion#using-notion-auth-in-custom-tools) that need to call the Notion API ## Configuring Notion auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#configuring-notion-auth) In a production environment, you will most likely want to use your own Notion app credentials. This way, your users will see your application’s name requesting permission. You can use your own Notion credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Notion app credentials, let’s go through the steps to create a Notion app. ### Create a Notion app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#create-a-notion-app) - Create a new public integration in your [integration’s settings page](https://www.notion.so/profile/integrations) - Set the redirect URI to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Once you complete creating your integration, copy the client ID and client secret to use below Next, add the Notion app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Notion Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#configuring-your-own-notion-auth-provider-in-arcade) There are two ways to configure your Notion app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Notion Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Notion**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-notion-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Notion app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Notion auth using your Arcade account credentials, the Arcade Engine will automatically use this Notion OAuth provider. If you have multiple Notion providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Notion auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#set-environment-variables) Set the following environment variables: ```nextra-code export NOTION_CLIENT_ID="" export NOTION_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code NOTION_CLIENT_ID="" NOTION_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `notion` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-notion description: "The default Notion provider" enabled: true type: oauth2 provider_id: notion client_id: ${env:NOTION_CLIENT_ID} client_secret: ${env:NOTION_CLIENT_SECRET} ``` ## Using Notion auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#using-notion-auth-in-app-code) Use the Notion auth provider in your own agents and AI apps to get a user token for the Notion API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Notion API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="notion" ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "notion"); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Notion auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/notion\#using-notion-auth-in-custom-tools) You can use the pre-built [Arcade Notion toolkit](https://docs.arcade.dev/toolkits/development/github/github) to quickly build agents and AI apps that interact with Notion. If the pre-built tools in the Notion toolkit don’t meet your needs, you can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Notion API. Use the `Notion()` auth class to specify that a tool requires authorization with Notion. The `context.authorization.token` field will be automatically populated with the user’s Notion token: ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Notion @tool(requires_auth=Notion()) async def search_page_by_title( context: ToolContext, title_includes: Annotated[str, "The text to compare against page and database titles."], ) -> Annotated[dict, "The matching pages."]: """ Search for a Notion page by its title. """ url = "https://api.notion.com/v1/search" headers = { "Authorization": context.authorization.token, "Content-Type": "application/json", "Notion-Version": "2022-06-28", } payload = {"query": title_includes, "filter": {"property": "object", "value": "page"}} async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, json=payload) response.raise_for_status() return dict(response.json()) ``` [Microsoft](https://docs.arcade.dev/home/auth-providers/microsoft "Microsoft") [OAuth 2.0](https://docs.arcade.dev/home/auth-providers/oauth2 "OAuth 2.0") ## API Key Management [Home](https://docs.arcade.dev/home "Home") Get an API key # Getting Your API Key Before you begin, you’ll need an Arcade account - if you haven’t created one yet, you can [sign up here](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=get-api-key). Once you have an account, you can generate API keys through either our dashboard or CLI. DashboardCLI ### Using the Dashboard ### Navigate to API Keys page [Permalink for this section](https://docs.arcade.dev/home/api-keys\#navigate-to-api-keys-page) Visit the [API Keys page](https://api.arcade.dev/dashboard/api-keys) in Arcade Dashboard. ### Create a new API key [Permalink for this section](https://docs.arcade.dev/home/api-keys\#create-a-new-api-key) 1. Click the `Create API Key` button in the top right 2. Enter a descriptive name to help identify your key 3. Click `Create API Key` to generate your key ### Save your API key securely [Permalink for this section](https://docs.arcade.dev/home/api-keys\#save-your-api-key-securely) 1. Copy your API key immediately - it will only be shown once 2. Store it securely 3. You can always generate new keys if needed ### Using the CLI ### Install and login [Permalink for this section](https://docs.arcade.dev/home/api-keys\#install-and-login) 1. Install the Arcade CLI: uvpip ```nextra-code uv pip install arcade-ai ``` ```nextra-code pip install arcade-ai ``` 2. Start the login process: ```nextra-code arcade login ``` ### Complete setup [Permalink for this section](https://docs.arcade.dev/home/api-keys\#complete-setup) The CLI will automatically: - Print your API key to the console - Save your credentials to `~/.arcade/credentials.yaml` API keys are administrator credentials. Anyone who has your API key can make requests to Arcade as you. Always store your API keys in a safe place, such as system environment variables, and never commit them to version control, share them publicly, or use them in browser or frontend code. ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/api-keys\#next-steps) Once you have your API key, you can: - [Start using tools](https://docs.arcade.dev/home/quickstart) - [Create custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) [Quickstart](https://docs.arcade.dev/home/quickstart "Quickstart") [Create a toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Create a toolkit") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Discord Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Discord # Discord auth provider At this time, Arcade does not offer a default Discord Auth Provider. To use Discord auth, you must create a custom Auth Provider with your own Discord OAuth 2.0 credentials as described below. The Discord auth provider enables tools and agents to call the Discord API on behalf of a user. Behind the scenes, the Arcade Engine and the Discord auth provider seamlessly manage Discord OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#whats-documented-here) This page describes how to use and configure Discord auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/discord#using-discord-auth-in-app-code) that needs to call Discord APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/discord#using-discord-auth-in-custom-tools) that need to call Discord APIs ## Configuring Discord auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#configuring-discord-auth) In a production environment, you will most likely want to use your own Discord app credentials. This way, your users will see your application’s name requesting permission. You can use your own Discord credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Discord app credentials, let’s go through the steps to create a Discord app. ### Create a Discord app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#create-a-discord-app) - Create a Discord Application in the [Discord developer portal](https://discord.com/developers/applications) - In the OAuth2 tab, set the redirect URI to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the Client ID and Client Secret (you may need to reset the secret to see it) Next, add the Discord app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Discord Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#configuring-your-own-discord-auth-provider-in-arcade) There are two ways to configure your Atlassian app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Discord Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Discord**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-discord-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Discord app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Discord auth using your Arcade account credentials, the Arcade Engine will automatically use this Discord OAuth provider. If you have multiple Discord providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Discord auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#set-environment-variables) Set the following environment variables: ```nextra-code export DISCORD_CLIENT_ID="" export DISCORD_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code DISCORD_CLIENT_SECRET="" DISCORD_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `discord` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-discord description: "The default Discord provider" enabled: true type: oauth2 provider_id: discord client_id: ${env:DISCORD_CLIENT_ID} client_secret: ${env:DISCORD_CLIENT_SECRET} ``` ## Using Discord auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#using-discord-auth-in-app-code) Use the Discord auth provider in your own agents and AI apps to get a user token for the Discord API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Discord API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="discord", scopes=["identify", "email", "guilds", "guilds.join"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "discord", { scopes: ["identify", "email", "guilds", "guilds.join"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Discord auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/discord\#using-discord-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Discord API. Use the `Discord()` auth class to specify that a tool requires authorization with Discord. The `context.authorization.token` field will be automatically populated with the user’s Discord token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Discord @tool( requires_auth=Discord( scopes=["guilds"], ) ) async def list_servers( context: ToolContext, user_id: Annotated[\ Optional[str],\ "The user's user ID. Defaults to '@me' for the current user.",\ ] = "@me", ) -> Annotated[dict, "List of servers the user is a member of"]: """List a Discord user's servers they are a member of.""" url = f"https://discord.com/api/users/{user_id}/guilds" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json() ``` [Atlassian](https://docs.arcade.dev/home/auth-providers/atlassian "Atlassian") [Dropbox](https://docs.arcade.dev/home/auth-providers/dropbox "Dropbox") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade CLI Tool [Home](https://docs.arcade.dev/home "Home") Arcade CLI # The Arcade CLI The Arcade CLI is a command-line tool that allows you to manage your Arcade deployments, generate, test, and manage your toolkits, and more. This same package contains the SDK that you will use to [build your own toolkits](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Installation [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#installation) Like all python packages, the Arcade CLI needs to be installed within the python virtual environment you are using for your Arcade development environment. Python + uvPython + CondaStandard Python ```nextra-code # install uv: https://docs.astral.sh/uv/getting-started/installation/ uv venv --seed source .venv/bin/activate ``` ```nextra-code # install miniconda: https://www.anaconda.com/docs/getting-started/miniconda/install conda create --name arcade conda activate arcade ``` ```nextra-code python -m venv .venv source .venv/bin/activate ``` Now that your python virtual environment is activated, you can install the Arcade CLI with the following command: uvpip ```nextra-code uv pip install arcade-ai ``` ```nextra-code pip install arcade-ai ``` ## Usage [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#usage) ```nextra-code Usage: arcade [OPTIONS] COMMAND [ARGS]... ╭─ Options ───────────────────────────────────────────────────────────────────────────╮ │ --version -v Print version and exit. │ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─ User ──────────────────────────────────────────────────────────────────────────────╮ │ login Log in to Arcade Cloud │ │ logout Log out of Arcade Cloud │ │ dashboard Open the Arcade Dashboard in a web browser │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Tool Development ──────────────────────────────────────────────────────────────────╮ │ new Create a new toolkit package directory │ │ show Show the installed toolkits or details of a specific tool │ │ chat Start a chat with a model in the terminal to test tools │ │ evals Run tool calling evaluations │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Launch ────────────────────────────────────────────────────────────────────────────╮ │ serve Start tool server worker with locally installed tools │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Deployment ────────────────────────────────────────────────────────────────────────╮ │ deploy Deploy toolkits to Arcade Cloud │ │ worker Manage deployments of tool servers (logs, list, etc) │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ``` You can learn more about any of the commands by running `arcade --help`, e.g. `arcade new --help`. ## `arcade login` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-login) ```nextra-code Usage: arcade login [OPTIONS] Log in to Arcade Cloud ╭─ Options ─────────────────────────────────────────────────────────────────────────╮ │ --host -h TEXT The Arcade Cloud host to log in to. │ │ [default: cloud.arcade.dev] │ │ --port -p INTEGER The port of the Arcade Cloud host (if running locally). │ │ [default: None] │ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade logout` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-logout) ```nextra-code Usage: arcade logout [OPTIONS] Log out of Arcade Cloud ╭─ Options ─────────────────────────────────────────────────────────────────────────╮ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade dashboard` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-dashboard) ```nextra-code Usage: arcade dashboard [OPTIONS] Open the Arcade Dashboard in a web browser ╭─ Options ─────────────────────────────────────────────────────────────────────────╮ │ --host -h TEXT The Arcade Engine host that serves the dashboard. │ │ [default: api.arcade.dev] │ │ --port -p INTEGER The port of the Arcade Engine. │ │ [default: None] │ │ --local -l Open the local dashboard instead of the default remote │ │ dashboard. │ │ --tls Whether to force TLS for the connection to the Arcade │ │ Engine. │ │ --no-tls Whether to disable TLS for the connection to the │ │ Arcade Engine. │ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade new` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-new) ```nextra-code Usage: arcade new [OPTIONS] TOOLKIT_NAME Create a new toolkit package directory. Example: arcade new my_toolkit ╭─ Arguments ──────────────────────────────────────────────────────────────────────╮ │ * toolkit_name TEXT The name of the toolkit to create [required] │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ─────────────────────────────────────────────────────────────────────────╮ │ --dir TEXT tools directory path │ │ [default: current directory] │ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade show` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-show) ```nextra-code Usage: arcade show [OPTIONS] Show the installed toolkits or details of a specific tool ╭─ Options ─────────────────────────────────────────────────────────────────────────╮ │ --toolkit -T TEXT The toolkit to show the tools of │ │ [default: None] │ │ --tool -t TEXT The specific tool to show details for │ │ [default: None] │ │ --host -h TEXT The Arcade Engine address to show the tools/toolkits │ │ of. │ │ [default: api.arcade.dev] │ │ --local -l Show the local environment's catalog instead of an │ │ Arcade Engine's catalog. │ │ --port -p INTEGER The port of the Arcade Engine. │ │ [default: None] │ │ --tls Whether to force TLS for the connection to the Arcade │ │ Engine. If not specified, the connection will use TLS │ │ if the engine URL uses a 'https' scheme. │ │ --no-tls Whether to disable TLS for the connection to the │ │ Arcade Engine. │ │ --debug -d Show debug information │ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade chat` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-chat) ```nextra-code Usage: arcade chat [OPTIONS] Start a chat with a model in the terminal to test tools ╭─ Options ───────────────────────────────────────────────────────────────────────────╮ │ --model -m TEXT The model to use for prediction. │ │ [default: gpt-4o] │ │ --stream -s Stream the tool output. │ │ --prompt TEXT The system prompt to use for the chat. │ │ [default: None] │ │ --debug -d Show debug information │ │ --host -h TEXT The Arcade Engine address to send chat requests to. │ │ [default: api.arcade.dev] │ │ --port -p INTEGER The port of the Arcade Engine. │ │ [default: None] │ │ --tls Whether to force TLS for the connection to the Arcade │ │ Engine. If not specified, the connection will use TLS if │ │ the engine URL uses a 'https' scheme. │ │ --no-tls Whether to disable TLS for the connection to the Arcade │ │ Engine. │ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade evals` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-evals) ```nextra-code Run tool calling evaluations ╭─ Arguments ─────────────────────────────────────────────────────────────────────────╮ │ directory [DIRECTORY] Directory containing evaluation files │ │ [default: .] │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ───────────────────────────────────────────────────────────────────────────╮ │ --details -d Show detailed results │ │ --max-concurrent -c INTEGER Maximum number of concurrent evaluations │ │ (default: 1) │ │ [default: 1] │ │ --models -m TEXT The models to use for evaluation (default: │ │ gpt-4o). Use commas to separate multiple models. │ │ [default: gpt-4o] │ │ --host -h TEXT The Arcade Engine address to send chat requests │ │ to. │ │ [default: localhost] │ │ --cloud Whether to run evaluations against the Arcade │ │ Cloud Engine. Overrides the 'host' option. │ │ --port -p INTEGER The port of the Arcade Engine. │ │ [default: None] │ │ --tls Whether to force TLS for the connection to the │ │ Arcade Engine. If not specified, the connection │ │ will use TLS if the engine URL uses a 'https' │ │ scheme. │ │ --no-tls Whether to disable TLS for the connection to the │ │ Arcade Engine. │ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade serve` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-serve) ```nextra-code Usage: arcade serve [OPTIONS] Start tool server worker with locally installed tools ╭─ Options ───────────────────────────────────────────────────────────────────────────╮ │ --host TEXT Host for the app, from settings by default. │ │ [default: 127.0.0.1] │ │ --port -p INTEGER Port for the app, defaults to │ │ [default: 8002] │ │ --no-auth Disable authentication for the worker. Not │ │ recommended for production. | | --reload Enable auto-reloading when toolkit or server files | | change. │ │ --otel-enable Send logs to OpenTelemetry │ │ --mcp Run as a local MCP server over stdio │ │ --debug -d Show debug information │ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade deploy` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-deploy) ```nextra-code Usage: arcade deploy [OPTIONS] Deploy toolkits to Arcade Cloud ╭─ Options ───────────────────────────────────────────────────────────────────────────╮ │ --deployment-file -d TEXT The deployment file to deploy. │ │ [default: worker.toml] │ │ --host -h TEXT The Arcade Engine host to register the worker │ │ to. │ │ [default: api.arcade.dev] │ │ --port -p INTEGER The port of the Arcade Engine host. │ │ [default: None] │ │ --tls Whether to force TLS for the connection to the │ │ Arcade Engine. If not specified, the connection │ │ will use TLS if the engine URL uses a 'https' │ │ scheme. │ │ --no-tls Whether to disable TLS for the connection to │ │ the Arcade Engine. │ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ``` ## `arcade worker` [Permalink for this section](https://docs.arcade.dev/home/arcade-cli\#arcade-worker) ```nextra-code Usage: arcade worker [OPTIONS] COMMAND [ARGS]... Manage deployments of tool servers (logs, list, etc) ╭─ Options ───────────────────────────────────────────────────────────────────────────╮ │ --host -h TEXT The Arcade Engine host. │ │ [default: api.arcade.dev] │ │ --port -p INTEGER The port of the Arcade Engine host. │ │ [default: None] │ │ --tls Whether to force TLS for the connection to the Arcade │ │ Engine. │ │ --no-tls Whether to disable TLS for the connection to the Arcade │ │ Engine. │ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ──────────────────────────────────────────────────────────────────────────╮ │ list List all workers │ │ enable Enable a worker │ │ disable Disable a worker │ │ rm Remove a worker │ │ logs Get logs for a worker │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ``` [Direct Third-Party API Call](https://docs.arcade.dev/home/auth/call-third-party-apis-directly "Direct Third-Party API Call") [Arcade Clients](https://docs.arcade.dev/home/arcade-clients "Arcade Clients") ## Asana Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Asana # Asana auth provider The Asana auth provider enables tools and agents to call Asana APIs on behalf of a user. Behind the scenes, the Arcade Engine and the Asana auth provider seamlessly manage Asana OAuth 2.0 authorization for your users. Want to quickly get started with Asana services in your agent or AI app? The pre-built [Arcade Asana toolkit](https://docs.arcade.dev/toolkits/productivity/asana) is what you want! ## What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#whats-documented-here) This page describes how to use and configure Asana auth with Arcade. This auth provider is used by: - The [Arcade Asana toolkit](https://docs.arcade.dev/toolkits/productivity/asana), which provides pre-built tools for interacting with Asana - Your [app code](https://docs.arcade.dev/home/auth-providers/asana#using-asana-auth-in-app-code) that needs to call Asana APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/asana#using-asana-auth-in-custom-tools) that need to call Asana APIs ## Use Arcade’s Default Asana Auth Provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#use-arcades-default-asana-auth-provider) Arcade offers a default Asana auth provider that you can use in the Arcade Cloud. In this case, your users will see `Arcade` as the name of the application that’s requesting permission. If you choose to use Arcade’s Asana auth, you don’t need to configure anything. Follow the [Asana toolkit examples](https://docs.arcade.dev/toolkits/productivity/asana) to get started calling Asana tools. ## Use Your Own Asana App Credentials [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#use-your-own-asana-app-credentials) In a production environment, you will most likely want to use your own Asana app credentials. This way, your users will see your application’s name requesting permission. You can use your own Asana credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Asana app credentials, let’s go through the steps to create an Asana app. ## Create an Asana App [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#create-an-asana-app) Follow the documentation on [Building an App with Asana](https://developers.asana.com/docs/overview). You may create a [developer sandbox account](https://developers.asana.com/docs/developer-sandbox) to test your app before moving to production. When creating your app, use the following settings: - Set an appropriate App name, description and icon. This will be visible to your users authorizing access to your app. - Take note of the **Client ID** and **Client Secret**. - In the OAuth settings: - Under “Redirect URLs”, click **Add Redirect URL** and add `https://cloud.arcade.dev/api/v1/oauth/callback`. - Under “Permission Scopes”, select “Full Permissions” - In the “App Listing Details” section, optionally add more information about your app. - In the “Manage Distribution” section, under “Choose a distribution method”, select “Any workspace”. - Optionally, submit your app for the Asana team review. Asana [recently\\ introduced](https://forum.asana.com/t/new-oauth-permission-scopes/1048556) granular permission scopes. This feature is still in preview and the scopes available at the moment do not include all endpoints/actions that the Asana Toolkit needs. For those reasons, Arcade uses the “Full Permissions” scope. ## Configuring your own Asana Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#configuring-your-own-asana-auth-provider-in-arcade) There are two ways to configure your Asana app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (only possible with a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Asana Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Asana**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-asana-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Asana app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Asana auth using your Arcade account credentials, the Arcade Engine will automatically use this Asana OAuth provider. If you have multiple Asana providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configure Asana Auth Using the Engine Configuration YAML Refer to [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. #### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#set-environment-variables) Set the following environment variables: ```nextra-code export ASANA_CLIENT_ID="" export ASANA_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code ASANA_CLIENT_ID="" ASANA_CLIENT_SECRET="" ``` #### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#edit-the-engine-configuration) To locate the `engine.yaml` file in your OS after installing the Arcade Engine, check the [Engine configuration\\ file](https://docs.arcade.dev/home/local-deployment/configure/overview#engine-configuration-file) documentation. Edit the `engine.yaml` file and add an Asana item to the `auth.providers` section: ```nextra-code auth: providers: - id: asana description: "Custom Asana provider" enabled: true type: oauth2 client_id: ${env:ASANA_CLIENT_ID} client_secret: ${env:ASANA_CLIENT_SECRET} ``` #### Restart the Arcade Engine [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#restart-the-arcade-engine) If the Arcade Engine is already running, you will need to restart it for the changes to take effect. ## Using the Arcade Asana Toolkit [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#using-the-arcade-asana-toolkit) The [Arcade Asana toolkit](https://docs.arcade.dev/toolkits/productivity/asana) provides tools to interact with various Asana objects, such as tasks, projects, teams, and users. Refer to the [toolkit documentation and examples](https://docs.arcade.dev/toolkits/productivity/asana) to learn how to use the toolkit to build agents and AI apps that interact with Asana services. ## Using Asana auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#using-asana-auth-in-app-code) Use the Asana auth provider in your own agents and AI apps to get a user-scoped token for the Asana API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Asana API: As explained [above](https://docs.arcade.dev/home/auth-providers/asana#create-an-asana-app), the Asana granular permission scopes are in preview and not yet supported. The `"default"` scope should be used to authorize any action/endpoint you need to call in the Asana API. PythonJavaScript If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), change the `base_url` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code from arcadepy import Arcade client = Arcade(base_url="https://api.arcade.dev") # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="asana", scopes=["default"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) # Do something interesting with the token... auth_token = auth_response.context.token ``` If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), change the `baseURL` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade({ baseURL: "https://api.arcade.dev" }); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "asana", { scopes: ["default"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete const response = await client.auth.waitForCompletion(authResponse); // Do something interesting with the token... const auth_token = response.context.token; ``` You can use the auth token to call the [Get multiple tasks endpoint](https://developers.asana.com/reference/gettasks) and read information about tasks, for example. Any Asana API endpoint can be called with the auth token. ## Using Asana auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/asana\#using-asana-auth-in-custom-tools) You can use the pre-built [Arcade Asana toolkit](https://docs.arcade.dev/toolkits/productivity/asana) to quickly build agents and AI apps that interact with Asana. If the pre-built tools in the Asana toolkit don’t meet your needs, you can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with Asana API. Use the `Asana()` auth class to specify that a tool requires authorization with Asana. The authentication token needed to call the Asana API is available in the tool context through the `context.get_auth_token_or_empty()` method. As explained [above](https://docs.arcade.dev/home/auth-providers/asana#create-an-asana-app), the Asana granular permission scopes are in preview and not yet supported. The `"default"` scope should be used as the only scope in all tools. ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Asana @tool(requires_auth=Asana(scopes=["default"])) async def delete_task( context: ToolContext, task_id: Annotated[str, "The ID of the task to delete."], ) -> Annotated[dict, "Details of the deletion response"]: """Deletes a task.""" url = f"https://api.asana.com/api/1.0/tasks/{task_id}" headers = { "Authorization": f"Bearer {context.get_auth_token_or_empty()}", "Accept": "application/json", } async with httpx.AsyncClient() as client: response = await client.delete(url, headers=headers) response.raise_for_status() return response.json() ``` If you are [self-hosting Arcade](https://docs.arcade.dev/home/local-deployment/install/overview), you will need to restart the Arcade Worker and the Engine for the new tool to be available. Your new tool can be called like demonstrated below: PythonJavaScript If you are self-hosting, change the `base_url` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code from arcadepy import Arcade client = Arcade(base_url="https://api.arcade.dev") # Automatically finds the `ARCADE_API_KEY` env variable USER_ID = "user@example.com" TOOL_NAME = "Asana.DeleteTask" auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID) if auth_response.status != "completed": print(f"Click this link to authorize: {auth_response.url}") # Wait for the authorization to complete client.auth.wait_for_completion(auth_response) tool_input = { "task_id": "1234567890", } response = client.tools.execute( tool_name=TOOL_NAME, input=tool_input, user_id=USER_ID, ) print(response.output.value) ``` If you are self-hosting, change the `baseURL` parameter in the `Arcade` constructor to match your Arcade Engine URL. By default, the Engine will be available at `http://localhost:9099`. ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade({ baseURL: "https://api.arcade.dev" }); // Automatically finds the `ARCADE_API_KEY` env variable const USER_ID = "user@example.com"; const TOOL_NAME = "Asana.DeleteTask"; // Start the authorization process const authResponse = await client.tools.authorize({ tool_name: TOOL_NAME, user_id: USER_ID, }); if (authResponse.status !== "completed") { console.log(`Click this link to authorize: ${authResponse.url}`); } // Wait for the authorization to complete await client.auth.waitForCompletion(authResponse); const toolInput = { task_id: "1234567890", }; const response = await client.tools.execute({ tool_name: TOOL_NAME, input: toolInput, user_id: USER_ID, }); console.log(response.output.value); ``` [Overview](https://docs.arcade.dev/home/auth-providers "Overview") [Atlassian](https://docs.arcade.dev/home/auth-providers/atlassian "Atlassian") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Authorized Tool Calling [Home](https://docs.arcade.dev/home "Home") [Authorization](https://docs.arcade.dev/home/auth/how-arcade-helps "Authorization") Authorized Tool Calling # Authorized Tool Calling Arcade provides an authorization system that handles OAuth 2.0, API keys, and user tokens needed by AI agents to access external services through tools. This means your AI agents can now act on behalf of users securely and privately. With Arcade, developers can now create agents that can as _as the end user of their application_ to perform tasks like: - Creating a new Zoom meeting - Sending or reading email - Answering questions about files in Google Drive. Arcade also allows for actions (tools) to be authorized directly. For example, to access a user’s Gmail account, you can utilize the following guide. ### Initialize the client [Permalink for this section](https://docs.arcade.dev/home/auth/auth-tool-calling\#initialize-the-client) Import the Arcade client in a Python/Javascript script. The client automatically finds API keys set by `arcade login`. PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable ``` ```nextra-code import Arcade from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable ``` ### Authorize a tool directly [Permalink for this section](https://docs.arcade.dev/home/auth/auth-tool-calling\#authorize-a-tool-directly) Many tools require authorization. For example, the `Google.ListEmails` tool requires authorization with Google. This authorization must be approved by the user. By approving, the user allows your agent or app to access only the data they’ve approved. PythonJavaScript ```nextra-code # As the developer, you must identify the user you're authorizing # and pass a unique identifier for them (e.g. an email or user ID) to Arcade: USER_ID = "you@example.com" # Request access to the user's Gmail account auth_response = client.tools.authorize( tool_name="Google.ListEmails", user_id=USER_ID, ) if auth_response.status != "completed": print(f"Click this link to authorize: {auth_response.url}") ``` ```nextra-code // As the developer, you must identify the user you're authorizing // and pass a unique identifier for them (e.g. an email or user ID) to Arcade: const userId = "you@example.com"; // Request access to the user's Gmail account const authResponse = await client.tools.authorize({ tool_name: "Google.ListEmails", user_id: userId, }); if (authResponse.status !== "completed") { console.log(`Click this link to authorize: ${authResponse.url}`); } ``` This will print a URL that the user must visit to approve the authorization. ### Check for authorization status [Permalink for this section](https://docs.arcade.dev/home/auth/auth-tool-calling\#check-for-authorization-status) You can wait for the authorization to complete using the following methods: PythonJavaScript ```nextra-code client.auth.wait_for_completion(auth_response) ``` ```nextra-code await client.auth.waitForCompletion(authResponse); ``` ### Call the tool with authorization [Permalink for this section](https://docs.arcade.dev/home/auth/auth-tool-calling\#call-the-tool-with-authorization) Once the user has approved the action, you can run the tool. You only need to pass the `user_id`: PythonJavaScript ```nextra-code emails_response = client.tools.execute( tool_name="Google.ListEmails", user_id=USER_ID, ) print(emails_response) ``` ```nextra-code const emailsResponse = await client.tools.execute({ tool_name: "Google.ListEmails", user_id: userId, }); console.log(emailsResponse.output.value); ``` Arcade remembers the user’s authorization tokens, so you don’t have to! Next time the user runs the same tool, they won’t have to go through the authorization process again until the auth expires or is revoked. ### How it works [Permalink for this section](https://docs.arcade.dev/home/auth/auth-tool-calling\#how-it-works) When you call a tool with `client.tools.execute()`, Arcade: 1. Checks for authorization. 2. Routes the request to the tool’s provider. 3. Returns the tool’s response. With `client.tools.authorize()`, you can also authorize tools for later use. These APIs give you programmatic control over tool calling. ### Next steps [Permalink for this section](https://docs.arcade.dev/home/auth/auth-tool-calling\#next-steps) Arcade also allows you to [build your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) to integrate any custom functionality or API to your Agent or AI workflows. Your tools can use the [service providers supported by Arcade](https://docs.arcade.dev/home/auth-providers) or you can integrate with any [OAuth2-compatible service](https://docs.arcade.dev/home/auth-providers/oauth2). [How Arcade Helps](https://docs.arcade.dev/home/auth/how-arcade-helps "How Arcade Helps") [Checking Authorization Status](https://docs.arcade.dev/home/auth/tool-auth-status "Checking Authorization Status") ## Jira Toolkit Reference [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Jira](https://docs.arcade.dev/toolkits/productivity/jira "Jira") Reference # Jira Reference Below is a reference of enumerations used by some tools in the Jira toolkit: ## PrioritySchemeOrderBy [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira/reference\#priorityschemeorderby) - **NAME\_ASCENDING**: `name ascending` - **NAME\_DESCENDING**: `name descending` ## IssueCommentOrderBy [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira/reference\#issuecommentorderby) - **CREATED\_DATE\_ASCENDING**: `created_date_ascending` - **CREATED\_DATE\_DESCENDING**: `created_date_descending` [Environment Variables](https://docs.arcade.dev/toolkits/productivity/jira/environment_variables "Environment Variables") [Outlook Calendar](https://docs.arcade.dev/toolkits/productivity/microsoft/outlook_calendar "Outlook Calendar") ## Confluence Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") Confluence # Confluence **Description:** Enable agents to interact with Confluence. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/confluence) **Auth:** User authorizationvia the [Atlassian auth provider](https://docs.arcade.dev/home/auth-providers/atlassian) [![PyPI Version](https://img.shields.io/pypi/v/arcade_confluence)](https://pypi.org/project/arcade_confluence/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_confluence)](https://pypi.org/project/arcade_confluence/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_confluence)](https://pypi.org/project/arcade_confluence/)[![Downloads](https://img.shields.io/pypi/dm/arcade_confluence)](https://pypi.org/project/arcade_confluence/) The Arcade Confluence toolkit provides a pre-built set of tools for interacting with Confluence. These tools make it easy to build agents and AI apps that can: - Work with pages, spaces, and attachments - Search for content ## Available tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#available-tools) These tools are currently available in the Arcade Confluence toolkit. | Tool Name | Description | | --- | --- | | Confluence.CreatePage | Create a new page at the root of the given space. | | Confluence.UpdatePageContent | Update a page's content. | | Confluence.RenamePage | Rename a page by changing its title. | | Confluence.GetPage | Retrieve a SINGLE page's content by its ID or title. | | Confluence.GetPagesById | Get the content of MULTIPLE pages by their ID in a single efficient request. | | Confluence.ListPages | Get the content of multiple pages by their ID. | | Confluence.ListAttachments | List attachments in a workspace. | | Confluence.GetAttachmentsForPage | Get attachments for a page by its ID or title. | | Confluence.SearchContent | Search for content in Confluence. | | Confluence.GetSpace | Get the details of a space by its ID or key. | | Confluence.ListSpaces | List all spaces sorted by name in ascending order. | | Confluence.GetSpaceHierarchy | Retrieve the full hierarchical structure of a Confluence space as a tree structure. | If you need to perform an action that’s not listed here, you can [get in touch with us](mailto:contact@arcade.dev) to request a new tool, or [create your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Confluence auth provider](https://docs.arcade.dev/home/auth-providers/atlassian). ## Confluence.CreatePage [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencecreatepage) Create a new page at the root of the given space. **Parameters** - **`space_identifier`** _(string, required)_: The ID or title of the space to create the page in - **`title`** _(string, required)_: The title of the page - **`content`** _(string, required)_: The content of the page. Only plain text is supported - **`parent_id`** _(string, optional)_: The ID of the parent. If not provided, the page will be created at the root of the space - **`is_private`** _(bool, optional)_: If true, then only the user who creates this page will be able to see it. Defaults to False - **`is_draft`** _(bool, optional)_: If true, then the page will be created as a draft. Defaults to False See Example > * * * ## Confluence.UpdatePageContent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluenceupdatepagecontent) Update a page’s content. **Parameters** - **`page_identifier`** _(string, required)_: The ID or title of the page to update. Numerical titles are NOT supported - **`content`** _(string, required)_: The content of the page. Only plain text is supported - **`update_mode`** _(enum ( [PageUpdateMode](https://docs.arcade.dev/toolkits/productivity/confluence#pageupdatemode)), optional)_: The mode of update. Defaults to ‘append’ See Example > ## Confluence.RenamePage [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencerenamepage) Rename a page by changing its title. **Parameters** - **`page_identifier`** _(string, required)_: The ID or title of the page to rename. Numerical titles are NOT supported - **`title`** _(string, required)_: The title of the page See Example > * * * ## Confluence.GetPage [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencegetpage) Retrieve a SINGLE page’s content by its ID or title. If a title is provided, then the first page with an exact matching title will be returned. IMPORTANT: For retrieving MULTIPLE pages, use `get_pages_by_id` instead for a massive performance and efficiency boost. If you call this function multiple times instead of using `get_pages_by_id`, then the universe will explode. **Parameters** - **`page_identifier`** _(string, required)_: Can be a page’s ID or title. Numerical titles are NOT supported See Example > * * * ## Confluence.GetPagesById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencegetpagesbyid) Get the content of MULTIPLE pages by their ID in a single efficient request. IMPORTANT: Always use this function when you need to retrieve content from more than one page, rather than making multiple separate calls to get\_page, because this function is significantly more efficient than calling get\_page multiple times. **Parameters** - **`page_ids`** _(list of strings, required)_: The IDs of the pages to get. IDs are numeric. Titles of pages are NOT supported. Maximum of 250 page ids supported See Example > * * * ## Confluence.ListPages [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencelistpages) Get the content of multiple pages by their ID. **Parameters** - **`space_ids`** _(list of strings, optional)_: Restrict the response to only include pages in these spaces. Only space IDs are supported. Titles of spaces are NOT supported. If not provided, then no restriction is applied. Maximum of 100 space ids supported - **`sort_by`** _(enum ( [PageSortOrder](https://docs.arcade.dev/toolkits/productivity/confluence#pagesortorder)), optional)_: The order of the pages to sort by. Defaults to created-date-newest-to-oldest - **`limit`** _(int, optional)_: The maximum number of pages to return. Defaults to 25. Max is 250 - **`pagination_token`** _(string, optional)_: The pagination token to use for the next page of results See Example > * * * ## Confluence.ListAttachments [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencelistattachments) List attachments in a workspace. **Parameters** - **`sort_order`** _(enum ( [AttachmentSortOrder](https://docs.arcade.dev/toolkits/productivity/confluence#attachmentsortorder)), optional)_: The order of the attachments to sort by. Defaults to created-date-newest-to-oldest - **`limit`** _(int, optional)_: The maximum number of attachments to return. Defaults to 25. Max is 250 - **`pagination_token`** _(string, optional)_: The pagination token to use for the next page of results See Example > * * * ## Confluence.GetAttachmentsForPage [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencegetattachmentsforpage) Get attachments for a page by its ID or title. If a page title is provided, then the first page with an exact matching title will be returned. **Parameters** - **`page_identifier`** _(string, required)_: The ID or title of the page to get attachments for - **`limit`** _(int, optional)_: The maximum number of attachments to return. Defaults to 25. Max is 250 - **`pagination_token`** _(string, optional)_: The pagination token to use for the next page of results See Example > * * * ## Confluence.SearchContent [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencesearchcontent) Search for content in Confluence. The search is performed across all content in the authenticated user’s Confluence workspace. All search terms in Confluence are case insensitive. You can use the parameters in different ways: - must\_contain\_all: For AND logic - content must contain ALL of these - can\_contain\_any: For OR logic - content can contain ANY of these - Combine them: must\_contain\_all=\[‘banana’\] AND can\_contain\_any=\[‘database’, ‘guide’\] **Parameters** - **`must_contain_all`** _(list of strings, optional)_: Words/phrases that content MUST contain (AND logic). Each item can be: - Single word: ‘banana’ - content must contain this word - Multi-word phrase: ‘How to’ - content must contain all these words (in any order) - All items in this list must be present for content to match - Example: \[‘banana’, ‘apple’\] finds content containing BOTH ‘banana’ AND ‘apple’ - **`can_contain_any`** _(list of strings, optional)_: Words/phrases where content can contain ANY of these (OR logic). Each item can be: - Single word: ‘project’ - content containing this word will match - Multi-word phrase: ‘pen & paper’ - content containing all these words will match - Content matching ANY item in this list will be included - Example: \[‘project’, ‘documentation’\] finds content with ‘project’ OR ‘documentation’ - **`enable_fuzzy`** _(bool, optional)_: Enable fuzzy matching to find similar terms (e.g. ‘roam’ will find ‘foam’). Defaults to True - **`limit`** _(int, optional)_: Maximum number of results to return (1-100). Defaults to 25 See Example > * * * ## Confluence.GetSpace [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencegetspace) Get the details of a space by its ID or key. **Parameters** - **`space_identifier`** _(string, required)_: Can be a space’s ID or key. Numerical keys are NOT supported See Example > * * * ## Confluence.ListSpaces [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencelistspaces) List all spaces sorted by name in ascending order. **Parameters** - **`limit`** _(int, optional)_: The maximum number of spaces to return. Defaults to 25. Max is 250 - **`pagination_token`** _(string, optional)_: The pagination token to use for the next page of results See Example > * * * ## Confluence.GetSpaceHierarchy [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#confluencegetspacehierarchy) Retrieve the full hierarchical structure of a Confluence space as a tree structure. Only structural metadata is returned (not content). The response is akin to the sidebar in the Confluence UI. Includes all pages, folders, whiteboards, databases, smart links, etc. organized by parent-child relationships. **Parameters** - **`space_identifier`** _(string, required)_: Can be a space’s ID or key. Numerical keys are NOT supported See Example > ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#auth) The Arcade Notion toolkit uses the [Notion auth provider](https://docs.arcade.dev/home/auth-providers/notion) to connect to users’ Notion accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Notion auth provider](https://docs.arcade.dev/home/auth-providers/notion#configuring-notion-auth) with your own Notion app credentials. * * * ## Reference [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#reference) ### PageUpdateMode [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#pageupdatemode) The mode of update. - **`prepend`** _(string: “prepend”)_ - **`append`** _(string: “append”)_ - **`replace`** _(string: “replace”)_ ### PageSortOrder [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#pagesortorder) The order of the pages to sort by. - **`id-ascending`**: Sort by ID in ascending order. - **`id-descending`**: Sort by ID in descending order. - **`title-ascending`**: Sort by title in ascending order. - **`title-descending`**: Sort by title in descending order. - **`created-date-oldest-to-newest`**: Sort by created date from oldest to newest. - **`created-date-newest-to-oldest`**: Sort by created date from newest to oldest. - **`modified-date-oldest-to-newest`**: Sort by modified date from oldest to newest. - **`modified-date-newest-to-oldest`**: Sort by modified date from newest to oldest. ### AttachmentSortOrder [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/confluence\#attachmentsortorder) The order of the attachments to sort by. - **`created-date-oldest-to-newest`**: Sort by created date from oldest to newest. - **`created-date-newest-to-oldest`**: Sort by created date from newest to oldest. - **`modified-date-oldest-to-newest`**: Sort by modified date from oldest to newest. - **`modified-date-newest-to-oldest`**: Sort by modified date from newest to oldest. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_confluence\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/productivity/asana/reference "Reference") [Dropbox](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox "Dropbox") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Tools Integration [Home](https://docs.arcade.dev/home "Home") [Google ADK](https://docs.arcade.dev/home/google-adk/overview "Google ADK") Using Arcade tools ## Use Arcade with Google ADK [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#use-arcade-with-google-adk) In this guide, let’s explore how to integrate Arcade tools into your Google ADK application. Follow the step-by-step instructions below. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Set up your environment [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#set-up-your-environment) Install the required packages, and ensure your environment variables are set with your Arcade API key: ```nextra-code pip install google-adk-arcade ``` ### Configure API keys [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#configure-api-keys) Provide your Arcade and Google API keys. You can store it in environment variables or directly in your code: > Need an Arcade API key? Visit the [Get an API key](https://docs.arcade.dev/home/api-keys) page to create one. ```nextra-code export ARCADE_API_KEY='YOUR_ARCADE_API_KEY' export GOOGLE_API_KEY='YOUR_GOOGLE_API_KEY' export GOOGLE_GENAI_USE_VERTEXAI=FALSE ``` ### Create and manage Arcade tools [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#create-and-manage-arcade-tools) Use the `get_arcade_tools` function to retrieve tools from specific toolkits: ```nextra-code from arcadepy import AsyncArcade from google_adk_arcade.tools import get_arcade_tools # Initialize the Arcade client client = AsyncArcade() # Get all tools from the "Google" toolkit tools = await get_arcade_tools(client, toolkits=["google"]) # You can request multiple toolkits at once tools = await get_arcade_tools(client, toolkits=["google", "github", "linkedin"]) # You can request specific tools tools = await get_arcade_tools(client, tools=["Google_ListEmails", "Slack_ListUsers", "Slack_SendDmToUser"]) ``` ### Authorize the tools [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#authorize-the-tools) Enable the tools for your agents: ```nextra-code # authorize the tools for tool in google_tools: result = await client.tools.authorize( tool_name=tool.name, user_id=user_id ) if result.status != "completed": print(f"Click this link to authorize {tool.name}:\n{result.url}") await client.auth.wait_for_completion(result) ``` ### Set up the agent with Arcade tools [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#set-up-the-agent-with-arcade-tools) Create an agent and provide it with the Arcade tools: ```nextra-code # import the Google ADK requirements from google.adk import Agent, Runner from google.adk.artifacts import InMemoryArtifactService from google.adk.sessions import InMemorySessionService from google.genai import types # create a new session and artifact services session_service = InMemorySessionService() artifact_service = InMemoryArtifactService() # Create an agent with Google tools google_agent = Agent( model="gemini-2.0-flash", name="google_tool_agent", instruction="I can use Google tools to manage an inbox!", description="An agent equipped with tools to read Gmail emails." tools=tools, ) ``` ### Run the agent with user context [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#run-the-agent-with-user-context) Run the agent, providing a user\_id for tool authorization: ```nextra-code # create a new session and pass the user id into the context session = await session_service.create_session( app_name=app_name, user_id=user_id, state={ "user_id": user_id, } ) # create a new runner with the agent and services runner = Runner( app_name=app_name, agent=google_agent, artifact_service=artifact_service, session_service=session_service, ) # pass a prompt to the agent and stream the response user_input = "summarize my latest 3 emails" content = types.Content( role='user', parts=[types.Part.from_text(text=user_input)] ) for event in runner.run( user_id=user_id, session_id=session.id, new_message=content, ): if event.content.parts and event.content.parts[0].text: print(f'** {event.author}: {event.content.parts[0].text}') ``` ### Complete example [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#complete-example) Here’s a complete example putting everything together: ```nextra-code import asyncio from arcadepy import AsyncArcade from google.adk import Agent, Runner from google.adk.artifacts import InMemoryArtifactService from google.adk.sessions import InMemorySessionService from google.genai import types from google_adk_arcade.tools import get_arcade_tools async def main(): app_name = 'my_app' user_id = 'mateo@arcade.dev' session_service = InMemorySessionService() artifact_service = InMemoryArtifactService() client = AsyncArcade() google_tools = await get_arcade_tools(client, tools=["Google.ListEmails"]) # authorize the tools for tool in google_tools: result = await client.tools.authorize( tool_name=tool.name, user_id=user_id ) if result.status != "completed": print(f"Click this link to authorize {tool.name}:\n{result.url}") await client.auth.wait_for_completion(result) google_agent = Agent( model="gemini-2.0-flash", name="google_tool_agent", instruction="I can use Google tools to manage an inbox!", description="An agent equipped with tools to read Gmail emails. " "Make sure to call google_listemails to read and summarize" " emails", tools=google_tools, ) session = await session_service.create_session( app_name=app_name, user_id=user_id, state={ "user_id": user_id, } ) runner = Runner( app_name=app_name, agent=google_agent, artifact_service=artifact_service, session_service=session_service, ) user_input = "summarize my latest 3 emails" content = types.Content( role='user', parts=[types.Part.from_text(text=user_input)] ) for event in runner.run( user_id=user_id, session_id=session.id, new_message=content, ): if event.content.parts and event.content.parts[0].text: print(f'** {event.author}: {event.content.parts[0].text}') if __name__ == '__main__': asyncio.run(main()) ``` ## Tips for selecting tools [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#tips-for-selecting-tools) - **Relevance**: Pick only the tools you need. Avoid using all tools at once. - **User identification**: Always provide a unique and consistent `user_id` for each user. Use your internal or database user ID, not something entered by the user. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/google-adk/use-arcade-tools\#next-steps) Now that you have integrated Arcade tools into your Google ADK application, you can: - Experiment with different toolkits, such as “github” or “linkedin” - Customize the agent’s instructions for specific tasks - Try out multi-agent systems using different Arcade tools - Build your own custom tools with the Arcade Tool SDK Enjoy exploring Arcade and building powerful AI-enabled Python applications! [Overview](https://docs.arcade.dev/home/google-adk/overview "Overview") [Overview](https://docs.arcade.dev/home/mastra/overview "Overview") ## Arcade Zoom Integration [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") [Zoom](https://docs.arcade.dev/toolkits/social-communication/zoom "Zoom") Install # Arcade for Zoom ## Integrate Arcade with your Zoom account [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#integrate-arcade-with-your-zoom-account) Arcade securely connects your AI agents to APIs, data, code, and other systems via Tools. Our Zoom integration allows Arcade’s tools to connect to your Zoom account, helping you manage meetings and gather information more efficiently. You can leverage this app in Arcade’s Playground when you log in to the Arcade Dashboard, or in your own applications. While the Arcade app for Zoom does not directly expose a Large Language Model (LLM) to you, you will likely use Arcade’s tools in conjunction with an LLM. When using LLMs, there’s always potential to generate inaccurate responses, summaries, or other output. Arcade’s Zoom app brings Arcade’s powerful AI tool-calling capabilities to your meeting management. The Arcade app for Zoom can: - List your upcoming meetings within the next 24 hours - Retrieve meeting invitation details for specific meetings - Find the participants and/or registrants for a specific meeting - and more! For more details on what tools are available and what scopes they require, see the [Zoom toolkit documentation](https://docs.arcade.dev/toolkits/social-communication/zoom). The Arcade Zoom app requires an active Arcade account. If you don’t have one yet, [sign up for free](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=zoom-app-install). ## How it works [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#how-it-works) ### Start using Arcade’s Zoom tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#start-using-arcades-zoom-tools) Use Arcade’s [tools for Zoom](https://docs.arcade.dev/toolkits/social-communication/zoom) to: - List your upcoming meetings - Get meeting invitation details - Find meeting participants and registrants - and more! Try leveraging the Arcade Zoom tools in the Arcade Playground by [chatting with an LLM](https://api.arcade.dev/dashboard/playground/chat) asking, “What meetings do I have scheduled today?” or [executing Zoom tools directly](https://api.arcade.dev/dashboard/playground/execute?toolId=ListUpcomingMeetings&toolkits=%5B%5D&authProviders=%5B%5D&secrets=%5B%5D&input=%7B%22user_id%22%3A%22me%22%7D) without interacting with an LLM. When using LLMs with Zoom, responses may sometimes contain inaccuracies. Always review AI-generated content before taking action. ## Support and troubleshooting [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#support-and-troubleshooting) If you encounter any issues connecting Arcade to your Zoom account: 1. Verify you’ve granted all required permissions during authorization 2. Ensure your Zoom account is active and in good standing 3. Check that you’re using a compatible browser (Chrome, Firefox, Safari, or Edge) 4. Clear your browser cache and cookies, then try again ### Adding the Arcade Zoom app to your Zoom account [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#adding-the-arcade-zoom-app-to-your-zoom-account) If using the Arcade playground directly did not work, you can try adding the Arcade Zoom app to your Zoom account by clicking the “Connect with Zoom” button below. [![](https://docs.arcade.dev/images/icons/zoom_fav.svg)Connect with Zoom](https://docs.arcade.dev/toolkits/social-communication/zoom/install#) You’ll need to have a Zoom account with appropriate permissions to allow Arcade to access your Zoom data. ### Authorize the requested permissions [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#authorize-the-requested-permissions) When connecting Arcade to your Zoom account, depending on which Arcade tools you’ll be using, you’ll be asked to authorize specific permissions: - **user:read:user** \- Allows Arcade to access basic profile information - **user:read:email** \- Enables Arcade to access your email address - **meeting:read:meetings** \- Enables Arcade to list your upcoming meetings - **meeting:read:invitation** \- Enables Arcade to read meeting invitation details These permissions ensure Arcade can perform the necessary functions while protecting your privacy and security. ### Removing the Arcade Zoom app [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#removing-the-arcade-zoom-app) To remove the Arcade Zoom app from your Zoom account, you can do so by going to the [Zoom App Marketplace](https://marketplace.zoom.us/user/installed) and uninstalling the app. Arcade only stores authentication tokens, not your Zoom data. These tokens become invalid when you uninstall the app and will eventually expire. To remove tokens immediately, delete the Zoom Auth Provider from the [Arcade Dashboard](https://api.arcade.dev/dashboard/auth/oauth). ## Privacy and security [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#privacy-and-security) Arcade takes the security of your Zoom data seriously: - We only request the minimum permissions needed for our tools to function - Your Zoom credentials are never stored on our servers - All communication between Arcade and Zoom is encrypted - You can revoke Arcade’s access to your Zoom account at any time through your [Zoom App Marketplace](https://marketplace.zoom.us/user/installed) ## Next steps [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#next-steps) The Arcade Zoom app is a sample of what Arcade can do with your Zoom account. For your own applications, you might want to [create your own Zoom app](https://docs.arcade.dev/home/auth-providers/zoom). Creating your own Zoom application will allow you to brand the app, customize the permissions, and more. ## Need help? [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/zoom/install\#need-help) If you have any questions or need assistance: - Check our [Zoom toolkit documentation](https://docs.arcade.dev/toolkits/social-communication/zoom) - [Contact our support team](https://docs.arcade.dev/home/contact-us) [Zoom](https://docs.arcade.dev/toolkits/social-communication/zoom "Zoom") [Spotify](https://docs.arcade.dev/toolkits/entertainment/spotify "Spotify") ## Arcade Installation Overview [Home](https://docs.arcade.dev/home "Home") Local DeploymentInstallOverview # Installation Explore the different installation options for Arcade. - Set up Arcade [locally](https://docs.arcade.dev/home/local-deployment/install/local) - Run Arcade in [Docker](https://docs.arcade.dev/home/local-deployment/install/docker) - Kubernetes (coming soon) ## Client [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#client) The Arcade Client can be installed with `pip` by following the [quickstart guide](https://docs.arcade.dev/home/quickstart). ## CLI [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#cli) The Arcade CLI & SDK can be installed with `pip` by following the [CLI guide](https://docs.arcade.dev/home/arcade-cli). ## Engine [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#engine) ### Brew and APT [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#brew-and-apt) The `arcade-engine` binary can be downloaded through system package managers like `brew` or `apt` following the instructions [here](https://docs.arcade.dev/home/local-deployment/install/local#install-the-engine) ### Binary [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#binary) The `arcade-engine` binary can be downloaded through system package managers like `brew` or `apt-get` or [directly](https://deb.arcade.dev/ubuntu/dists/stable/main/) ### Docker [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#docker) Containers can be downloaded from [GHCR](https://github.com/orgs/ArcadeAI/packages). Apple Silicon Macs and Intel Chip Macs can use the linux/arm64 and linux/amd64 images respectively. ### Kubernetes [Permalink for this section](https://docs.arcade.dev/home/local-deployment/install/overview\#kubernetes) Kubernetes deployments are not yet supported but coming soon. [Hybrid Worker](https://docs.arcade.dev/home/hybrid-deployment/hybrid-worker "Hybrid Worker") [Local](https://docs.arcade.dev/home/local-deployment/install/local "Local") ## Arcade Slack Integration [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") [Slack](https://docs.arcade.dev/toolkits/social-communication/slack "Slack") Install # Arcade for Slack ## Integrate Arcade with your Slack workspace [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#integrate-arcade-with-your-slack-workspace) Arcade securely connects your AI agents to APIs, data, code, and other systems via Tools. Our integration for Slack allows Arcade’s tools to connect to your Slack workspace, helping your team work more efficiently. You can leverage this app in Arcade’s Playground when you log in to the Arcade Dashboard, or in your own applications. While the Arcade app for Slack does not directly expose a Large Language Model (LLM) to you, you will likely use Arcade’s tools in conjunction with an LLM. When using LLMs, there’s always potential to generate inaccurate responses, summaries, or other output. Arcade’s sample app for Slack brings Arcade’s powerful AI tool-calling capabilities to your team’s everyday conversations. The Arcade app for Slack can: - Send messages to your Slack channels and direct messages on your behalf - Find information in your Slack channels and direct messages - Generate content, summaries, and responses for messages you receive - and more! For more details on what tools are available and what scopes they require, see the [Slack toolkit documentation](https://docs.arcade.dev/toolkits/social-communication/slack). The Arcade app for Slack requires an active Arcade account. If you don’t have one yet, [sign up for free](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=slack-app-install). ## How it works [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#how-it-works) ### Install the Arcade app for Slack [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#install-the-arcade-app-for-slack) Click the “Add to Slack” button below to install Arcade in your workspace. [![Add to Slack](https://platform.slack-edge.com/img/add_to_slack@2x.png)](https://docs.arcade.dev/toolkits/social-communication/slack/install#) You’ll need to be a workspace admin or have permission to install apps to add Arcade to your Slack workspace. ### Invite Arcade to your channels [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#invite-arcade-to-your-channels) Invite Arcade to any channel or direct message by typing `/invite @Arcade` to allow it to read and interact with content in that channel. ### Start using Arcade’s Slack tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#start-using-arcades-slack-tools) Use Arcade’s [tools for Slack](https://docs.arcade.dev/toolkits/social-communication/slack) to: - Send messages to channels and DMs - Find information in conversations - Generate summaries of discussions Try leveraging the Arcade tools for Slack in the Arcade Playground by [chatting with an LLM](https://api.arcade.dev/dashboard/playground/chat) asking, “What are the last 5 messages in the general Slack channel?” or [executing Slack tools directly](https://api.arcade.dev/dashboard/playground/execute?toolId=GetMessagesInChannelByName&toolkits=%5B%5D&authProviders=%5B%5D&secrets=%5B%5D&input=%7B%22owner%22%3A%22ArcadeAI%22%2C%22name%22%3A%22arcade-ai%22%2C%22starred%22%3A%22true%22%2C%22channel_name%22%3A%22general%22%2C%22limit%22%3A%225%22%7D) without interacting with an LLM. When using LLMs with Slack, responses may sometimes contain inaccuracies. Always review AI-generated content before taking action. ## Next steps [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#next-steps) The Arcade app for Slack is a sample for what Arcade can do with your Slack workspace. It’s likely that for your own applications you’ll need to [create your own app for Slack](https://docs.arcade.dev/home/auth-providers/slack). Creating your own application for Slack will allow you to brand the app, customize the permissions, and more. ## Need help? [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack/install\#need-help) If you have any questions or need assistance: - Check our [Slack toolkit documentation](https://docs.arcade.dev/toolkits/social-communication/slack) - [Contact our support team](https://docs.arcade.dev/home/contact-us) [Slack](https://docs.arcade.dev/toolkits/social-communication/slack "Slack") [Reference](https://docs.arcade.dev/toolkits/social-communication/twilio/reference "Reference") ## Authorize LangChain Tools [Home](https://docs.arcade.dev/home "Home") [LangChain](https://docs.arcade.dev/home/langchain/use-arcade-tools "LangChain") Authorizing existing tools ## Authorize Existing Tools [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#authorize-existing-tools) In this guide, we’ll show you how to authorize LangChain tools like the `GmailToolkit` using Arcade. You may already have tools you want to use, and this guide will show you how to authorize them. Arcade handles retrieving, authorizing, and managing tokens so you don’t have to. For complete working examples, see our [Python](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain/langchain_tool_arcade_auth.py) and [JavaScript](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain-ts/langchain-tool-arcade-auth.ts) examples. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Install the required packages [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#install-the-required-packages) Instead of the `langchain_arcade` package, you only need the `arcadepy` package to authorize existing tools since Arcade tools are not being used. PythonJavaScript ```nextra-code pip install langchain-openai langgraph arcadepy langchain-google-community ``` ```nextra-code npm install @arcadeai/arcadejs @langchain/openai @langchain/core @langchain/langgraph @langchain/community ``` ### Import the necessary packages [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#import-the-necessary-packages) PythonJavaScript ```nextra-code import os from arcadepy import Arcade from google.oauth2.credentials import Credentials from langchain_google_community import GmailToolkit from langchain_google_community.gmail.utils import build_resource_service from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; import { GmailCreateDraft, GmailGetMessage, GmailGetThread, GmailSearch, GmailSendMessage, } from "@langchain/community/tools/gmail"; import type { StructuredTool } from "@langchain/core/tools"; import { createReactAgent } from "@langchain/langgraph/prebuilt"; import { ChatOpenAI } from "@langchain/openai"; ``` ### Initialize the Arcade client [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#initialize-the-arcade-client) PythonJavaScript ```nextra-code api_key = os.getenv("ARCADE_API_KEY") client = Arcade(api_key=api_key) ``` ```nextra-code const arcade = new Arcade(); ``` ### Start the authorization process for Gmail [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#start-the-authorization-process-for-gmail) PythonJavaScript ```nextra-code user_id = "user@example.com" auth_response = client.auth.start( user_id=user_id, provider="google", scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) ``` ```nextra-code const USER_ID = "user@example.com"; const authResponse = await arcade.auth.start(USER_ID, "google", { scopes: ["https://www.googleapis.com/auth/gmail.readonly"], }); ``` ### Prompt the user to authorize [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#prompt-the-user-to-authorize) PythonJavaScript ```nextra-code if auth_response.status != "completed": print("Please authorize the application in your browser:") print(auth_response.url) ``` The `auth_response.status` will be `"completed"` if the user has already authorized the application, so they won’t be prompted to authorize again. ```nextra-code if (authResponse.status !== "completed") { console.log("Please authorize the application in your browser:"); console.log(authResponse.url); } ``` The `authResponse.status` will be `"completed"` if the user has already authorized the application, so they won’t be prompted to authorize again. ### Wait for authorization completion [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#wait-for-authorization-completion) PythonJavaScript ```nextra-code auth_response = client.auth.wait_for_completion(auth_response) ``` The `wait_for_completion` method will do nothing if the user has already authorized the application. ```nextra-code const completedAuth = await arcade.auth.waitForCompletion(authResponse); ``` The `waitForCompletion` method will do nothing if the user has already authorized the application. ### Use the token to initialize the Gmail toolkit [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#use-the-token-to-initialize-the-gmail-toolkit) PythonJavaScript ```nextra-code creds = Credentials(auth_response.context.token) api_resource = build_resource_service(credentials=creds) toolkit = GmailToolkit(api_resource=api_resource) tools = toolkit.get_tools() ``` ```nextra-code const gmailParam = { credentials: { accessToken: completedAuth.context.token, }, }; const tools: StructuredTool[] = [\ new GmailCreateDraft(gmailParam),\ new GmailGetMessage(gmailParam),\ new GmailGetThread(gmailParam),\ new GmailSearch(gmailParam),\ new GmailSendMessage(gmailParam),\ ]; ``` ### Initialize the agent [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#initialize-the-agent) PythonJavaScript ```nextra-code model = ChatOpenAI(model="gpt-4o") agent_executor = create_react_agent(model, tools) ``` ```nextra-code const llm = new ChatOpenAI({ model: "gpt-4o" }); const agent_executor = createReactAgent({ llm, tools }); ``` ### Execute the agent [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#execute-the-agent) PythonJavaScript ```nextra-code example_query = "Read my latest emails and summarize them." events = agent_executor.stream( {"messages": [("user", example_query)]}, stream_mode="values", ) for event in events: event["messages"][-1].pretty_print() ``` ```nextra-code const exampleQuery = "Read my latest emails and summarize them."; const events = await agent_executor.stream({ messages: [ { role: "user", content: exampleQuery } ] }, { streamMode: "values" } ); for await (const event of events) { console.log(event.messages[event.messages.length - 1]); } ``` ### Next Steps [Permalink for this section](https://docs.arcade.dev/home/langchain/auth-langchain-tools\#next-steps) Now you’re ready to explore more LangChain tools with Arcade. Try integrating additional toolkits and crafting more complex queries to enhance your AI workflows. [User authorization](https://docs.arcade.dev/home/langchain/user-auth-interrupts "User authorization") [Using Arcade tools](https://docs.arcade.dev/home/crewai/use-arcade-tools "Using Arcade tools") ## Web Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Developer Tools](https://docs.arcade.dev/toolkits/development/code-sandbox "Developer Tools") [Web](https://docs.arcade.dev/toolkits/development/web/reference "Web") Web # Web **Description:** Enable agents to scrape, crawl, and map websites. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/web) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_web)](https://pypi.org/project/arcade_web/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_web)](https://pypi.org/project/arcade_web/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_web)](https://pypi.org/project/arcade_web/)[![Downloads](https://img.shields.io/pypi/dm/arcade_web)](https://pypi.org/project/arcade_web/) The Arcade Web toolkit provides a pre-built set of tools for interacting with websites. These tools make it easy to build agents and AI apps that can: - Scrape web pages - Crawl websites - Map website structures - Retrieve crawl status and data - Cancel ongoing crawls ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#available-tools) These tools are currently available in the Arcade Web toolkit. | Tool Name | Description | | --- | --- | | Web.ScrapeUrl | Scrape a URL and return data in specified formats. | | Web.CrawlWebsite | Crawl a website and return crawl status and data. | | Web.GetCrawlStatus | Retrieve the status of a crawl job. | | Web.GetCrawlData | Retrieve data from a completed crawl job. | | Web.CancelCrawl | Cancel an ongoing crawl job. | | Web.MapWebsite | Map a website from a single URL to a map of the entire website. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Web.ScrapeUrl [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#webscrapeurl) See Example > Scrape a URL and return data in specified formats. **Auth:** - **Environment Variables Required:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. **Parameters** - **`url`** _(string, required)_ The URL to scrape. - **`formats`** _(enum ( [Formats](https://docs.arcade.dev/toolkits/development/web/reference#formats)), optional)_ The format of the scraped web page. Defaults to `Formats.MARKDOWN`. - **`only_main_content`** _(bool, optional)_ Only return the main content of the page. Defaults to `True`. - **`include_tags`** _(list, optional)_ List of tags to include in the output. - **`exclude_tags`** _(list, optional)_ List of tags to exclude from the output. - **`wait_for`** _(int, optional)_ Delay in milliseconds before fetching content. Defaults to `10`. - **`timeout`** _(int, optional)_ Timeout in milliseconds for the request. Defaults to `30000`. * * * ## Web.CrawlWebsite [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#webcrawlwebsite) See Example > Crawl a website and return crawl status and data. **Auth:** - **Environment Variables Required:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. **Parameters** - **`url`** _(string, required)_ The URL to crawl. - **`exclude_paths`** _(list, optional)_ URL patterns to exclude from the crawl. - **`include_paths`** _(list, optional)_ URL patterns to include in the crawl. - **`max_depth`** _(int, required)_ Maximum depth to crawl. Defaults to `2`. - **`ignore_sitemap`** _(bool, required)_ Ignore the website sitemap. Defaults to `True`. - **`limit`** _(int, required)_ Limit the number of pages to crawl. Defaults to `10`. - **`allow_backward_links`** _(bool, required)_ Enable navigation to previously linked pages. Defaults to `False`. - **`allow_external_links`** _(bool, required)_ Allow following links to external websites. Defaults to `False`. - **`webhook`** _(string, optional)_ URL to send a POST request when the crawl is started, updated, and completed. - **`async_crawl`** _(bool, required)_ Run the crawl asynchronously. Defaults to `True`. * * * ## Web.GetCrawlStatus [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#webgetcrawlstatus) See Example > Retrieve the status of a crawl job. **Auth:** - **Environment Variables Required:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. **Parameters** - **`crawl_id`** _(string, required)_ The ID of the crawl job. * * * ## Web.GetCrawlData [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#webgetcrawldata) See Example > Retrieve data from a completed crawl job. **Auth:** - **Environment Variables Required:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. **Parameters** - **`crawl_id`** _(string, required)_ The ID of the crawl job. * * * ## Web.CancelCrawl [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#webcancelcrawl) See Example > Cancel an ongoing crawl job. **Auth:** - **Environment Variables Required:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. **Parameters** - **`crawl_id`** _(string, required)_ The ID of the asynchronous crawl job to cancel. * * * ## Web.MapWebsite [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#webmapwebsite) See Example > Map a website from a single URL to a map of the entire website. **Auth:** - **Environment Variables Required:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. **Parameters** - **`url`** _(string, required)_ The base URL to start crawling from. - **`search`** _(string, optional)_ Search query to use for mapping. - **`ignore_sitemap`** _(bool, required)_ Ignore the website sitemap. Defaults to `True`. - **`include_subdomains`** _(bool, required)_ Include subdomains of the website. Defaults to `False`. - **`limit`** _(int, required)_ Maximum number of links to return. Defaults to `5000`. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/development/web/web\#auth) The Arcade Web toolkit uses [Firecrawl](https://www.firecrawl.dev/) to scrape, crawl, and map websites. **Global Environment Variables:** - `FIRECRAWL_API_KEY`: Your [Firecrawl](https://www.firecrawl.dev/) API key. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_web\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/development/web/reference "Reference") [Stripe](https://docs.arcade.dev/toolkits/payments/stripe "Stripe") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Toolkit Template [Integrations](https://docs.arcade.dev/toolkits "Integrations") Community Toolkit Template # Arcade YOUR-TOOLKIT-NAME Toolkit The Arcade YOUR-TOOLKIT-NAME Toolkit is a community contributed toolkit meaning that it is created and maintained by the community. To learn more about the toolkit, please visit the [Arcade YOUR-TOOLKIT-NAME GitHub repository](https://github.com/YOUR-GITHUB-USERNAME/YOUR-TOOLKIT-REPO-NAME). [Contribute a toolkit](https://docs.arcade.dev/toolkits/contribute-a-toolkit "Contribute a toolkit") ## Dropbox Auth Configuration [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Dropbox # Dropbox auth provider At this time, Arcade does not offer a default Dropbox Auth Provider. To use Dropbox auth, you must create a custom Auth Provider with your own Dropbox OAuth 2.0 credentials as described below. The Dropbox auth provider enables tools and agents to call the Dropbox API on behalf of a user. Behind the scenes, the Arcade Engine and the Dropbox auth provider seamlessly manage Dropbox OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#whats-documented-here) This page describes how to use and configure Dropbox auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/dropbox#using-dropbox-auth-in-app-code) that needs to call Dropbox APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/dropbox#using-dropbox-auth-in-custom-tools) that need to call Dropbox APIs ## Configuring Dropbox auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#configuring-dropbox-auth) In a production environment, you will most likely want to use your own Dropbox app credentials. This way, your users will see your application’s name requesting permission. You can use your own Dropbox credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Dropbox app credentials, let’s go through the steps to create a Dropbox app. ### Create a Dropbox app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#create-a-dropbox-app) - Create a Dropbox Application in the [Dropbox App Console](https://www.dropbox.com/developers/apps) - In the Settings tab, under the “OAuth 2” section, set the redirect URI to: `https://cloud.arcade.dev/api/v1/oauth/callback` - In the Permissions tab, add any scopes that your app will need - In the Settings tab, copy the App key (Client ID) and App secret (Client Secret), which you’ll need below Next, add the Dropbox app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Dropbox Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#configuring-your-own-dropbox-auth-provider-in-arcade) There are two ways to configure your Dropbox app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Dropbox Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Dropbox**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-dropbox-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Dropbox app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Dropbox auth using your Arcade account credentials, the Arcade Engine will automatically use this Dropbox OAuth provider. If you have multiple Dropbox providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Dropbox auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#set-environment-variables) The Client ID is the Dropbox “App key” and the Client Secret is the Dropbox “App secret”. Set the following environment variables: ```nextra-code export DROPBOX_CLIENT_ID="" export DROPBOX_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code DROPBOX_CLIENT_SECRET="" DROPBOX_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `dropbox` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-dropbox description: "The default Dropbox provider" enabled: true type: oauth2 provider_id: dropbox client_id: ${env:DROPBOX_CLIENT_ID} client_secret: ${env:DROPBOX_CLIENT_SECRET} ``` ## Using Dropbox auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#using-dropbox-auth-in-app-code) Use the Dropbox auth provider in your own agents and AI apps to get a user-scoped token for the Dropbox API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Dropbox API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="dropbox", scopes=["openid", "sharing.read", "files.metadata.read"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "dropbox", { scopes: ["openid", "sharing.read", "files.metadata.read"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Dropbox auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/dropbox\#using-dropbox-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Dropbox API. Use the `Dropbox()` auth class to specify that a tool requires authorization with Dropbox. The `context.authorization.token` field will be automatically populated with the user’s Dropbox token: ```nextra-code from typing import Annotated, Optional import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Dropbox @tool( requires_auth=Dropbox( scopes=["files.metadata.read"], ) ) async def list_files( context: ToolContext, path: Annotated[\ Optional[str],\ "The path to the folder to list the contents of. Defaults to empty string to list the root folder.",\ ] = "", ) -> Annotated[dict, "List of servers the user is a member of"]: """Starts returning the contents of a folder.""" url = "https://api.dropboxapi.com/2/files/list_folder" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, json={"path": path}) response.raise_for_status() return response.json() ``` [Discord](https://docs.arcade.dev/home/auth-providers/discord "Discord") [GitHub](https://docs.arcade.dev/home/auth-providers/github "GitHub") ## Asana Toolkit Integration [Integrations](https://docs.arcade.dev/toolkits "Integrations") Productivity & DocsAsana # Asana **Description:** Enable agents to interact with tasks, projects, and workspaces in Asana. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/asana) **Auth:** User authorization [![PyPI Version](https://img.shields.io/pypi/v/arcade_asana)](https://pypi.org/project/arcade_asana/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_asana)](https://pypi.org/project/arcade_asana/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_asana)](https://pypi.org/project/arcade_asana/)[![Downloads](https://img.shields.io/pypi/dm/arcade_asana)](https://pypi.org/project/arcade_asana/) The Arcade Asana toolkit provides a pre-built set of tools for interacting with Asana. These tools make it easy to build agents and AI apps that can: - Manage teams, projects, and workspaces. - Create, update, and search for tasks. - Retrieve data about tasks, projects, workspaces, users, etc. - Manage task attachments. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#available-tools) | Tool Name | Description | | --- | --- | | Asana.GetProjectById | Get a project by its ID. | | Asana.ListProjects | List projects associated to one or more teams. | | Asana.GetTagById | Get a tag by its ID. | | Asana.CreateTag | Create a tag. | | Asana.ListTags | List tags associated to one or more workspaces. | | Asana.GetTasksWithoutId | Search and retrieve tasks using full-text and filters when you don't have the task ID. | | Asana.GetTaskById | Get a task by its ID. | | Asana.GetSubtasksFromATask | Get subtasks associated to a task. | | Asana.UpdateTask | Update a task. | | Asana.MarkTaskAsCompleted | Mark a task as completed. | | Asana.CreateTask | Create a task. | | Asana.AttachFileToTask | Attach a file to a task. | | Asana.ListUsers | List users that are members of one or more workspaces. | | Asana.GetUserById | Get a user by their ID. | | Asana.GetWorkspaceById | Get a workspace by its ID. | | Asana.ListWorkspaces | List the user workspaces. | | Asana.GetTeamById | Get a team by its ID. | | Asana.ListTeamsTheCurrentUserIsAMemberOf | List the teams the current user is a member of. | | Asana.ListTeams | List teams associated to a workspace. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Asana.GetProjectById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagetprojectbyid) See Example > Get a project by its ID. **Parameters** - **project\_id** _(string, required)_ The ID of the project. E.g. ‘1234567890’ ## Asana.ListProjects [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanalistprojects) See Example > List projects associated to one or more teams. **Parameters** - **team\_id** _(string, optional)_ The team ID to get projects from. Defaults to None (does not filter by team). - **workspace\_id** _(string, optional)_ The workspace ID to get projects from. Defaults to None. If not provided and the user has only one workspace, it will use that workspace. If not provided and the user has multiple workspaces, it will raise an error listing the available workspaces. - **limit** _(int, optional, Defaults to `100`)_ The maximum number of projects to return. Min is 1, max is 100. Defaults to 100. - **next\_page\_token** _(string, optional)_ The token to retrieve the next page of projects. Defaults to None (start from the first page). ## Asana.GetTagById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagettagbyid) See Example > Get a tag by its ID. **Parameters** - **tag\_id** _(string, required)_ The ID of the tag. E.g. ‘1234567890’ ## Asana.CreateTag [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanacreatetag) See Example > Create a tag. **Parameters** - **name** _(string, required)_ The name of the tag. E.g. ‘Priority’. - **description** _(string, optional)_ The description of the tag. Defaults to None (no description). - **color** _(list of enum [TagColor](https://docs.arcade.dev/toolkits/productivity/asana/reference#tagcolor), optional)_ The color of the tag. Defaults to None (no color). - **workspace\_id** _(string, None)_ The ID of the workspace to create the tag in. If not provided, it will associate the tag to the user’s workspace, if there’s only one. Otherwise, it will raise an error. ## Asana.ListTags [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanalisttags) See Example > List tags associated to one or more workspaces. **Parameters** - **workspace\_id** _(string, optional)_ The workspace ID to retrieve tags from. Defaults to None. If not provided and the user has only one workspace, it will use that workspace. If not provided and the user has multiple workspaces, it will raise an error listing the available workspaces. - **limit** _(int, optional, Defaults to `100`)_ Maximum number of items to return. Defaults to 100. Maximum allowed is 100. - **next\_page\_token** _(string, optional)_ The token to retrieve the next page of tags. Defaults to None (start from the first page). ## Asana.GetTasksWithoutId [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagettaskswithoutid) See Example > Search and retrieve tasks using full-text and filters when you don’t have the task ID. **Parameters** - **keywords** _(string, optional)_ Keywords to search for tasks. Matches against the task name and description. Defaults to None (no keyword filter). - **workspace\_id** _(string, optional)_ The workspace ID to search for tasks. Defaults to None. If not provided and the user has only one workspace, it will use that workspace. If not provided and the user has multiple workspaces, it will raise an error listing the available workspaces. - **assignee\_id** _(string, optional)_ The ID of the user to filter tasks assigned to. Defaults to None (does not filter by assignee). - **project** _(string, optional)_ The ID or name of the project to filter tasks. Defaults to None (does not filter by project). - **team\_id** _(string, optional)_ The ID of the team to filter tasks. Defaults to None (does not filter by team). - **tags** _(list of strings, optional)_ Restricts the search to tasks associated to the given tags. Each item in the list can be a tag name (e.g. ‘My Tag’) or a tag ID (e.g. ‘1234567890’). Defaults to None (searches tasks associated to any tag or no tag). - **due\_on** _(string, optional)_ Match tasks that are due exactly on this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (searches tasks due on any date or without a due date). - **due\_on\_or\_after** _(string, optional)_ Match tasks that are due on OR AFTER this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (searches tasks due on any date or without a due date). - **due\_on\_or\_before** _(string, optional)_ Match tasks that are due on OR BEFORE this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (searches tasks due on any date or without a due date). - **completed** _(bool, optional)_ Match tasks that are completed. Defaults to False (tasks that are NOT completed). - **start\_on** _(string, optional)_ Match tasks that started on this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (searches tasks started on any date or without a start date). - **start\_on\_or\_after** _(string, optional)_ Match tasks that started on OR AFTER this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (searches tasks started on any date or without a start date). - \\*\\* start\_on\_or\_before\*\* _(string, optional)_ Match tasks that started on OR BEFORE this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (searches tasks started on any date or without a start date). - **completed** _(bool, optional)_ Match tasks that are completed. Defaults to False (tasks that are NOT completed). - **limit** _(int, optional, Defaults to `20`)_ Maximum number of tasks to return. Min of 1, max of 20. Defaults to 20. - **sort\_by** _(enum [TaskSortBy](https://docs.arcade.dev/toolkits/productivity/asana/reference#tasksortby), optional)_ The field to sort the tasks by. Defaults to TaskSortBy.MODIFIED\_AT. - **sort\_order** _(enum [SortOrder](https://docs.arcade.dev/toolkits/productivity/asana/reference#sortorder), optional)_ The order to sort the tasks by. Defaults to SortOrder.DESCENDING. ## Asana.GetTaskById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagettaskbyid) See Example > Get a task by its ID. **Parameters** - **task\_id** _(string, required)_ The ID of the task. E.g. ‘1234567890’ - **max\_subtasks** _(int, optional)_ The maximum number of subtasks to return. Min of 0 (no subtasks), max of 100. Defaults to 100. ## Asana.GetSubtasksFromATask [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagetsubtasksfromatask) See Example > Get subtasks associated to a task. **Parameters** - **task\_id** _(string, required)_ The ID of the task. E.g. ‘1234567890’ - **limit** _(int, optional, Defaults to `100`)_ Maximum number of subtasks to return. Defaults to 100. Maximum allowed is 100. - **next\_page\_token** _(string, optional)_ The token to retrieve the next page of subtasks. Defaults to None (start from the first page). ## Asana.UpdateTask [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanaupdatetask) See Example > Update a task. **Parameters** - **task\_id** _(string, required)_ The ID of the task. E.g. ‘1234567890’ - **name** _(string, optional)_ The new name of the task. Defaults to None (does not change the current name). - **description** _(string, optional)_ The new description of the task. Defaults to None (does not change the current description). - **completed** _(bool, optional)_ The new completion status of the task. Provide True to mark the task as completed, False to mark it as not completed. Defaults to None (does not change the current completion status). - **start\_date** _(string, optional)_ The new start date of the task. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (does not change the current start date). - **due\_date** _(string, optional)_ The new due date of the task. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (does not change the current due date). - **assignee\_id** _(string, optional)_ The ID of the user to assign the task to. Defaults to None (does not change the current assignee). ## Asana.MarkTaskAsCompleted [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanamarktaskascompleted) See Example > Mark a task as completed. **Parameters** - **task\_id** _(string, required)_ The ID of the task. E.g. ‘1234567890’ ## Asana.CreateTask [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanacreatetask) See Example > Create a task. **Parameters** - **name** _(string, required)_ The name of the task. E.g. ‘My Task’ - **description** _(string, optional)_ The description of the task. Defaults to None (no description). - **start\_date** _(string, optional)_ The start date of the task. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no start date). - **due\_date** _(string, optional)_ The due date of the task. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no due date). - **parent\_task\_id** _(string, optional)_ The ID of the parent task. Defaults to None (no parent task). - **workspace\_id** _(string, optional)_ The ID of the workspace to associate the task to. Defaults to None. - **project** _(string, optional)_ The ID or name of the project to associate the task to. Defaults to None (no project). - **assignee\_id** _(string, optional)_ The ID of the user to assign the task to. Defaults to None (does not assign the task to anyone). - **tags** _(list of strings, optional)_ The tags to associate with the task. Multiple tags can be provided in the list. Each item in the list can be a tag name (e.g. ‘My Tag’) or a tag ID (e.g. ‘1234567890’). If a tag name does not exist, it will be automatically created with the new task. Defaults to None (no tags associated). Observations: A new task must be associated to at least one of the following: parent\_task\_id, project, or workspace\_id. If none of these are provided and the account has only one workspace, the task will be associated to that workspace. If none are provided and the account has multiple workspaces, an error will be raised with a list of available workspaces. ## Asana.AttachFileToTask [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanaattachfiletotask) See Example > Attach a file to a task. **Parameters** - **task\_id** _(string, required)_ The ID of the task. E.g. ‘1234567890’ - **file\_name** _(string, required)_ The name of the file to attach with format extension. E.g. ‘Image.png’ or ‘Report.pdf’. - **file\_content\_stream** _(string, required)_ The string contents of the file to attach. Use this if the file is a text file. Defaults to None. - **file\_content\_base64** _(string, required)_ The base64-encoded binary contents of the file. Use this for binary files like images or PDFs. Defaults to None. - **file\_content\_url** _(string, required)_ The URL of the file to attach. Use this if the file is hosted on an external URL. Defaults to None. - **file\_encoding** _(string, optional)_ The encoding of the file to attach. Only used with file\_content\_str. Defaults to ‘utf-8’. Observations: Provide exactly one of `file_content_str`, `file_content_base64`, or `file_content_url`, never more than one or none. - Use `file_content_str` for text files (will be encoded using `file_encoding`) - Use `file_content_base64` for binary files like images, PDFs, etc. - Use `file_content_url` if the file is hosted on an external URL ## Asana.ListUsers [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanalistusers) See Example > List users that are members of one or more workspaces. **Parameters** - **workspace\_id** _(string, optional)_ The workspace ID to list users from. Defaults to None. If no workspace ID is provided, it will use the current user’s workspace , if there’s only one. If the user has multiple workspaces, it will raise an error. - **limit** _(int, optional, Defaults to `500`)_ The maximum number of users to retrieve. Min is 1, max is 500. Defaults to 500. - **next\_page\_token** _(string, optional)_ The token to retrieve the next page of users. Defaults to None (start from the first page). ## Asana.GetUserById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagetuserbyid) See Example > Get a user by their ID. **Parameters** - **user\_id** _(string, required)_ The ID of the user. E.g. ‘1234567890’ ## Asana.GetTeamById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagetteambyid) See Example > Get a team by its ID. **Parameters** - **team\_id** _(string, required)_ The ID of the team. E.g. ‘1234567890’ ## Asana.ListTeamsTheCurrentUserIsAMemberOf [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanalistteamsthecurrentuserisamemberof) See Example > List the teams the current user is a member of. **Parameters** - **workspace\_id** _(string, optional)_ The workspace ID to list teams from. Defaults to None. If no workspace ID is provided, it will use the current user’s workspace , if there’s only one. If the user has multiple workspaces, it will raise an error. - **limit** _(int, optional, Defaults to `100`)_ The maximum number of teams to retrieve. Min is 1, max is 100. Defaults to 100. - **next\_page\_token** _(string, optional)_ The token to retrieve the next page of teams. Defaults to None (start from the first page). ## Asana.ListTeams [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanalistteams) See Example > List teams associated to a workspace. **Parameters** - **workspace\_id** _(string, optional)_ The workspace ID to list teams from. Defaults to None. If no workspace ID is provided, it will use the current user’s workspace, if there’s only one. If the user has multiple workspaces, it will raise an error listing the available workspaces. ## Asana.GetWorkspaceById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanagetworkspacebyid) See Example > Get a workspace by its ID. **Parameters** - **workspace\_id** _(string, required)_ The ID of the workspace. E.g. ‘1234567890’ ## Asana.ListWorkspaces [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#asanalistworkspaces) See Example > List the user workspaces. **Parameters** - **limit** _(int, optional, Defaults to `100`)_ The maximum number of workspaces to retrieve. Min is 1, max is 100. Defaults to 100. - **next\_page\_token** _(string, optional)_ The token to retrieve the next page of workspaces. Defaults to None (start from the first page). ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/asana\#auth) The Arcade Asana toolkit uses the [Asana auth provider](https://docs.arcade.dev/home/auth-providers/asana) to connect to users’ Asana accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Asana auth provider](https://docs.arcade.dev/home/auth-providers/asana#configuring-asana-auth) with your own Asana app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_asana\\ ```](https://docs.arcade.dev/home/hosting-overview) [Overview](https://docs.arcade.dev/toolkits "Overview") [Reference](https://docs.arcade.dev/toolkits/productivity/asana/reference "Reference") ## YouTube Video Search [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Youtube # YouTube Search **Description:** Enable agents to search for videos on YouTube. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade YouTube Search toolkit provides a pre-built set of tools for interacting with YouTube. These tools make it easy to build agents and AI apps that can: - Search for videos on YouTube; - Get details about a video. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/youtube\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchYoutubeVideos | Search for videos on YouTube. | | Search.GetYoutubeVideoDetails | Get details about a video on YouTube. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.SearchYoutubeVideos [Permalink for this section](https://docs.arcade.dev/toolkits/search/youtube\#searchsearchyoutubevideos) See Example > Search for videos on YouTube. **Parameters** - **keywords** _(string, required)_ Keywords to search for. E.g. ‘apple iphone’ or ‘samsung galaxy’ - **`language_code`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to use in the YouTube search. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). - **`country_code`** _(string, optional, Defaults to ‘us’ United States)_ 2-character country code to use in the YouTube search. A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). - **`next_page_token`** _(string, optional, Defaults to ‘None’)_ The next page token to use for pagination. Defaults to `None` (start from the first page). ## Search.GetYoutubeVideoDetails [Permalink for this section](https://docs.arcade.dev/toolkits/search/youtube\#searchgetyoutubevideodetails) See Example > Get details about a video on YouTube. **Parameters** - **video\_id** _(string, required)_ Video ID. E.g. ‘414600577’. This can be retrieved from the search results of the `SearchYoutubeVideos` tool. - **`language_code`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to return information about the video. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). - **`country_code`** _(string, optional, Defaults to ‘us’ United States)_ 2-character country code to return information about the video. A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/youtube\#auth) The Arcade YouTube Search toolkit uses the [SerpAPI](https://serpapi.com/) to get video information from YouTube. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Default parameter values [Permalink for this section](https://docs.arcade.dev/toolkits/search/youtube\#default-parameter-values) Language and Country are configurable through environment variables. When set, they will be used as default for YouTube tools. Providing a different value as `language_code` or `country_code` argument in a tool call will override the default value set in the environment variables. **Language** The language code is a 2-character code that determines the language in which the API will search and return video information. There are two environment variables: - `ARCADE_GOOGLE_LANGUAGE`: a default value for all Google Search tools. If not set, defaults to ‘en’ (English). - `ARCADE_YOUTUBE_SEARCH_LANGUAGE`: a default value for the YouTube Search tools. If not set, defaults to `ARCADE_GOOGLE_LANGUAGE`. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). **Country** The country code is a 2-character code that determines the country in which the API will search for videos: - `ARCADE_GOOGLE_COUNTRY`: a default value for all Google Search tools. If not set, defaults to `None`. - `ARCADE_YOUTUBE_SEARCH_COUNTRY`: a default value for the YouTube Search tools. If not set, defaults to `ARCADE_GOOGLE_COUNTRY`. If `ARCADE_GOOGLE_COUNTRY` is not set, the default country for YouTube tools will be `us` (United States). A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Walmart](https://docs.arcade.dev/toolkits/search/walmart "Walmart") [Hubspot](https://docs.arcade.dev/toolkits/sales/hubspot "Hubspot") ## Arcade X Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") X # X (Twitter) **Description:** Enable agents to interact with X (formerly Twitter). **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/x) **Auth:** User authorizationvia the [X auth provider](https://docs.arcade.dev/home/auth-providers/x) [![PyPI Version](https://img.shields.io/pypi/v/arcade_x)](https://pypi.org/project/arcade_x/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_x)](https://pypi.org/project/arcade_x/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_x)](https://pypi.org/project/arcade_x/)[![Downloads](https://img.shields.io/pypi/dm/arcade_x)](https://pypi.org/project/arcade_x/) The Arcade X (Twitter) toolkit provides a pre-built set of tools for interacting with X (formerly Twitter). These tools make it easy to build agents and AI apps that can: - Post tweets - Delete tweets - Search for tweets by username - Search for tweets by keywords - Look up a user by username ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#available-tools) These tools are currently available in the Arcade X toolkit. | Tool Name | Description | | --- | --- | | X.PostTweet | Post a tweet to X (Twitter). | | X.DeleteTweetById | Delete a tweet on X (Twitter). | | X.SearchRecentTweetsByUsername | Search recent tweets by username. | | X.SearchRecentTweetsByKeywords | Search recent tweets by keywords or phrases. | | X.LookupSingleUserByUsername | Look up a user on X (Twitter) by username. | | X.LookupTweetById | Look up a tweet by its ID | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [X auth\\ provider](https://docs.arcade.dev/home/auth-providers/x#using-x-auth-in-custom-tools). ## X.PostTweet [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#xposttweet) See Example > Post a tweet to X (Twitter). **Parameters** - **`tweet_text`** _(string, required)_ The text content of the tweet you want to post. * * * ## X.DeleteTweetById [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#xdeletetweetbyid) See Example > Delete a tweet on X (Twitter). **Parameters** - **`tweet_id`** _(string, required)_ The ID of the tweet you want to delete. * * * ## X.SearchRecentTweetsByUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#xsearchrecenttweetsbyusername) See Example > Search for recent tweets (last 7 days) on X (Twitter) by username. Includes replies and reposts. **Parameters** - **`username`** _(string, required)_ The username of the X (Twitter) user to look up. - **`max_results`** _(integer, optional, Defaults to 10)_ The maximum number of results to return. Cannot be less than 10. - **`next_token`** _(string, optional)_ The pagination token starting from which to return results. * * * ## X.SearchRecentTweetsByKeywords [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#xsearchrecenttweetsbykeywords) See Example > Search for recent tweets (last 7 days) on X (Twitter) by required keywords and phrases. Includes replies and reposts. _At least one of the following parameters must be provided: `keywords`, `phrases`._ **Parameters** - **`keywords`** _(array of strings, optional)_ List of keywords that must be present in the tweet. - **`phrases`** _(array of strings, optional)_ List of phrases that must be present in the tweet. - **`max_results`** _(integer, optional, Defaults to 10)_ The maximum number of results to return. Cannot be less than 10. * * * ## X.LookupTweetById [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#xlookuptweetbyid) See Example > Look up a tweet on X (Twitter) by its ID. **Parameters** - **`tweet_id`** _(string, required)_ The ID of the tweet to look up. * * * ## X.LookupSingleUserByUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#xlookupsingleuserbyusername) See Example > Look up a user on X (Twitter) by their username. **Parameters** - **`username`** _(string, required)_ The username of the X (Twitter) user to look up. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/x\#auth) The Arcade X (Twitter) toolkit uses the [X auth provider](https://docs.arcade.dev/home/auth-providers/x) to connect to users’ X (formerly Twitter) accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the X auth provider](https://docs.arcade.dev/home/auth-providers/x#configuring-x-auth) with your own X (formerly Twitter) app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_x\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/social-communication/twilio/reference "Reference") [Zoom](https://docs.arcade.dev/toolkits/social-communication/zoom "Zoom") ## AI Agent Deployment # Welcome to Arcade! Learn how to move AI agents from demo to production with Arcade. Arcade enables your AI agent to securely take real-world actions through user-specific permissions, pre-built integrations with Gmail, Slack, GitHub, and more. You can also build your own agentic tools and MCP servers with our authoring and testing suite. Arcade is your toolengine,registry, andruntime. Get started with a 5-minute quickstart. [Get Started](https://docs.arcade.dev/home/quickstart) [Build a tool](https://docs.arcade.dev/home/build-tools/create-a-toolkit) ## Sample Applications Get started quickly with our pre-built templates and example applications. [![Arcade Chat](https://docs.arcade.dev/_next/image?url=%2Fimages%2Fsample-apps%2Farcade-chat.png&w=3840&q=75)\\ \\ **Arcade Chat** \\ \\ A chatbot that can help you with your daily tasks.](https://chat.arcade.dev/) [![Archer](https://docs.arcade.dev/_next/image?url=%2Fimages%2Flogo%2Farcade.png&w=3840&q=75)\\ \\ **Archer** \\ \\ A bot for Slack that can act on your behalf.](https://github.com/ArcadeAI/ArcadeSlackAgent) [![Summarize YouTube Podcasts in Slack](https://docs.arcade.dev/_next/image?url=%2Fimages%2Fsample-apps%2Fslack-aipodcast-summaries.jpg&w=3840&q=75)\\ \\ **Summarize YouTube Podcasts in Slack** \\ \\ A Slack bot that extracts and summarizes YouTube transcripts in Weaviate, perfect for AI podcasts.](https://github.com/dforwardfeed/slack-AIpodcast-summaries) ## Arcade Overview ![arcade overview](https://docs.arcade.dev/_next/image?url=%2Fimages%2Foverview.png&w=1920&q=75) [Arcade Engine\\ \\ The Arcade engine is your MCP Server and Agentic tool provider. It allows you to write your tools once and serve them across any LLM or orchestration framework, no matter the protocol. The engine manages agent authentication, tool registration, and tool execution.](https://docs.arcade.dev/home#) [Control Plane\\ \\ The Control Plane is how you manage your tools, users, and deployments from a single place. No matter how large your deployment or organization gets, the Control Plane will scale with you.](https://docs.arcade.dev/home#) [Public and Private Tools\\ \\ Arcade makes it easy to develop custom tools that just work with Agents. Our SDKs and framework integrations make it easy to get started. When you are ready, it's easy to run your tools either on-prem or in our cloud.](https://docs.arcade.dev/home#) [Tools and MCP Servers Together\\ \\ The Arcade Engine is the only way to combine MCP servers with your Agentic tools. Regardless of where your tool is hosted, you can serve and manage access to it via the Engine. You easily can mix our public tools with your own private tools in your agents.](https://docs.arcade.dev/home#) [Contact us](https://docs.arcade.dev/home/contact-us "[object Object]") ## Google News Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google News # Google News **Description:** Enable agents to search for news stories with Google News. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google News toolkit provides a pre-built set of tools for interacting with Google News. These tools make it easy to build agents and AI apps that can: - Search for news stories with Google News. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_news\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchNews | Search for news stories with Google News. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.SearchNews [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_news\#searchsearchnews) See Example > Search for news stories with Google News. **Parameters** - **`query`** _(string, required)_ Keywords to search for news articles. E.g. ‘Apple launches new iPhone’. - **`country_code`** _(string, optional, Defaults to `None`)_ 2-character country code to search for news articles. E.g. ‘us’ (United States). Defaults to `None` (search news globally). - **`language`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to search for news articles. E.g. ‘en’ (English). Defaults to ‘en’ (English). - **`limit`** _(int, optional, Defaults to `None`)_ Maximum number of news articles to return. Defaults to None (returns all results found by the API). ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_news\#auth) The Arcade Google News toolkit uses the [SerpAPI](https://serpapi.com/) to get news data from Google News. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Default parameters [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_news\#default-parameters) Language and Country are configurable through environment variables. When set, they will be used as default for Google News tools. Providing a different value as `language_code` or `country_code` argument in the tool call will override the default value. **Language** The language code is a 2-character code that determines the language in which the API will search and return news articles. There are two environment variables: - `ARCADE_GOOGLE_LANGUAGE`: a default value for all Google search tools. If not set, defaults to ‘en’ (English). - `ARCADE_GOOGLE_NEWS_LANGUAGE`: a default value for the news search tools. If not set, defaults to `ARCADE_GOOGLE_LANGUAGE`. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). **Country** The country code is a 2-character code that determines the country in which the API will search for news articles. There are two environment variables: - `ARCADE_GOOGLE_NEWS_COUNTRY`: a default value for the `SearchNews` tool. If not set, defaults to `None` (search news globally). A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google Maps](https://docs.arcade.dev/toolkits/search/google_maps "Google Maps") [Google Search](https://docs.arcade.dev/toolkits/search/google_search "Google Search") ## Using Arcade Tools [Home](https://docs.arcade.dev/home "Home") [Mastra](https://docs.arcade.dev/home/mastra/overview "Mastra") Using Arcade tools This guide shows you how to integrate and use Arcade tools within a Mastra agent. For the complete working example, check out our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/tree/main/examples/mastra). ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) - Basic familiarity with TypeScript and Mastra concepts ### Create a Mastra project [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#create-a-mastra-project) Start by creating a new Mastra project using the official CLI: ```nextra-code # Create a new Mastra project npx create-mastra@latest my-arcade-agent # Navigate to the project cd my-arcade-agent ``` For more details on setting up a Mastra project, refer to the [Mastra documentation](https://mastra.ai/docs/getting-started/installation). ### Install Arcade client [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#install-arcade-client) Install the Arcade client: pnpmnpmyarn ```nextra-code pnpm add @arcadeai/arcadejs ``` ```nextra-code npm install @arcadeai/arcadejs ``` ```nextra-code yarn install @arcadeai/arcadejs ``` ### Configure API keys [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#configure-api-keys) Set up your environment with the required API keys: ```nextra-code // Set your API keys in your environment variables or .env file process.env.ARCADE_API_KEY = "your_arcade_api_key"; process.env.ANTHROPIC_API_KEY = "your_anthropic_api_key"; // or another supported model provider ``` ### Convert Arcade tools to Mastra tools [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#convert-arcade-tools-to-mastra-tools) Arcade offers methods to convert tools into Zod schemas, which is essential since Mastra defines tools using Zod. The `toZodToolSet` method is particularly useful, as it simplifies this integration and makes it easier to use Arcade’s tools with Mastra. Learn more about Arcade’s Zod integration options [here](https://docs.arcade.dev/home/use-tools/get-tool-definitions#get-zod-tool-definitions). ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; import { executeOrAuthorizeZodTool, toZodToolSet, } from "@arcadeai/arcadejs/lib"; // Initialize Arcade const arcade = new Arcade(); // Get Google tools const googleToolkit = await arcade.tools.list({ toolkit: "google", limit: 30 }); export const googleTools = toZodToolSet({ tools: googleToolkit.items, client: arcade, userId: "", // Your app's internal ID for the user (an email, UUID, etc). It's used internally to identify your user in Arcade executeFactory: executeOrAuthorizeZodTool, // Checks if tool is authorized and executes it, or returns authorization URL if needed }); ``` ### Create and configure your Mastra agent [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#create-and-configure-your-mastra-agent) Now create a Mastra agent that uses Arcade tools: ```nextra-code import { Agent } from "@mastra/core/agent"; import { anthropic } from "@ai-sdk/anthropic"; // Create the Mastra agent with Arcade tools export const googleAgent = new Agent({ name: "googleAgent", instructions: `You are a Google assistant that helps users manage their Google services (Gmail, Calendar, Sheets, Drive, and Contacts). If a tool requires authorization, you will receive an authorization URL. When that happens, clearly present this URL to the user and ask them to visit it to grant permissions.`, model: anthropic("claude-3-7-sonnet-20250219"), tools: googleTools, }); ``` ### Interact with your agent [Permalink for this section](https://docs.arcade.dev/home/mastra/use-arcade-tools\#interact-with-your-agent) You can interact with your agent in two main ways: **1\. Using the Mastra Development Playground:** Start the Mastra development server: ```nextra-code npm run dev ``` This will launch a local development playground, typically accessible at `http://localhost:4111`. Open this URL in your browser, select the `googleAgent` from the list of available agents, and start chatting with it directly in the UI. **2\. Programmatically:** Alternatively, you can interact with the agent directly in your code: ```nextra-code // Generate a response from the agent const response = await googleAgent.generate( "Read my last email and summarize it in a few sentences", ); console.log(response.text); // Or stream the response for a more interactive experience const stream = await googleAgent.stream("Send an email to dev@arcade.dev with the subject 'Hello from Mastra'"); for await (const chunk of stream.textStream) { process.stdout.write(chunk); } ``` ⚠️ When running your agent for the first time with tools that require user consent (like Google or Github), the agent will return an authorization reponse (e.g., `{ authorization_required: true, url: '...', message: '...' }`). Your agent’s instructions should guide it to present this URL to the user. After the user visits this URL and grants permissions, the tool can be used successfully. See the [Managing user authorization](https://docs.arcade.dev/home/mastra/user-auth-interrupts) guide for more details on handling authentication flows. [Overview](https://docs.arcade.dev/home/mastra/overview "Overview") [Managing user authorization](https://docs.arcade.dev/home/mastra/user-auth-interrupts "Managing user authorization") ## Reddit Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Reddit # Reddit auth provider At this time, Arcade does not offer a default Reddit Auth Provider. To use Reddit auth, you must create a custom Auth Provider with your own Reddit OAuth 2.0 credentials as described below. The Reddit auth provider enables tools and agents to call the Reddit API on behalf of a user. Behind the scenes, the Arcade Engine and the Reddit auth provider seamlessly manage Reddit OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#whats-documented-here) This page describes how to use and configure Reddit auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/reddit#using-reddit-auth-in-app-code) that needs to call Reddit APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/reddit#using-reddit-auth-in-custom-tools) that need to call Reddit APIs ## Configuring Reddit auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#configuring-reddit-auth) In a production environment, you will most likely want to use your own Reddit app credentials. This way, your users will see your application’s name requesting permission. You can use your own Reddit credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Reddit app credentials, let’s go through the steps to create a Reddit app. ### Create a Reddit app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#create-a-reddit-app) - Create a Reddit Application in the [Reddit App Console](https://www.reddit.com/prefs/apps) - Set the OAuth Redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the App key (Client ID) and App secret (Client Secret), which you’ll need below Next, add the Reddit app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Reddit Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#configuring-your-own-reddit-auth-provider-in-arcade) There are two ways to configure your Reddit app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Reddit Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Reddit**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-reddit-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Reddit app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Reddit auth using your Arcade account credentials, the Arcade Engine will automatically use this Reddit OAuth provider. If you have multiple Reddit providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Reddit auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#set-environment-variables) The Client ID is the Reddit “App key” and the Client Secret is the Reddit “App secret”. Set the following environment variables: ```nextra-code export REDDIT_CLIENT_ID="" export REDDIT_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code REDDIT_CLIENT_SECRET="" REDDIT_CLIENT_ID="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `reddit` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-reddit description: "The default Reddit provider" enabled: true type: oauth2 provider_id: reddit client_id: ${env:REDDIT_CLIENT_ID} client_secret: ${env:REDDIT_CLIENT_SECRET} ``` ## Using Reddit auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#using-reddit-auth-in-app-code) Use the Reddit auth provider in your own agents and AI apps to get a user-scoped token for the Reddit API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Reddit API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="reddit", scopes=["identity"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # TODO: Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process const authResponse = await client.auth.start(userId, "reddit", { scopes: ["identity"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Reddit auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/reddit\#using-reddit-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Reddit API. Use the `Reddit()` auth class to specify that a tool requires authorization with Reddit. The `context.authorization.token` field will be automatically populated with the user’s Reddit token: ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Reddit @tool( requires_auth=Reddit( scopes=["identity"], ) ) async def get_user_info( context: ToolContext, ) -> Annotated[dict, "The user info"]: """Get the user info for the current user.""" url = "https://oauth.reddit.com/api/v1/me" headers = { "Authorization": f"Bearer {context.authorization.token}", "User-Agent": "YourAppName v1.0 by u/YourRedditUsername", } async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json() ``` [OAuth 2.0](https://docs.arcade.dev/home/auth-providers/oauth2 "OAuth 2.0") [Salesforce](https://docs.arcade.dev/home/auth-providers/salesforce "Salesforce") ## Contribute a Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") Contribute a toolkit # How to contribute a toolkit Arcade welcomes your toolkit contributions. By adding your toolkit to the Arcade documentation, you help other developers discover and use your tools. Follow these steps to submit your own toolkit. ## Prerequisites [Permalink for this section](https://docs.arcade.dev/toolkits/contribute-a-toolkit\#prerequisites) - Build your toolkit. See [build a toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit) for guidance. - Publish your toolkit on PyPI. ## Submit your toolkit [Permalink for this section](https://docs.arcade.dev/toolkits/contribute-a-toolkit\#submit-your-toolkit) Open a pull request in the [Arcade Documentation GitHub repository](https://github.com/ArcadeAI/docs) that completes the [community toolkit checklist](https://github.com/ArcadeAI/docs/blob/main/.github/PULL_REQUEST_TEMPLATE/community_contributed_toolkit.md). The checklist will guide you through the necessary steps to ensure your toolkit contribution is successful. ## Review and merge [Permalink for this section](https://docs.arcade.dev/toolkits/contribute-a-toolkit\#review-and-merge) After submitting your pull request: - Double-check all checklist items have been completed. - Address any feedback from the reviewers. - Once approved, your toolkit will be added to the Arcade documentation for other developers to discover and use! [Salesforce](https://docs.arcade.dev/toolkits/sales/salesforce "Salesforce") ## Direct API Calls [Home](https://docs.arcade.dev/home "Home") [Authorization](https://docs.arcade.dev/home/auth/how-arcade-helps "Authorization") Direct Third-Party API Call # Direct Third-Party API Call In this guide, you’ll learn how to use Arcade to obtain user authorization and interact with third-party services by calling their API endpoints directly, without using Arcade for tool execution or definition. We’ll use Google’s Gmail API as an example to demonstrate how to: - Get authorization tokens through Arcade - Handle user authentication flows - Use tokens with external services This can be useful when you need to manage authorization flows in your application. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#prerequisites) - Sign up for an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=call-third-party-apis-directly) if you haven’t already - Generate an [Arcade API key](https://docs.arcade.dev/home/api-keys) and take note of it ### Install required libraries [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#install-required-libraries) PythonJavaScript ```nextra-code pip install arcadepy google-api-python-client google-auth-httplib2 google-auth-oauthlib ``` ```nextra-code npm install @arcadeai/arcadejs googleapis ``` ### Start coding [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#start-coding) PythonJavaScript Create a new file `direct_api_call.py` and import all libraries we’re going to use: ```nextra-code from arcadepy import Arcade from google.oauth2.credentials import Credentials from googleapiclient.discovery import build ``` Create a new file `direct_api_call.js` and import all libraries we’re going to use: ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; import { google } from "googleapis"; ``` ### Initialize the Arcade client [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#initialize-the-arcade-client) Create an instance of the Arcade client: PythonJavaScript ```nextra-code client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable ``` ```nextra-code const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable ``` ### Initiate an authorization request [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#initiate-an-authorization-request) Use `client.auth.start` to initiate the authorization process: PythonJavaScript ```nextra-code # This would be your app's internal ID for the user (an email, UUID, etc.) user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="google", scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) ``` ```nextra-code // Your app's internal ID for the user (an email, UUID, etc). It's used internally to identify your user in Arcade, not to identify with the Gmail service. const user_id = "user@example.com"; // Start the authorization process let auth_response = await client.auth.start(user_id, "google", { scopes: ["https://www.googleapis.com/auth/gmail.readonly"], }); ``` ### Guide the user through authorization [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#guide-the-user-through-authorization) If authorization is not completed, prompt the user to visit the authorization URL: PythonJavaScript ```nextra-code if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) ``` ```nextra-code if (auth_response.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(auth_response.url); } ``` ### Wait for the user to authorize the request [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#wait-for-the-user-to-authorize-the-request) PythonJavaScript ```nextra-code auth_response = client.auth.wait_for_completion(auth_response) ``` ```nextra-code auth_response = await client.auth.waitForCompletion(auth_response); ``` ### Use the obtained token [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#use-the-obtained-token) Once authorization is complete, you can use the obtained token to access the third-party service: PythonJavaScript ```nextra-code credentials = Credentials(auth_response.context.token) gmail = build("gmail", "v1", credentials=credentials) email_messages = ( gmail.users().messages().list(userId="me").execute().get("messages", []) ) print(email_messages) ``` ```nextra-code // Set up Google API client with the token const auth = new google.auth.OAuth2(); auth.setCredentials({ access_token: auth_response.context.token }); const gmail = google.gmail({ version: "v1", auth }); // List email messages const response = await gmail.users.messages.list({ userId: "me", }); const email_messages = response.data.messages || []; console.log(email_messages); ``` ### Execute the code [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#execute-the-code) PythonJavaScript ```nextra-code python3 direct_api_call.py ``` ```nextra-code node direct_api_call.js ``` You should see an output similar to this:, which is a list of the email messages returned by the Gmail API: ```nextra-code [{'id': '195f77a8ce90f2c1', 'threadId': '195f77a8ce90f2c1'}, {'id': '195ed467a90e8538', 'threadId': '195ed467a90e8538'}, ...] ``` For each item in the list/array, you could use the [`users.messages.get`](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/get) endpoint to get the full message details. Consider using the [Arcade Google toolkit](https://docs.arcade.dev/toolkits/productivity/google/gmail), which simplifies the process for retrieving email messages even further! The pattern described here is useful if you need to directly get a token to use with Google in other parts of your codebase. ### How it works [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#how-it-works) By using `client.auth.start` and `client.auth.wait_for_completion`, you leverage Arcade to manage the OAuth flow for user authorization. Arcade handles the authorization challenges and tokens, simplifying the process for you. ### Next steps [Permalink for this section](https://docs.arcade.dev/home/auth/call-third-party-apis-directly\#next-steps) Integrate this authorization flow into your application, and explore how you can manage different [auth providers](https://docs.arcade.dev/home/auth-providers) and scopes. [Checking Authorization Status](https://docs.arcade.dev/home/auth/tool-auth-status "Checking Authorization Status") [Arcade CLI](https://docs.arcade.dev/home/arcade-cli "Arcade CLI") ## Custom Auth Flow [Home](https://docs.arcade.dev/home "Home") [CrewAI](https://docs.arcade.dev/home/crewai/use-arcade-tools "CrewAI") Custom auth flow ## Custom Auth Flow with CrewAI [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#custom-auth-flow-with-crewai) In this guide, we will explore how to create a custom auth flow that will be performed before executing Arcade tools within your CrewAI agent team. The `ArcadeToolManager`’s built-in authorization and tool execution flows work well for many typical use cases. However, some scenarios call for a tailored approach. By implementing a custom auth flow, you gain flexibility in handling tool authorization. If your use case calls for a unique interface, additional approval steps, or specialized error handling, then this guide is for you. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Set up your environment [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#set-up-your-environment) Install the required package, and ensure your environment variables are set with your Arcade and OpenAI API keys: ```nextra-code pip install crewai-arcade ``` ### Configure API keys [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#configure-api-keys) Provide your Arcade and OpenAI API keys. You can store them in environment variables like so: ```nextra-code export ARCADE_API_KEY="your_arcade_api_key" export OPENAI_API_KEY="your_openai_api_key" ``` ### Define your custom auth flow [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#define-your-custom-auth-flow) The custom auth flow defined in the following code snippet is a function that will be called whenever CrewAI needs to call a tool. ```nextra-code from typing import Any from crewai_arcade import ArcadeToolManager USER_ID = "user@example.com" def custom_auth_flow( manager: ArcadeToolManager, tool_name: str, **tool_input: dict[str, Any] ) -> Any: """Custom auth flow for the ArcadeToolManager This function is called when CrewAI needs to call a tool that requires authorization. Authorization is handled before executing the tool. This function overrides the ArcadeToolManager's default auth flow performed by ArcadeToolManager.authorize_tool """ # Get authorization status auth_response = manager.authorize(tool_name, USER_ID) # If the user is not authorized for the tool, # then we need to handle the authorization before executing the tool if not manager.is_authorized(auth_response.id): print(f"Authorization required for tool: '{tool_name}' with inputs:") for input_name, input_value in tool_input.items(): print(f" {input_name}: {input_value}") # Handle authorization print(f"\nTo authorize, visit: {auth_response.url}") # Block until the user has completed the authorization auth_response = manager.wait_for_auth(auth_response) # Ensure authorization completed successfully if not manager.is_authorized(auth_response.id): raise ValueError(f"Authorization failed for {tool_name}. URL: {auth_response.url}") else: print(f"Authorization already granted for tool: '{tool_name}' with inputs:") for input_name, input_value in tool_input.items(): print(f" {input_name}: {input_value}") def tool_manager_callback(tool_manager: ArcadeToolManager, tool_name: str, **tool_input: dict[str, Any]) -> Any: """Tool executor callback with custom auth flow for the ArcadeToolManager ArcadeToolManager's default executor handles authorization and tool execution. This function overrides the default executor to handle authorization in a custom way and then executes the tool. """ custom_auth_flow(tool_manager, tool_name, **tool_input) return tool_manager.execute_tool(USER_ID, tool_name, **tool_input) ``` ### Get Arcade tools [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#get-arcade-tools) You can now provide the tool manager callback to the `ArcadeToolManager` upon initialization: ```nextra-code # Provide the tool manager callback to the ArcadeToolManager manager = ArcadeToolManager(executor=tool_manager_callback) # Retrieve the provided tools and/or toolkits as CrewAI StructuredTools. tools = manager.get_tools(tools=["Google.ListEmails"], toolkits=["Slack"]) ``` ### Use tools in your CrewAI agent team [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#use-tools-in-your-crewai-agent-team) Create a Crew that uses your tools with the custom auth flow. When the tool is called, your tool manager callback will be called to handle the authorization and then the tool will be executed. ```nextra-code from crewai import Agent, Crew, Task from crewai.llm import LLM crew_agent = Agent( role="Main Agent", backstory="You are a helpful assistant", goal="Help the user with their requests", tools=tools, allow_delegation=False, verbose=True, llm=LLM(model="gpt-4o"), ) task = Task( description="Get the 5 most recent emails from the user's inbox and summarize them and recommend a response for each.", expected_output="A bulleted list with a one sentence summary of each email and a recommended response to the email.", agent=crew_agent, tools=crew_agent.tools, ) crew = Crew( agents=[crew_agent], tasks=[task], verbose=True, memory=True, ) result = crew.kickoff() print("\n\n\n ------------ Result ------------ \n\n\n") print(result) ``` Click to view a full example ## Next steps [Permalink for this section](https://docs.arcade.dev/home/crewai/custom-auth-flow\#next-steps) Now you’re ready to integrate Arcade tools with a custom auth flow into your own CrewAI agent team. [Using Arcade tools](https://docs.arcade.dev/home/crewai/use-arcade-tools "Using Arcade tools") [Overview](https://docs.arcade.dev/home/google-adk/overview "Overview") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Drive Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Google](https://docs.arcade.dev/toolkits/productivity/google/calendar "Google") Drive # Drive **Description:** Enable agents to interact with Google Drive. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/google) **Auth:** User authorizationvia the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) [![PyPI Version](https://img.shields.io/pypi/v/arcade_google)](https://pypi.org/project/arcade_google/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_google)](https://pypi.org/project/arcade_google/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_google)](https://pypi.org/project/arcade_google/)[![Downloads](https://img.shields.io/pypi/dm/arcade_google)](https://pypi.org/project/arcade_google/) The Arcade Drive toolkit provides a pre-built set of tools for interacting with Google Drive. These tools make it easy to build agents and AI apps that can: - Search Google documents in the user’s Google Drive - Search and retrieve the contents of Google documents in the user’s Google Drive ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/drive\#available-tools) These tools are currently available in the Arcade Drive toolkit. | Tool Name | Description | | --- | --- | | Google.SearchDocuments | Search for documents in the user's Google Drive. Note: This tool currently requires a self-hosted instance of Arcade. | | Google.SearchAndRetrieveDocuments | Search and retrieve the contents of Google documents in the user's Google Drive. Note: This tool currently requires a self-hosted instance of Arcade. | | Google.GetFileTreeStructure | Get the file/folder tree structure of the user's Google Drive. | | Google.GenerateGoogleFilePickerUrl | Generate a Google File Picker URL for user-driven file selection and authorization | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Google.SearchDocuments [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/drive\#googlesearchdocuments) See Example > Search Google documents in the user’s Google Drive. Excludes documents that are in the trash. **Parameters** - **`document_contains`** _(list\[str\], optional)_ Keywords or phrases that must be in the document title or body. Provide a list of keywords or phrases if needed. - **`document_not_contains`** _(list\[str\], optional)_ Keywords or phrases that must not be in the document title or body. Provide a list of keywords or phrases if needed. - **`search_only_in_shared_drive_id`** _(str, optional)_ The ID of the shared drive to restrict the search to. If provided, the search will only return documents from this drive. Defaults to None, which searches across all drives. - **`include_shared_drives`** _(bool, optional)_ Whether to include documents from shared drives in the search results. Defaults to False (searches only in the user’s ‘My Drive’). - **`include_organization_domain_documents`** _(bool, optional)_ Whether to include documents from the organization’s domain. This is applicable to admin users who have permissions to view organization-wide documents in a Google Workspace account. Defaults to False. - **`order_by`** _(enum ( [OrderBy](https://docs.arcade.dev/toolkits/productivity/google/reference#orderby)), optional)_ Sort order. Defaults to listing the most recently modified documents first. - **`limit`** _(int, optional)_ The number of documents to list. Defaults to `50`. - **`pagination_token`** _(str, optional)_ The pagination token to continue a previous request ## Google.SearchAndRetrieveDocuments [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/drive\#googlesearchandretrievedocuments) See Example > Searches for documents in the user’s Google Drive and returns a list of documents (with text content) matching the search criteria. Excludes documents that are in the trash. **Parameters** - **`document_format`** _(enum ( [DocumentFormat](https://docs.arcade.dev/toolkits/productivity/google/reference#documentformat)), optional)_ The format of the document to be returned. Defaults to Markdown. - **`document_contains`** _(list\[str\], optional)_ Keywords or phrases that must be in the document title or body. Provide a list of keywords or phrases if needed. - **`document_not_contains`** _(list\[str\], optional)_ Keywords or phrases that must not be in the document title or body. Provide a list of keywords or phrases if needed. - **`search_only_in_shared_drive_id`** _(str, optional)_ The ID of the shared drive to restrict the search to. If provided, the search will only return documents from this drive. Defaults to None, which searches across all drives. - **`include_shared_drives`** _(bool, optional)_ Whether to include documents from shared drives in the search results. Defaults to False (searches only in the user’s ‘My Drive’). - **`include_organization_domain_documents`** _(bool, optional)_ Whether to include documents from the organization’s domain. This is applicable to admin users who have permissions to view organization-wide documents in a Google Workspace account. Defaults to False. - **`order_by`** _(enum ( [OrderBy](https://docs.arcade.dev/toolkits/productivity/google/reference#orderby)), optional)_ Sort order. Defaults to listing the most recently modified documents first. - **`limit`** _(int, optional)_ The number of documents to list. Defaults to `50`. - **`pagination_token`** _(str, optional)_ The pagination token to continue a previous request ## Google.GetFileTreeStructure [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/drive\#googlegetfiletreestructure) See Example > Get the file/folder tree structure of the user’s Google Drive. **Parameters** - **`include_shared_drives`** _(bool, optional)_ Whether to include shared drives in the file tree structure. Defaults to False. - **`restrict_to_shared_drive_id`** _(str, optional)_ If provided, only include files from this shared drive in the file tree structure. Defaults to None, which will include files and folders from all drives. - **`include_organization_domain_documents`** _(bool, optional)_ Whether to include documents from the organization’s domain. This is applicable to admin users who have permissions to view organization-wide documents in a Google Workspace account. Defaults to False. - **`order_by`** _(enum ( [OrderBy](https://docs.arcade.dev/toolkits/productivity/google/reference#orderby)), optional)_ Sort order. Defaults to listing the most recently modified documents first. - **`limit`** _(int, optional)_ The number of files and folders to list. Defaults to None, which will list all files and folders. ## Google.GenerateGoogleFilePickerUrl [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/drive\#googlegenerategooglefilepickerurl) See Example > Generate a Google File Picker URL for user-driven file selection and authorization. This tool generates a URL that directs the end-user to a Google File Picker interface where where they can select or upload Google Drive files. Users can grant permission to access their Drive files, providing a secure and authorized way to interact with their files. This is particularly useful when prior tools (e.g., those accessing or modifying Google Docs, Google Sheets, etc.) encountered failures due to file non-existence (Requested entity was not found) or permission errors. Once the user completes the file picker flow, the prior tool can be retried. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/drive\#auth) The Arcade Drive toolkit uses the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) to connect to users’ Google accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Google auth provider](https://docs.arcade.dev/home/auth-providers/google#configuring-google-auth) with your own Google app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_google\\ ```](https://docs.arcade.dev/home/hosting-overview) [Docs](https://docs.arcade.dev/toolkits/productivity/google/docs "Docs") [Gmail](https://docs.arcade.dev/toolkits/productivity/google/gmail "Gmail") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade in VS Code [Home](https://docs.arcade.dev/home "Home") [IDEs and desktop clients](https://docs.arcade.dev/home/mcp-desktop-clients/claude-desktop-client "IDEs and desktop clients") Use Arcade in Visual Studio Code # Use Arcade in Visual Studio Code In this guide, you’ll learn how to connect Visual Studio Code to Arcade.dev’s MCP server. As of version 1.100.0, Visual Studio Code does not yet support [MCP authorization](https://modelcontextprotocol.io/specification/draft/basic/authorization). Only tools that do not require auth, such as math and [search](https://docs.arcade.dev/toolkits/search/google_search) tools, will work with Visual Studio Code. We’re working to improve this - stay tuned! ### Set up Visual Studio Code [Permalink for this section](https://docs.arcade.dev/home/mcp-desktop-clients/vscode-client\#set-up-visual-studio-code) 1. Download and open [Visual Studio Code](https://code.visualstudio.com/download) (version 1.100.0 or higher) 2. Open the command palette and select **MCP: Add Server…** 3. Choose **HTTP** 4. Paste the following URL: `https://api.arcade.dev/v1/mcps/arcade-anon/mcp` This URL is Arcade’s public beta MCP server. We’d love to [hear your feedback](https://docs.arcade.dev/home/contact-us)! Coming soon: deploy a server with your own tools. 5. Give your MCP server a name, like `mcp-arcade-dev` Visual Studio Code will update your `settings.json` file with the following: ```nextra-code "mcp": { "servers": { "mcp-arcade-dev": { "url": "https://api.arcade.dev/v1/mcps/arcade-anon/mcp" } } }, ``` ### Try it out [Permalink for this section](https://docs.arcade.dev/home/mcp-desktop-clients/vscode-client\#try-it-out) 1. Open the chat pane (typically Cmd-Shift-I or Ctrl-Shift-I) 2. Make sure you are in **Agent** mode 3. Click the 🛠️ Tools button, which opens a panel of available tools 4. Click to select the tools you want to use, and type your request in the chat pane! ![Visual Studio Code tools panel](https://docs.arcade.dev/videos/vscode_mcp_demo.webp) [Use Arcade with Claude Desktop](https://docs.arcade.dev/home/mcp-desktop-clients/claude-desktop-client "Use Arcade with Claude Desktop") [Introduction](https://docs.arcade.dev/home/use-tools/tools-overview "Introduction") ## Arcade Tools Integration [Home](https://docs.arcade.dev/home "Home") LangChainUsing Arcade tools ## Use LangGraph with Arcade [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#use-langgraph-with-arcade) In this guide, let’s explore how to integrate Arcade tools into your LangGraph application. Follow the step-by-step instructions below. For complete working examples, see our [Python](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain/langgraph_arcade_minimal.py) and [JavaScript](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain-ts/langgraph-arcade-minimal.ts) examples. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Set up your environment [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#set-up-your-environment) Install the required packages, and ensure your environment variables are set with your Arcade and OpenAI API keys: PythonJavaScript ```nextra-code pip install langchain-arcade langchain-openai langgraph ``` ```nextra-code npm install @arcadeai/arcadejs @langchain/openai @langchain/core @langchain/langgraph ``` ### Configure API keys [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#configure-api-keys) Provide your Arcade and OpenAI API keys. You can store them in environment variables or directly in your code: > Need an Arcade API key? Visit the [Get an API key](https://docs.arcade.dev/home/api-keys) page to create one. PythonJavaScript ```nextra-code import os arcade_api_key = os.environ.get("ARCADE_API_KEY", "YOUR_ARCADE_API_KEY") openai_api_key = os.environ.get("OPENAI_API_KEY", "YOUR_OPENAI_API_KEY") ``` ```nextra-code ARCADE_API_KEY= OPENAI_API_KEY= ``` ### Create and manage Arcade tools [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#create-and-manage-arcade-tools) PythonJavaScript Use the ArcadeToolManager to retrieve specific tools or entire toolkits: ```nextra-code from langchain_arcade import ArcadeToolManager manager = ArcadeToolManager(api_key=arcade_api_key) # Fetch the "ScrapeUrl" tool from the "Web" toolkit tools = manager.get_tools(tools=["Web.ScrapeUrl"]) print(manager.tools) # Get all tools from the "Google" toolkit tools = manager.get_tools(toolkits=["Google"]) print(manager.tools) ``` Arcade offers methods to convert tools into Zod schemas, which is essential since LangGraph defines tools using Zod. The `toZod` method is particularly useful, as it simplifies this integration and makes it easier to use Arcade’s tools with LangGraph. Learn more about Arcade’s Zod integration options [here](https://docs.arcade.dev/home/use-tools/get-tool-definitions#get-zod-tool-definitions). ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; import { executeOrAuthorizeZodTool, toZod } from "@arcadeai/arcadejs/lib"; import { tool } from "@langchain/core/tools"; // Initialize the Arcade client const arcade = new Arcade(); // Get the Arcade tools, you can customize the toolkit (e.g. "github", "notion", "google", etc.) const googleToolkit = await arcade.tools.list({ toolkit: "google", limit: 30 }); const arcadeTools = toZod({ tools: googleToolkit.items, client: arcade, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) }); // Convert Arcade tools to LangGraph tools const tools = arcadeTools.map(({ name, description, execute, parameters }) => tool(execute, { name, description, schema: parameters, }), ); console.log(tools); ``` ### Set up the language model and memory [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#set-up-the-language-model-and-memory) Create an AI model and bind your tools. Use MemorySaver for checkpointing: PythonJavaScript ```nextra-code from langchain_openai import ChatOpenAI from langgraph.checkpoint.memory import MemorySaver model = ChatOpenAI(model="gpt-4o", api_key=openai_api_key) bound_model = model.bind_tools(tools) memory = MemorySaver() ``` ```nextra-code import { ChatOpenAI } from "@langchain/openai"; import { MemorySaver } from "@langchain/langgraph"; const model = new ChatOpenAI({ model: "gpt-4o", apiKey: process.env.OPENAI_API_KEY }); const boundModel = model.bindTools(tools); const memory = new MemorySaver(); ``` ### Create a ReAct-style agent [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#create-a-react-style-agent) Use the prebuilt ReAct agent from LangGraph to handle your Arcade tools: PythonJavaScript ```nextra-code from langgraph.prebuilt import create_react_agent graph = create_react_agent(model=bound_model, tools=tools, checkpointer=memory) ``` ```nextra-code import { createReactAgent } from "@langchain/langgraph/prebuilt"; const graph = createReactAgent({ llm: boundModel, tools, checkpointer: memory }); ``` ### Provide configuration and user query [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#provide-configuration-and-user-query) Supply a basic config dictionary and a user query. Notice that user\_id is required for tool authorization: PythonJavaScript ```nextra-code config = { "configurable": { "thread_id": "1", "user_id": "user@example.coom" } } user_input = { "messages": [\ ("user", "List any new and important emails in my inbox.")\ ] } ``` ```nextra-code const config = { configurable: { thread_id: "1", user_id: "user@example.com", }, streamMode: "values" as const, }; const user_input = { messages: [\ {\ role: "user",\ content: "List any new and important emails in my inbox.",\ },\ ], }; ``` ### Stream the response [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#stream-the-response) Stream the assistant’s output. If the tool requires authorization, the agent will ask the user to authorize the tool. PythonJavaScript ```nextra-code from langgraph.errors import NodeInterrupt try: for chunk in graph.stream(user_input, config, stream_mode="values"): chunk["messages"][-1].pretty_print() except NodeInterrupt as exc: print(f"\nNodeInterrupt occurred: {exc}") print("Please authorize the tool or update the request, then re-run.") ``` ```nextra-code try { const stream = await graph.stream(user_input, config); for await (const chunk of stream) { console.log(chunk.messages[chunk.messages.length - 1]); } } catch (error) { console.error("Error streaming response:", error); } ``` ## Tips for selecting tools [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#tips-for-selecting-tools) - **Relevance**: Pick only the tools you need. Avoid using all tools at once. - **Avoid conflicts**: Be mindful of duplicate or overlapping functionality. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/langchain/use-arcade-tools\#next-steps) Now that you have integrated Arcade tools into your LangGraph agent, you can: - Experiment with different toolkits, such as “Math” or “Search.” - Customize the agent’s prompts for specific tasks. - Try out other language models and compare their performance. Enjoy exploring Arcade and building powerful AI-enabled Python applications! [Modal](https://docs.arcade.dev/home/serve-tools/modal-worker "Modal") [User authorization](https://docs.arcade.dev/home/langchain/user-auth-interrupts "User authorization") ## Mastra Overview [Home](https://docs.arcade.dev/home "Home") MastraOverview ## Overview: Arcade Tools in Mastra [Permalink for this section](https://docs.arcade.dev/home/mastra/overview\#overview-arcade-tools-in-mastra) [Mastra](https://mastra.ai/docs) is an open-source TypeScript agent framework that provides essential primitives for building AI applications. Integrate Arcade’s extensive tool ecosystem to enhance your Mastra agents and enable them to interact seamlessly with numerous third-party services. This integration enables you to: - **Access a wide range of tools:** Use Arcade’s [pre-built tools](https://docs.arcade.dev/toolkits) for GitHub, Google Workspace, Slack, and more directly within your Mastra agent. - **Simplify tool management:** Let Arcade handle the complexities of tool discovery, execution, and authentication. - **Build sophisticated agents:** Combine Mastra’s agent framework (including memory, workflows, and RAG) with Arcade’s powerful tool capabilities. ### How it Works [Permalink for this section](https://docs.arcade.dev/home/mastra/overview\#how-it-works) The integration works through three key mechanisms: 1. **Tool Discovery:** Access available tools through a unified API ( `arcade.tools.list`). 2. **Schema Conversion:** Transform Arcade’s tool definitions into Mastra-compatible Zod schemas with the `toZodToolSet` utility, enabling seamless integration between the two frameworks without manual schema mapping. 3. **Execution Delegation:** Seamlessly route tool calls from your Mastra agent through Arcade’s API, which handles all the complexities of third-party service authentication and execution. Before starting, obtain an [Arcade API key](https://docs.arcade.dev/home/api-keys). ### Next Steps [Permalink for this section](https://docs.arcade.dev/home/mastra/overview\#next-steps) - Learn how to [use Arcade tools](https://docs.arcade.dev/home/mastra/use-arcade-tools) in a Mastra agent - Implement [user authentication handling](https://docs.arcade.dev/home/mastra/user-auth-interrupts) for tools in multi-user applications [Using Arcade tools](https://docs.arcade.dev/home/google-adk/use-arcade-tools "Using Arcade tools") [Using Arcade tools](https://docs.arcade.dev/home/mastra/use-arcade-tools "Using Arcade tools") ## Dropbox Item Categories [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Dropbox](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox "Dropbox") Reference ## DropboxItemCategory [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/dropbox/reference\#dropboxitemcategory) - **IMAGE**: `'image'` - **DOCUMENT**: `'document'` - **PDF**: `'pdf'` - **SPREADSHEET**: `'spreadsheet'` - **PRESENTATION**: `'presentation'` - **AUDIO**: `'audio'` - **VIDEO**: `'video'` - **FOLDER**: `'folder'` - **PAPER**: `'paper'` [Dropbox](https://docs.arcade.dev/toolkits/productivity/dropbox/dropbox "Dropbox") [Calendar](https://docs.arcade.dev/toolkits/productivity/google/calendar "Calendar") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## OpenAI Agents Integration [Home](https://docs.arcade.dev/home "Home") OpenAI AgentsOverview # Arcade with OpenAI Agents Arcade provides seamless integration with the [OpenAI Agents Library](https://github.com/openai/openai-python) and [OpenAI Agents JS](https://openai.github.io/openai-agents-js/), allowing you to enhance your AI agents with powerful tools including Gmail, LinkedIn, GitHub, and many more. This integration is available through the `agents-arcade` package for Python and our [JavaScript client library](https://github.com/ArcadeAI/arcade-js). ## Installation [Permalink for this section](https://docs.arcade.dev/home/oai-agents/overview\#installation) Install the necessary packages to get started: PythonJavaScript ```nextra-code pip install agents-arcade arcadepy ``` ```nextra-code npm install @openai/agents @arcadeai/arcadejs ``` Make sure you have your Arcade API key ready. [Get an API key](https://docs.arcade.dev/home/api-keys) if you don’t already have one. ## Key features [Permalink for this section](https://docs.arcade.dev/home/oai-agents/overview\#key-features) - **Easy integration** with the OpenAI Agents framework - **Access to all Arcade toolkits** including Google, GitHub, LinkedIn, X, and more - **Create custom tools** with the Arcade Tool SDK - **Manage user authentication** for tools that require it - **Asynchronous support** compatible with OpenAI’s Agent framework ## Basic usage [Permalink for this section](https://docs.arcade.dev/home/oai-agents/overview\#basic-usage) Here’s a simple example of using Arcade tools with OpenAI Agents: PythonJavaScript ```nextra-code from agents import Agent, Runner from arcadepy import AsyncArcade from agents_arcade import get_arcade_tools from agents_arcade.errors import AuthorizationError async def main(): # Initialize the Arcade client client = AsyncArcade() # Get tools from the "google" toolkit tools = await get_arcade_tools(client, toolkits=["google"]) # Create an agent with Google tools google_agent = Agent( name="Google agent", instructions="You are a helpful assistant that can assist with Google API calls.", model="gpt-4o-mini", tools=tools, ) try: # Run the agent with a unique user_id for authorization result = await Runner.run( starting_agent=google_agent, input="What are my latest emails?", context={"user_id": "user@example.com"}, ) print("Final output:\n\n", result.final_output) except AuthorizationError as e: print("Please Login to Google:", e) if __name__ == "__main__": import asyncio asyncio.run(main()) ``` Check out the complete working example in our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/tree/main/examples/openai-agents-ts/src/index.ts). ```nextra-code import Arcade from '@arcadeai/arcadejs'; import { executeOrAuthorizeZodTool, toZod } from "@arcadeai/arcadejs/lib"; import { Agent, run, tool } from '@openai/agents'; // 1) Initialize Arcade client const client = new Arcade(); // 2) Fetch Google toolkit from Arcade and prepare tools for OpenAI Agents const googleToolkit = await client.tools.list({ toolkit: "google", limit: 30 }); const tools = toZod({ tools: googleToolkit.items, client, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) executeFactory: executeOrAuthorizeZodTool, }).map(tool); // 3) Create a new agent with the Google toolkit const googleAgent = new Agent({ name: "Google agent", instructions: "You are a helpful assistant that can assist with Google API calls.", model: "gpt-4o-mini", tools }); // 4) Run the agent const result = await run(googleAgent, "What are my latest emails?"); // 5) Print the result console.log(result.finalOutput); ``` ## Handling authorization [Permalink for this section](https://docs.arcade.dev/home/oai-agents/overview\#handling-authorization) PythonJavaScript When a user needs to authorize access to a tool (like Google or GitHub), the agent will raise an `AuthorizationError` with a URL for the user to visit: ```nextra-code try: # Run agent code # ... except AuthorizationError as e: # Display the authorization URL to the user print(f"Please visit this URL to authorize: {e}") ``` When a user needs to authorize access to a tool (like Google or GitHub), the agent will show a message like this: ```nextra-code [Authorize Gmail Access](https://accounts.google.com/o/oauth2/v2/auth?access_type=offline...) Once you have authorized access, I can retrieve your latest emails. ``` After visiting the URL and authorizing access, the user can run the agent again with the same `user_id`, and it will work without requiring re-authorization. ## Available toolkits [Permalink for this section](https://docs.arcade.dev/home/oai-agents/overview\#available-toolkits) Arcade provides a variety of toolkits you can use with your agents: - **Google Suite**: Gmail, Calendar, Drive, Docs - **Social Media**: LinkedIn, X - **Development**: GitHub - **Web**: Web search, content extraction - **And more**: Weather, financial data, etc. For a full list of available toolkits, visit the [Arcade Integrations](https://docs.arcade.dev/toolkits) documentation. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/oai-agents/overview\#next-steps) Ready to start building with Arcade and OpenAI Agents? Check out these guides: - [Using Arcade tools](https://docs.arcade.dev/home/oai-agents/use-arcade-tools) \- Learn the basics of using Arcade tools with OpenAI Agents - [Managing user authorization](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts) \- Handle tool authorization efficiently - [Creating custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) \- Build your own tools with the Arcade Tool SDK Enjoy exploring Arcade and building powerful AI-enabled applications! [Managing user authorization](https://docs.arcade.dev/home/mastra/user-auth-interrupts "Managing user authorization") [Using Arcade tools](https://docs.arcade.dev/home/oai-agents/use-arcade-tools "Using Arcade tools") ## Jira Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") Jira # Jira **Description:** Enable agents to interact with Jira **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/jira) **Auth:** User authorization [![PyPI Version](https://img.shields.io/pypi/v/arcade_jira)](https://pypi.org/project/arcade_jira/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_jira)](https://pypi.org/project/arcade_jira/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_jira)](https://pypi.org/project/arcade_jira/)[![Downloads](https://img.shields.io/pypi/dm/arcade_jira)](https://pypi.org/project/arcade_jira/) The Jira toolkit provides a comprehensive set of tools for interacting with Jira, enabling users and AI applications to efficiently manage issues and projects. With this toolkit, you can: - Create, update, and search for Jira issues using various parameters. - Retrieve detailed information about issues, projects, users, and issue types. - Manage issue labels and attachments, including adding and removing them. - Transition issues between different statuses and manage comments on issues. - Browse and list available projects, priorities, and users within Jira. This toolkit streamlines the process of issue management, making it easier to integrate Jira functionalities into applications and workflows. **The Jira toolkit only supports users authenticated with a single Jira instance.** When users are prompted to authorize access to their Jira account, they will be asked to select a Jira instance. If a user selects “Instance A” and later also authenticates with “Instance B”, the toolkit will raise an exception. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#available-tools) | Tool Name | Description | | --- | --- | | Jira.ListIssueTypesByProject | Get the list of issue types (e.g. 'Task', 'Epic', etc.) available to a given project. | | Jira.GetIssueTypeById | Get the details of a Jira issue type by its ID. | | Jira.GetIssueById | Get the details of a Jira issue by its ID. | | Jira.GetIssuesWithoutId | Search for Jira issues when you don't have the issue ID(s). | | Jira.ListIssues | Get the issues for a given project. | | Jira.SearchIssuesWithoutJql | Parameterized search for Jira issues (without having to provide a JQL query). | | Jira.SearchIssuesWithJql | Search for Jira issues using a JQL (Jira Query Language) query. | | Jira.CreateIssue | Create a new Jira issue. | | Jira.AddLabelsToIssue | Add labels to an existing Jira issue. | | Jira.RemoveLabelsFromIssue | Remove labels from an existing Jira issue. | | Jira.UpdateIssue | Update an existing Jira issue. | | Jira.ListLabels | Get the existing labels (tags) in the user's Jira instance. | | Jira.ListUsers | Browse users in Jira. | | Jira.GetUserById | Get user information by their ID. | | Jira.GetUsersWithoutId | Get users without their account ID, searching by display name and email address. | | Jira.AttachFileToIssue | Add an attachment to an issue. | | Jira.ListIssueAttachmentsMetadata | Get the metadata about the files attached to an issue. | | Jira.GetAttachmentMetadata | Get the metadata of an attachment. | | Jira.DownloadAttachment | Download the contents of an attachment associated with an issue. | | Jira.GetTransitionById | Get a transition by its ID. | | Jira.GetTransitionsAvailableForIssue | Get the transitions available for an existing Jira issue. | | Jira.GetTransitionByStatusName | Get a transition available for an issue by the transition name. | | Jira.TransitionIssueToNewStatus | Transition a Jira issue to a new status. | | Jira.ListProjects | Browse projects available in Jira. | | Jira.SearchProjects | Get the details of all Jira projects. | | Jira.GetProjectById | Get the details of a Jira project by its ID or key. | | Jira.GetPriorityById | Get the details of a priority by its ID. | | Jira.ListPrioritySchemes | Browse the priority schemes available in Jira. | | Jira.ListPrioritiesAssociatedWithAPriorityScheme | Browse the priorities associated with a priority scheme. | | Jira.ListProjectsAssociatedWithAPriorityScheme | Browse the projects associated with a priority scheme. | | Jira.ListPrioritiesAvailableToAProject | Browse the priorities available to be used in issues in the specified Jira project. | | Jira.ListPrioritiesAvailableToAnIssue | Browse the priorities available to be used in the specified Jira issue. | | Jira.GetCommentById | Get a comment by its ID. | | Jira.GetIssueComments | Get the comments of a Jira issue by its ID. | | Jira.AddCommentToIssue | Add a comment to a Jira issue. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Jira.ListIssueTypesByProject [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistissuetypesbyproject) See Example > Get the list of issue types (e.g. ‘Task’, ‘Epic’, etc.) available to a given project. **Parameters** - **project** ( `string`, required) The project to get issue types for. Provide a project name, key, or ID. If a project name is provided, the tool will try to find a unique exact match among the available projects. - **limit** ( `integer`, optional) The maximum number of issue types to retrieve. Min of 1, max of 200. Defaults to 200. - **offset** ( `integer`, optional) The number of issue types to skip. Defaults to 0 (start from the first issue type). ## Jira.GetIssueTypeById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetissuetypebyid) See Example > Get the details of a Jira issue type by its ID. **Parameters** - **issue\_type\_id** ( `string`, required) The ID of the issue type to retrieve ## Jira.GetIssueById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetissuebyid) See Example > Get the details of a Jira issue by its ID. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to retrieve ## Jira.GetIssuesWithoutId [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetissueswithoutid) See Example > Search for Jira issues when you don’t have the issue ID(s). **Parameters** - **keywords** ( `string`, optional) Keywords to search for issues. Matches against the issue name, description, comments, and any custom field of type text. Defaults to None (no keywords filtering). - **due\_from** ( `string`, optional) Match issues due on or after this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no due date filtering). - **due\_until** ( `string`, optional) Match issues due on or before this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no due date filtering). - **status** ( `string`, optional) Match issues that are in this status. Provide a status name. Ex: ‘To Do’, ‘In Progress’, ‘Done’. Defaults to None (any status). - **priority** ( `string`, optional) Match issues that have this priority. Provide a priority name. E.g. ‘Highest’. Defaults to None (any priority). - **assignee** ( `string`, optional) Match issues that are assigned to this user. Provide the user’s name or email address. Ex: ‘John Doe’ or ‘ [john.doe@example.com](mailto:john.doe@example.com)’. Defaults to None (any assignee). - **project** ( `string`, optional) Match issues that are associated with this project. Provide the project’s name, ID, or key. If a project name is provided, the tool will try to find a unique exact match among the available projects. Defaults to None (search across all projects). - **issue\_type** ( `string`, optional) Match issues that are of this issue type. Provide an issue type name or ID. E.g. ‘Task’, ‘Epic’, ‘12345’. If a name is provided, the tool will try to find a unique exact match among the available issue types. Defaults to None (any issue type). - **labels** ( `array[string]`, optional) Match issues that are in these labels. Defaults to None (any label). - **parent\_issue** ( `string`, optional) Match issues that are a child of this issue. Provide the issue’s ID or key. Defaults to None (no parent issue filtering). - **limit** ( `integer`, optional) The maximum number of issues to retrieve. Min 1, max 100, default 50. - **next\_page\_token** ( `string`, optional) The token to use to get the next page of issues. Defaults to None (first page). ## Jira.ListIssues [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistissues) See Example > Get the issues for a given project. **Parameters** - **project** ( `string`, optional) The project to get issues for. Provide a project ID, key or name. If a project is not provided and 1) the user has only one project, the tool will use that; 2) the user has multiple projects, the tool will raise an error listing the available projects to choose from. - **limit** ( `integer`, optional) The maximum number of issues to retrieve. Min 1, max 100, default 50. - **next\_page\_token** ( `string`, optional) The token to use to get the next page of issues. Defaults to None (first page). ## Jira.SearchIssuesWithoutJql [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jirasearchissueswithoutjql) See Example > Parameterized search for Jira issues (without having to provide a JQL query). **Parameters** - **keywords** ( `string`, optional) Keywords to search for issues. Matches against the issue name, description, comments, and any custom field of type text. Defaults to None (no keywords filtering). - **due\_from** ( `string`, optional) Match issues due on or after this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no due date filtering). - **due\_until** ( `string`, optional) Match issues due on or before this date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no due date filtering). - **status** ( `string`, optional) Match issues that are in this status. Provide a status name. Ex: ‘To Do’, ‘In Progress’, ‘Done’. Defaults to None (any status). - **priority** ( `string`, optional) Match issues that have this priority. Provide a priority name. E.g. ‘Highest’. Defaults to None (any priority). - **assignee** ( `string`, optional) Match issues that are assigned to this user. Provide the user’s name or email address. Ex: ‘John Doe’ or ‘ [john.doe@example.com](mailto:john.doe@example.com)’. Defaults to None (any assignee). - **project** ( `string`, optional) Match issues that are associated with this project. Provide the project’s name, ID, or key. If a project name is provided, the tool will try to find a unique exact match among the available projects. Defaults to None (search across all projects). - **issue\_type** ( `string`, optional) Match issues that are of this issue type. Provide an issue type name or ID. E.g. ‘Task’, ‘Epic’, ‘12345’. If a name is provided, the tool will try to find a unique exact match among the available issue types. Defaults to None (any issue type). - **labels** ( `array[string]`, optional) Match issues that are in these labels. Defaults to None (any label). - **parent\_issue** ( `string`, optional) Match issues that are a child of this issue. Provide the issue’s ID or key. Defaults to None (no parent issue filtering). - **limit** ( `integer`, optional) The maximum number of issues to retrieve. Min 1, max 100, default 50. - **next\_page\_token** ( `string`, optional) The token to use to get the next page of issues. Defaults to None (first page). ## Jira.SearchIssuesWithJql [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jirasearchissueswithjql) See Example > Search for Jira issues using a JQL (Jira Query Language) query. **Parameters** - **jql** ( `string`, required) The JQL (Jira Query Language) query to search for issues - **limit** ( `integer`, optional) The maximum number of issues to retrieve. Min of 1, max of 100. Defaults to 50. - **next\_page\_token** ( `string`, optional) The token to use to get the next page of issues. Defaults to None (first page). ## Jira.CreateIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiracreateissue) See Example > Create a new Jira issue. **Parameters** - **title** ( `string`, required) The title of the issue. - **issue\_type** ( `string`, required) The name or ID of the issue type. If a name is provided, the tool will try to find a unique exact match among the available issue types. - **project** ( `string`, optional) The ID, key or name of the project to associate the issue with. If a name is provided, the tool will try to find a unique exact match among the available projects. Defaults to None (no project). If `project` and `parent_issue` are not provided, the tool will select the single project available. If the user has multiple, an error will be returned with the available projects to choose from. - **due\_date** ( `string`, optional) The due date of the issue. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Defaults to None (no due date). - **description** ( `string`, optional) The description of the issue. Defaults to None (no description). - **environment** ( `string`, optional) The environment of the issue. Defaults to None (no environment). - **labels** ( `array[string]`, optional) The labels of the issue. Defaults to None (no labels). A label cannot contain spaces. If a label is provided with spaces, they will be trimmed and replaced by underscores. - **parent\_issue** ( `string`, optional) The ID or key of the parent issue. Defaults to None (no parent issue). Must provide at least one of `parent_issue` or `project` arguments. - **priority** ( `string`, optional) The ID or name of the priority to use for the issue. If a name is provided, the tool will try to find a unique exact match among the available priorities. Defaults to None (the issue is created with Jira’s default priority for the specified project). - **assignee** ( `string`, optional) The name, email or ID of the user to assign the issue to. If a name or email is provided, the tool will try to find a unique exact match among the available users. Defaults to None (no assignee). - **reporter** ( `string`, optional) The name, email or ID of the user who is the reporter of the issue. If a name or email is provided, the tool will try to find a unique exact match among the available users. Defaults to None (no reporter). ## Jira.AddLabelsToIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiraaddlabelstoissue) See Example > Add labels to an existing Jira issue. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to update - **labels** ( `array[string]`, required) The labels to add to the issue. A label cannot contain spaces. If a label is provided with spaces, they will be trimmed and replaced by underscores. - **notify\_watchers** ( `boolean`, optional) Whether to notify the issue’s watchers. Defaults to True (notifies watchers). ## Jira.RemoveLabelsFromIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiraremovelabelsfromissue) See Example > Remove labels from an existing Jira issue. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to update - **labels** ( `array[string]`, required) The labels to remove from the issue (case-insensitive) - **notify\_watchers** ( `boolean`, optional) Whether to notify the issue’s watchers. Defaults to True (notifies watchers). ## Jira.UpdateIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiraupdateissue) See Example > Update an existing Jira issue. **Parameters** - **issue** ( `string`, required) The key or ID of the issue to update - **title** ( `string`, optional) The new issue title. Provide an empty string to clear the title. Defaults to None (does not change the title). - **description** ( `string`, optional) The new issue description. Provide an empty string to clear the description. Defaults to None (does not change the description). - **environment** ( `string`, optional) The new issue environment. Provide an empty string to clear the environment. Defaults to None (does not change the environment). - **due\_date** ( `string`, optional) The new issue due date. Format: YYYY-MM-DD. Ex: ‘2025-01-01’. Provide an empty string to clear the due date. Defaults to None (does not change the due date). - **issue\_type** ( `string`, optional) The new issue type name or ID. If a name is provided, the tool will try to find a unique exact match among the available issue types. Defaults to None (does not change the issue type). - **priority** ( `string`, optional) The name or ID of the new issue priority. If a name is provided, the tool will try to find a unique exact match among the available priorities. Defaults to None (does not change the priority). - **parent\_issue** ( `string`, optional) The ID or key of the parent issue. A parent cannot be removed by providing an empty string. It is possible to change the parent issue by providing a new issue ID or key, or to leave it unchanged. Defaults to None (does not change the parent issue). - **assignee** ( `string`, optional) The new issue assignee name, email, or ID. If a name or email is provided, the tool will try to find a unique exact match among the available users. Provide an empty string to remove the assignee. Defaults to None (does not change the assignee). - **reporter** ( `string`, optional) The new issue reporter name, email, or ID. If a name or email is provided, the tool will try to find a unique exact match among the available users. Provide an empty string to remove the reporter. Defaults to None (does not change the reporter). - **labels** ( `array[string]`, optional) The new issue labels. This argument will replace all labels with the new list. Providing an empty list will remove all labels. To add or remove a subset of labels, use the `Jira.AddLabelsToIssue` or the `Jira.RemoveLabelsFromIssue` tools. Defaults to None (does not change the labels). A label cannot contain spaces. If a label is provided with spaces, they will be trimmed and replaced by underscores. - **notify\_watchers** ( `boolean`, optional) Whether to notify the issue’s watchers. Defaults to True (notifies watchers). ## Jira.ListLabels [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistlabels) See Example > Get the existing labels (tags) in the user’s Jira instance. **Parameters** - **limit** ( `integer`, optional) The maximum number of labels to return. Min of 1, Max of 200. Defaults to 200. - **offset** ( `integer`, optional) The number of labels to skip. Defaults to 0 (starts from the first label) ## Jira.ListUsers [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistusers) See Example > Browse users in Jira. **Parameters** - **account\_type** ( `string`, optional) The account type of the users to return. Defaults to ‘atlassian’. Provide `None` to disable filtering by account type. The account type filter will be applied after retrieving users from Jira API, thus the tool may return less users than the limit and still have more users to paginate. Check the `pagination` key in the response dictionary. - **limit** ( `integer`, optional) The maximum number of users to return. Min of 1, max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of users to skip before starting to return users. Defaults to 0 (start from the first user). ## Jira.GetUserById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetuserbyid) See Example > Get user information by their ID. **Parameters** - **user\_id** ( `string`, required) The the user’s ID. ## Jira.GetUsersWithoutId [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetuserswithoutid) See Example > Get users without their account ID, searching by display name and email address. **Parameters** - **name\_or\_email** ( `string`, required) The user’s display name or email address to search for (case-insensitive). The string can match the prefix of the user’s attribute. For example, a string of ‘john’ will match users with a display name or email address that starts with ‘john’, such as ‘John Doe’, ‘Johnson’, ‘ [john@example.com](mailto:john@example.com)’, etc. - **enforce\_exact\_match** ( `boolean`, optional) Whether to enforce an exact match of the name\_or\_email against users’ display name and email attributes. Defaults to False (return all users that match the prefix). If set to True, before returning results, the tool will filter users with a display name OR email address that match exactly the value of the `name_or_email` argument. - **limit** ( `integer`, optional) The maximum number of users to return. Min of 1, max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of users to skip before starting to return users. Defaults to 0 (start from the first user). ## Jira.AttachFileToIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiraattachfiletoissue) See Example > Add an attachment to an issue. **Parameters** - **issue** ( `string`, required) The issue ID or key to add the attachment to - **filename** ( `string`, required) The name of the file to add as an attachment. The filename should contain the file extension (e.g. ‘test.txt’, ‘report.pdf’), but it is not mandatory. - **file\_content\_str** ( `string`, optional) The string content of the file to attach. Use this if the file is a text file. Defaults to None. - **file\_content\_base64** ( `string`, optional) The base64-encoded binary contents of the file. Use this for binary files like images or PDFs. Defaults to None. - **file\_encoding** ( `string`, optional) The encoding of the file to attach. Only used with file\_content\_str. Defaults to ‘utf-8’. - **file\_type** ( `string`, optional) The type of the file to attach. E.g. ‘application/pdf’, ‘text’, ‘image/png’. If not provided, the tool will try to infer the type from the filename. If the filename is not recognized, it will attach the file without specifying a type. Defaults to None (infer from filename or attach without type). ## Jira.ListIssueAttachmentsMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistissueattachmentsmetadata) See Example > Get the metadata about the files attached to an issue. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to retrieve ## Jira.GetAttachmentMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetattachmentmetadata) See Example > Get the metadata of an attachment. **Parameters** - **attachment\_id** ( `string`, required) The ID of the attachment to retrieve ## Jira.DownloadAttachment [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiradownloadattachment) See Example > Download the contents of an attachment associated with an issue. **Parameters** - **attachment\_id** ( `string`, required) The ID of the attachment to download ## Jira.GetTransitionById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragettransitionbyid) See Example > Get a transition by its ID. **Parameters** - **issue** ( `string`, required) The ID or key of the issue - **transition\_id** ( `string`, required) The ID of the transition ## Jira.GetTransitionsAvailableForIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragettransitionsavailableforissue) See Example > Get the transitions available for an existing Jira issue. **Parameters** - **issue** ( `string`, required) The ID or key of the issue ## Jira.GetTransitionByStatusName [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragettransitionbystatusname) See Example > Get a transition available for an issue by the transition name. **Parameters** - **issue** ( `string`, required) The ID or key of the issue - **transition** ( `string`, required) The name of the transition status ## Jira.TransitionIssueToNewStatus [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiratransitionissuetonewstatus) See Example > Transition a Jira issue to a new status. **Parameters** - **issue** ( `string`, required) The ID or key of the issue - **transition** ( `string`, required) The transition to perform. Provide the transition ID or its name (case insensitive). ## Jira.ListProjects [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistprojects) See Example > Browse projects available in Jira. **Parameters** - **limit** ( `integer`, optional) The maximum number of projects to return. Min of 1, Max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of projects to skip. Defaults to 0 (starts from the first project) ## Jira.SearchProjects [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jirasearchprojects) See Example > Get the details of all Jira projects. **Parameters** - **keywords** ( `string`, optional) The keywords to search for projects. Matches against project name and key (case insensitive). Defaults to None (no keywords filter). - **limit** ( `integer`, optional) The maximum number of projects to return. Min of 1, Max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of projects to skip. Defaults to 0 (starts from the first project) ## Jira.GetProjectById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetprojectbyid) See Example > Get the details of a Jira project by its ID or key. **Parameters** - **project** ( `string`, required) The ID or key of the project to retrieve ## Jira.GetPriorityById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetprioritybyid) See Example > Get the details of a priority by its ID. **Parameters** - **priority\_id** ( `string`, required) The ID of the priority to retrieve. ## Jira.ListPrioritySchemes [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistpriorityschemes) See Example > Browse the priority schemes available in Jira. **Parameters** - **scheme\_name** ( `string`, optional) Filter by scheme name. Defaults to None (returns all scheme names). - **limit** ( `integer`, optional) The maximum number of priority schemes to return. Min of 1, max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of priority schemes to skip. Defaults to 0 (start from the first scheme). - **order\_by** ( `Enum` [PrioritySchemeOrderBy](https://docs.arcade.dev/toolkits/productivity/jira/reference#PrioritySchemeOrderBy), optional) The order in which to return the priority schemes. Defaults to name ascending. ## Jira.ListPrioritiesAssociatedWithAPriorityScheme [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistprioritiesassociatedwithapriorityscheme) See Example > Browse the priorities associated with a priority scheme. **Parameters** - **scheme\_id** ( `string`, required) The ID of the priority scheme to retrieve priorities for. - **limit** ( `integer`, optional) The maximum number of priority schemes to return. Min of 1, max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of priority schemes to skip. Defaults to 0 (start from the first scheme). ## Jira.ListProjectsAssociatedWithAPriorityScheme [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistprojectsassociatedwithapriorityscheme) See Example > Browse the projects associated with a priority scheme. **Parameters** - **scheme\_id** ( `string`, required) The ID of the priority scheme to retrieve projects for. - **project** ( `string`, optional) Filter by project ID, key or name. Defaults to None (returns all projects). - **limit** ( `integer`, optional) The maximum number of projects to return. Min of 1, max of 50. Defaults to 50. - **offset** ( `integer`, optional) The number of projects to skip. Defaults to 0 (start from the first project). ## Jira.ListPrioritiesAvailableToAProject [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistprioritiesavailabletoaproject) See Example > Browse the priorities available to be used in issues in the specified Jira project. **Parameters** - **project** ( `string`, required) The ID, key or name of the project to retrieve priorities for. ## Jira.ListPrioritiesAvailableToAnIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiralistprioritiesavailabletoanissue) See Example > Browse the priorities available to be used in the specified Jira issue. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to retrieve priorities for. ## Jira.GetCommentById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetcommentbyid) See Example > Get a comment by its ID. **Parameters** - **issue\_id** ( `string`, required) The ID or key of the issue to retrieve the comment from. - **comment\_id** ( `string`, required) The ID of the comment to retrieve - **include\_adf\_content** ( `boolean`, optional) Whether to include the ADF (Atlassian Document Format) content of the comment in the response. Defaults to False (return only the HTML rendered content). ## Jira.GetIssueComments [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiragetissuecomments) See Example > Get the comments of a Jira issue by its ID. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to retrieve - **limit** ( `integer`, optional) The maximum number of comments to retrieve. Min 1, max 100, default 100. - **offset** ( `integer`, optional) The number of comments to skip. Defaults to 0 (start from the first comment). - **order\_by** ( `Enum` [IssueCommentOrderBy](https://docs.arcade.dev/toolkits/productivity/jira/reference#IssueCommentOrderBy), optional) The order in which to return the comments. Defaults to ‘created\_date\_descending’ (most recent first). - **include\_adf\_content** ( `boolean`, optional) Whether to include the ADF (Atlassian Document Format) content of the comment in the response. Defaults to False (return only the HTML rendered content). ## Jira.AddCommentToIssue [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#jiraaddcommenttoissue) See Example > Add a comment to a Jira issue. **Parameters** - **issue** ( `string`, required) The ID or key of the issue to comment on. - **body** ( `string`, required) The body of the comment to add to the issue. - **reply\_to\_comment** ( `string`, optional) Quote a previous comment as a reply to it. Provide the comment’s ID. Must be a comment from the same issue. Defaults to None (no quoted comment). - **mention\_users** ( `array[string]`, optional) The users to mention in the comment. Provide the user display name, email address, or ID. Ex: ‘John Doe’ or ‘ [john.doe@example.com](mailto:john.doe@example.com)’. Defaults to None (no user mentions). ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira\#auth) The Arcade Jira toolkit uses the [Atlassian auth provider](https://docs.arcade.dev/home/auth-providers/atlassian) to connect to users’ Jira accounts. Please refer to the [Atlassian auth provider](https://docs.arcade.dev/home/auth-providers/atlassian) documentation to learn how to configure auth. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_jira\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reference](https://docs.arcade.dev/toolkits/productivity/google/reference "Reference") [Environment Variables](https://docs.arcade.dev/toolkits/productivity/jira/environment_variables "Environment Variables") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Slack Toolkit Integration [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") Slack # Slack **Description:** Enable agents to interact with Slack by sending messages, retrieving user and conversation information. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/slack) **Auth:** User authorizationvia the [Slack auth provider](https://docs.arcade.dev/home/auth-providers/slack) [![PyPI Version](https://img.shields.io/pypi/v/arcade_slack)](https://pypi.org/project/arcade_slack/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_slack)](https://pypi.org/project/arcade_slack/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_slack)](https://pypi.org/project/arcade_slack/)[![Downloads](https://img.shields.io/pypi/dm/arcade_slack)](https://pypi.org/project/arcade_slack/) The Arcade Slack toolkit provides a comprehensive set of tools for interacting with Slack. With these tools, you can build agents and AI applications that can: - Send direct messages to users - Send messages to channels - Retrieve members of conversations - Access conversation messages - Manage conversation metadata - Retrieve user information - List users - List conversations - Retrieve messages in a channel, direct or multi-person conversation - Retrieve conversation metadata If you intend to use this toolkit for commercial purposes, you must [create your own Slack App](https://docs.arcade.dev/home/auth-providers/slack#create-a-slack-app) and seek [Marketplace approval](https://api.slack.com/slack-marketplace/using), according to Slack API [Terms of Service](https://slack.com/terms-of-service/api). ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#available-tools) These tools are currently available in the Arcade Slack toolkit. | Tool Name | Description | | --- | --- | | Slack.SendDmToUser | Send a direct message to a user in Slack. | | Slack.SendMessageToChannel | Send a message to a channel in Slack. | | GetMembersInConversationById | Retrieve members of a conversation using its ID. | | GetMembersInChannelByName | Retrieve members of a channel using its name. | | GetMessagesInConversationById | Fetch the messages in a conversation using its ID. | | GetMessagesInChannelByName | Fetch the messages in a channel using its name. | | GetMessagesInDirectMessageConversationByUsername | Fetch the messages in a direct message conversation using the username of the other participant. | | GetMessagesInMultiPersonDmConversationByUsername | Fetch the messages in a multi-person direct message conversation using the usernames of the other participants. | | GetConversationMetadataById | Retrieve metadata of a conversation using its ID. | | GetChannelMetadataByName | Retrieve metadata of a channel using its name. | | GetDirectMessageConversationMetadataByUsername | Retrieve metadata of a direct message conversation using the username of the other participant. | | GetMultiPersonDmConversationMetadataByUsername | Retrieve metadata of a multi-person direct message conversation using the usernames of the other participants. | | Slack.ListConversationsMetadata | List metadata for Slack conversations. | | ListPublicChannelsMetadata | List metadata for public channels in Slack. | | ListPrivateChannelsMetadata | List metadata for private channels in Slack. | | ListGroupDirectMessageConversationsMetadata | List metadata for group direct message conversations in Slack. | | ListDirectMessageConversationsMetadata | List metadata for direct message conversations in Slack. | | Slack.GetUserInfoById | Retrieve information of a user by their ID. | | Slack.ListUsers | List all users in the authenticated Slack team. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your own\\ tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Slack auth\\ provider](https://docs.arcade.dev/home/auth-providers/slack#using-slack-auth-in-custom-tools). ## Slack.SendDmToUser [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#slacksenddmtouser) See Example > Send a direct message to a user in Slack. **Parameters** - **`user_name`** _(string, required)_ The Slack username of the person you want to message. Slack usernames are ALWAYS lowercase. - **`message`** _(string, required)_ The message you want to send. * * * ## Slack.SendMessageToChannel [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#slacksendmessagetochannel) See Example > Send a message to a channel in Slack. **Parameters** - **`channel_name`** _(string, required)_ The Slack channel name where you want to send the message. Slack channel names are ALWAYS lowercase. - **`message`** _(string, required)_ The message you want to send. * * * ## GetMembersInConversationById [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmembersinconversationbyid) See Example > Get the members of a conversation in Slack by the conversation’s ID. **Parameters** - **`conversation_id`** _(string, required)_ The ID of the conversation to get members for. - **`limit`** _(int, optional)_ The maximum number of members to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## GetMembersInChannelByName [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmembersinchannelbyname) See Example > Get the members of a channel in Slack by the channel’s name. **Parameters** - **`channel_name`** _(string, required)_ The name of the channel to get members for. - **`limit`** _(int, optional)_ The maximum number of members to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## GetMessagesInConversationById [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmessagesinconversationbyid) See Example > Slack Apps that are not [Marketplace](https://api.slack.com/slack-marketplace/using)-approved [will be limited](https://api.slack.com/changelog/2025-05-terms-rate-limit-update-and-faq) to 1 request/minute and up to 15 objects returned per request when using this tool. Get the history of a conversation in Slack. **Parameters** - **`conversation_id`** _(string, required)_ The ID of the conversation to get history for. - **`oldest_relative`** _(string, optional)_ The oldest message to include, in ‘DD:HH:MM’ format. - **`latest_relative`** _(string, optional)_ The latest message to include, in ‘DD:HH:MM’ format. - **`oldest_datetime`** _(string, optional)_ The oldest message to include, in ‘YYYY-MM-DD HH:MM:SS’ format. - **`latest_datetime`** _(string, optional)_ The latest message to include, in ‘YYYY-MM-DD HH:MM:SS’ format. - **`limit`** _(int, optional)_ The maximum number of messages to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination, if continuing from a previous search. * * * ## GetMessagesInChannelByName [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmessagesinchannelbyname) See Example > Slack Apps that are not [Marketplace](https://api.slack.com/slack-marketplace/using)-approved [will be limited](https://api.slack.com/changelog/2025-05-terms-rate-limit-update-and-faq) to 1 request/minute and up to 15 objects returned per request when using this tool. Get the messages in a channel in Slack. **Parameters** - **`channel_name`** _(string, required)_ The name of the channel to get messages for. - **`oldest_relative`** _(string, optional)_ The oldest message to include in the results, specified as a time offset from the current time in the format ‘DD:HH:MM’. - **`latest_relative`** _(string, optional)_ The latest message to include in the results, specified as a time offset from the current time in the format ‘DD:HH:MM’. - **`oldest_datetime`** _(string, optional)_ The oldest message to include in the results, specified as a datetime string in the format ‘YYYY-MM-DD HH:MM:SS’. - **`latest_datetime`** _(string, optional)_ The latest message to include in the results, specified as a datetime string in the format ‘YYYY-MM-DD HH:MM:SS’. - **`limit`** _(int, optional)_ The maximum number of messages to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## GetMessagesInDirectMessageConversationByUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmessagesindirectmessageconversationbyusername) See Example > Slack Apps that are not [Marketplace](https://api.slack.com/slack-marketplace/using)-approved [will be limited](https://api.slack.com/changelog/2025-05-terms-rate-limit-update-and-faq) to 1 request/minute and up to 15 objects returned per request when using this tool. Get the messages in a Direct Message conversation with another user in Slack. **Parameters** - **`username`** _(string, required)_ The username of the user to get messages with. - **`oldest_relative`** _(string, optional)_ The oldest message to include in the results, specified as a time offset from the current time in the format ‘DD:HH:MM’. - **`latest_relative`** _(string, optional)_ The latest message to include in the results, specified as a time offset from the current time in the format ‘DD:HH:MM’. - **`oldest_datetime`** _(string, optional)_ The oldest message to include in the results, specified as a datetime string in the format ‘YYYY-MM-DD HH:MM:SS’. - **`latest_datetime`** _(string, optional)_ The latest message to include in the results, specified as a datetime string in the format ‘YYYY-MM-DD HH:MM:SS’. - **`limit`** _(int, optional)_ The maximum number of messages to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## GetMessagesInMultiPersonDmConversationByUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmessagesinmultipersondmconversationbyusername) See Example > Slack Apps that are not [Marketplace](https://api.slack.com/slack-marketplace/using)-approved [will be limited](https://api.slack.com/changelog/2025-05-terms-rate-limit-update-and-faq) to 1 request/minute and up to 15 objects returned per request when using this tool. Get the messages in a multi-person direct message conversation in Slack by the usernames of the participants (other than the currently authenticated user). **Parameters** - **`usernames`** _(list of strings, required)_ The usernames of the users to get messages with. - **`oldest_relative`** _(string, optional)_ The oldest message to include in the results, specified as a time offset from the current time in the format ‘DD:HH:MM’. - **`latest_relative`** _(string, optional)_ The latest message to include in the results, specified as a time offset from the current time in the format ‘DD:HH:MM’. - **`oldest_datetime`** _(string, optional)_ The oldest message to include in the results, specified as a datetime string in the format ‘YYYY-MM-DD HH:MM:SS’. - **`latest_datetime`** _(string, optional)_ The latest message to include in the results, specified as a datetime string in the format ‘YYYY-MM-DD HH:MM:SS’. - **`limit`** _(int, optional)_ The maximum number of messages to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## GetConversationMetadataById [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getconversationmetadatabyid) See Example > Get the metadata of a conversation in Slack searching by its ID. **Parameters** - **`conversation_id`** _(string, required)_ The ID of the conversation to get metadata for. * * * ## GetChannelMetadataByName [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getchannelmetadatabyname) See Example > Get the metadata of a channel in Slack searching by its name. **Parameters** - **`channel_name`** _(string, required)_ The name of the channel to get metadata for. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination, if continuing from a previous search. * * * ## GetDirectMessageConversationMetadataByUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getdirectmessageconversationmetadatabyusername) See Example > Get the metadata of a direct message conversation in Slack searching by the username of the other participant. **Parameters** - **`username`** _(string, required)_ The username of the user/person to get messages with. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination, if continuing from a previous search. * * * ## GetMultiPersonDmConversationMetadataByUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#getmultipersondmconversationmetadatabyusername) See Example > Get the metadata of a multi-person direct message conversation in Slack searching by the usernames of the participants (other than the currently authenticated user). **Parameters** - **`usernames`** _(list of strings, required)_ The usernames of the users to get messages with. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination, if continuing from a previous search. * * * ## Slack.ListConversationsMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#slacklistconversationsmetadata) See Example > List metadata for Slack conversations (channels and/or direct messages) that the user is a member of. **Parameters** - **`conversation_types`** _(list of str, optional)_ The type(s) of conversations to list. Defaults to all types. Each must be one of: ‘public\_channel’, ‘private\_channel’, ‘multi\_person\_direct\_message’, or ‘direct\_message’. - **`limit`** _(int, optional)_ The maximum number of conversations to list. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## ListPublicChannelsMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#listpublicchannelsmetadata) See Example > List metadata for public channels in Slack that the user is a member of. **Parameters** - **`limit`** _(int, optional)_ The maximum number of channels to list. Defaults to 200. * * * ## ListPrivateChannelsMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#listprivatechannelsmetadata) See Example > List metadata for private channels in Slack that the user is a member of. **Parameters** - **`limit`** _(int, optional)_ The maximum number of channels to list. Defaults to 200. * * * ## ListGroupDirectMessageConversationsMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#listgroupdirectmessageconversationsmetadata) See Example > List metadata for group direct message conversations in Slack that the user is a member of. **Parameters** - **`limit`** _(int, optional)_ The maximum number of conversations to list. Defaults to 200. * * * ## ListDirectMessageConversationsMetadata [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#listdirectmessageconversationsmetadata) See Example > List metadata for direct message conversations in Slack that the user is a member of. **Parameters** - **`limit`** _(int, optional)_ The maximum number of channels to list. Defaults to 200. * * * ## Slack.GetUserInfoById [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#slackgetuserinfobyid) See Example > Get the information of a user in Slack. **Parameters** - **`user_id`** _(string, required)_ The ID of the user to get. * * * ## Slack.ListUsers [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#slacklistusers) See Example > List all users in the authenticated user’s Slack team. **Parameters** - **`exclude_bots`** _(bool, optional)_ Whether to exclude bots from the results. Defaults to `True`. - **`limit`** _(int, optional)_ The maximum number of users to return. Defaults to 200. - **`next_cursor`** _(string, optional)_ The cursor to use for pagination. * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/slack\#auth) The Arcade Slack toolkit uses the [Slack auth provider](https://docs.arcade.dev/home/auth-providers/slack) to connect to users’ Slack accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Slack auth provider](https://docs.arcade.dev/home/auth-providers/slack#configuring-slack-auth) with your own Slack app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_slack\\ ```](https://docs.arcade.dev/home/hosting-overview) [LinkedIn](https://docs.arcade.dev/toolkits/social-communication/linkedin "LinkedIn") [Readme](https://docs.arcade.dev/toolkits/social-communication/twilio/readme "Readme") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Reddit Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") Reddit # Reddit **Description:** Enable agents to interact with Reddit. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/reddit) **Auth:** User authorizationvia the [Reddit auth provider](https://docs.arcade.dev/home/auth-providers/reddit) [![PyPI Version](https://img.shields.io/pypi/v/arcade_reddit)](https://pypi.org/project/arcade_reddit/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_reddit)](https://pypi.org/project/arcade_reddit/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_reddit)](https://pypi.org/project/arcade_reddit/)[![Downloads](https://img.shields.io/pypi/dm/arcade_reddit)](https://pypi.org/project/arcade_reddit/) The Arcade Reddit toolkit provides a pre-built set of tools for interacting with Reddit. These tools make it easy to build agents and AI apps that can: - Submit text posts - Comment on posts - Reply to comments - Get posts (title and other metadata) in a subreddit - Get content (body) of posts - Get top-level comments of a post - Determine if a subreddit exists or is private - Get rules of a subreddit - Get the authenticated user’s username - Get posts by the authenticated user ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#available-tools) These tools are currently available in the Arcade Reddit toolkit. | Tool Name | Description | | --- | --- | | Reddit.SubmitTextPost | Submit a text-based post to Reddit. | | Reddit.CommentOnPost | Comment on a Reddit post. | | Reddit.ReplyToComment | Reply to a Reddit comment. | | Reddit.GetPostsInSubreddit | Gets posts titles, links, and other metadata in the specified subreddit | | Reddit.GetContentOfPost | Get content (body) of a Reddit post. | | Reddit.GetContentOfMultiplePosts | Get content (body) of multiple Reddit posts. | | Reddit.GetTopLevelCommentsOfPost | Get the first page of top-level comments of a Reddit post. | | Reddit.CheckSubredditAccess | Check whether a user has access to a subreddit, including whether it exists | | Reddit.GetSubredditRules | Get the rules of a subreddit | | Reddit.GetMyUsername | Get the authenticated user's username | | Reddit.GetMyPosts | Get posts created by the authenticated user | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Reddit auth\\ provider](https://docs.arcade.dev/home/auth-providers/reddit#using-reddit-auth-in-custom-tools). ## Reddit.SubmitTextPost [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditsubmittextpost) See Example > Submit a text-based post to a subreddit **Parameters** - **`subreddit`** _(string, required)_ The name of the subreddit to which the post will be submitted. - **`title`** _(string, required)_ The title of the submission. - **`body`** _(string, optional)_ The body of the post in markdown format. Should never be the same as the title. - **`nsfw`** _(boolean, optional)_ Indicates if the submission is NSFW. Default is `False`. - **`spoiler`** _(boolean, optional)_ Indicates if the post is marked as a spoiler. Default is `False`. - **`send_replies`** _(boolean, optional)_ If true, sends replies to the user’s inbox. Default is `True`. * * * ## Reddit.CommentOnPost [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditcommentonpost) See Example > Comment on a Reddit post. **Parameters** - **`post_identifier`** _(string, required)_ The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id. - **`text`** _(string, required)_ The body of the comment in markdown format. * * * ## Reddit.ReplyToComment [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditreplytocomment) See Example > Reply to a Reddit comment **Parameters** - **`comment_identifier`** _(string, required)_ The identifier of the Reddit comment to reply to. The identifier may be a comment ID, a Reddit URL to the comment, a permalink to the comment, or the fullname of the comment. - **`text`** _(string, required)_ The body of the reply in markdown format. * * * ## Reddit.GetPostsInSubreddit [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgetpostsinsubreddit) See Example > Gets posts titles, links, and other metadata in the specified subreddit. The time\_range is required if the listing type is ‘top’ or ‘controversial’. **Parameters** - **`subreddit`** _(string, required)_ The name of the subreddit to fetch posts from. - **`listing`** _(enum ( [SubredditListingType](https://docs.arcade.dev/toolkits/social-communication/reddit#subredditlistingtype)), optional)_ The type of listing to fetch. For simple listings such as ‘hot’, ‘new’, or ‘rising’, the time\_range parameter is ignored. For time-based listings such as ‘top’ or ‘controversial’, the ‘time\_range’ parameter is required. Default is ‘hot’. - **`limit`** _(integer, optional)_ The maximum number of posts to fetch. Default is 10, max is 100. - **`cursor`** _(str, optional)_ The pagination token from a previous call. - **`time_range`** _(enum ( [RedditTimeFilter](https://docs.arcade.dev/toolkits/social-communication/reddit#reddittimefilter)), optional)_ The time range for filtering posts. Must be provided if the listing type is ‘top’ or ‘controversial’. Otherwise, it is ignored. Defaults to ‘today’. * * * ## Reddit.GetContentOfPost [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgetcontentofpost) See Example > Get the content (body) of a Reddit post by its identifier. **Parameters** - **`post_identifier`** _(string, required)_ The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id. * * * ## Reddit.GetContentOfMultiplePosts [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgetcontentofmultipleposts) See Example > Get the content (body) of multiple Reddit posts by their identifiers in a single request **Parameters** - **`post_identifiers`** _(list of strings, required)_ A list of identifiers of the Reddit posts. The identifiers may be Reddit URLs, permalinks, fullnames, or post ids. * * * ## Reddit.GetTopLevelCommentsOfPost [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgettoplevelcommentsofpost) See Example > Get the first page of top-level comments of a Reddit post. **Parameters** - **`post_identifier`** _(string, required)_ The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id. * * * ## Reddit.CheckSubredditAccess [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditchecksubredditaccess) See Example > Checks whether the specified subreddit exists and also if it is accessible to the authenticated user. **Parameters** - **`subreddit`** _(string, required)_ The name of the subreddit to check. * * * ## Reddit.GetSubredditRules [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgetsubredditrules) See Example > Gets the rules of the specified subreddit **Parameters** - **`subreddit`** _(string, required)_ The name of the subreddit for which to fetch rules. * * * ## Reddit.GetMyUsername [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgetmyusername) See Example > Gets the username of the authenticated user. * * * ## Reddit.GetMyPosts [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#redditgetmyposts) See Example > Get posts that were created by the authenticated user sorted by newest first **Parameters** - **`limit`** _(integer, optional)_ The maximum number of posts to fetch. Default is 10, max is 100. - **`include_body`** _(boolean, optional)_ Whether to include the body of the posts in the response. Default is `True`. - **`cursor`** _(str, optional)_ The pagination token from a previous call. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#auth) The Arcade Reddit toolkit uses the [Reddit auth provider](https://docs.arcade.dev/home/auth-providers/reddit) to connect to users’ Reddit accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Reddit auth provider](https://docs.arcade.dev/home/auth-providers/reddit#configuring-reddit-auth) with your own Reddit app credentials. ## Reference [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#reference) ### SubredditListingType [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#subredditlistingtype) The type of listing to fetch. - **`HOT`** _(string: “hot”)_: The hottest posts in the subreddit. - **`NEW`** _(string: “new”)_: The newest posts in the subreddit. - **`RISING`** _(string: “rising”)_: The posts that are trending up in the subreddit. - **`TOP`** _(string: “top”)_: The top posts in the subreddit (time-based). - **`CONTROVERSIAL`** _(string: “controversial”)_: The posts that are currently controversial in the subreddit (time-based). ### RedditTimeFilter [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/reddit\#reddittimefilter) The time range for filtering posts. - **`NOW`** _(string: “NOW”)_ - **`TODAY`** _(string: “TODAY”)_ - **`THIS_WEEK`** _(string: “THIS\_WEEK”)_ - **`THIS_MONTH`** _(string: “THIS\_MONTH”)_ - **`THIS_YEAR`** _(string: “THIS\_YEAR”)_ - **`ALL_TIME`** _(string: “ALL\_TIME”)_ ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_reddit\\ ```](https://docs.arcade.dev/home/hosting-overview) [Zoom](https://docs.arcade.dev/toolkits/social-communication/zoom "Zoom") [Spotify](https://docs.arcade.dev/toolkits/entertainment/spotify "Spotify") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Understanding ToolContext [Home](https://docs.arcade.dev/home "Home") [Build tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Build tools") Tool Context # Understanding ToolContext ## What is ToolContext? [Permalink for this section](https://docs.arcade.dev/home/build-tools/tool-context\#what-is-toolcontext) `ToolContext` is a crucial component in Arcade that manages authorization and user information for tools requiring authentication. Let’s explore how it works and how you can use it in your projects. `ToolContext` is a class that holds two main pieces of information: 1. Authorization context: This includes a token for making authenticated requests to external APIs as well as structured user information for providers that support retrieving user information. 2. User ID: This identifies the user invoking the tool. Some authorization providers may also include additional structured user information in the `ToolContext`. ## How ToolContext Works [Permalink for this section](https://docs.arcade.dev/home/build-tools/tool-context\#how-toolcontext-works) When you invoke a tool that requires authorization, Arcade’s Tool SDK automatically: 1. Creates a `ToolContext` object 2. Passes this object to your tool You can then use the `ToolContext` object to make authenticated requests to external APIs. ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/build-tools/tool-context\#next-steps) Now that you understand the basics of `ToolContext`, you’re ready to apply this knowledge in creating your own authorized tools. To learn how to build a custom tool that requires user authorization, check out our guide on [adding user authorization to your tools](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth) or [adding secrets to your tools](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets). [Create a toolkit](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Create a toolkit") [Create a tool with auth](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth "Create a tool with auth") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Configuration Templates [Home](https://docs.arcade.dev/home "Home") [Local Deployment](https://docs.arcade.dev/home/local-deployment/install "Local Deployment") [Configure](https://docs.arcade.dev/home/local-deployment/configure/overview "Configure") Configuration Templates # Engine Config Templates ### engine.yaml [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/templates\#engineyaml) ```nextra-code # yaml-language-server: $schema=https://raw.githubusercontent.com/ArcadeAI/schemas/main/engine/config/1.0/schema.json $schema: https://raw.githubusercontent.com/ArcadeAI/schemas/main/engine/config/1.0/schema.json api: development: ${env:API_DEVELOPMENT} host: ${env:ARCADE_API_HOST} port: ${env:ARCADE_API_PORT} auth: providers: - id: default-atlassian description: 'The default Atlassian provider' enabled: false type: oauth2 provider_id: atlassian client_id: ${env:ATLASSIAN_CLIENT_ID} client_secret: ${env:ATLASSIAN_CLIENT_SECRET} - id: default-discord description: 'The default Discord provider' enabled: false type: oauth2 provider_id: discord client_id: ${env:DISCORD_CLIENT_ID} client_secret: ${env:DISCORD_CLIENT_SECRET} - id: default-dropbox description: 'The default Dropbox provider' enabled: false type: oauth2 provider_id: dropbox client_id: ${env:DROPBOX_CLIENT_ID} client_secret: ${env:DROPBOX_CLIENT_SECRET} - id: default-github description: 'The default GitHub provider' enabled: false type: oauth2 provider_id: github client_id: ${env:GITHUB_CLIENT_ID} client_secret: ${env:GITHUB_CLIENT_SECRET} - id: default-google description: 'The default Google provider' enabled: false type: oauth2 provider_id: google client_id: ${env:GOOGLE_CLIENT_ID} client_secret: ${env:GOOGLE_CLIENT_SECRET} - id: default-linkedin description: 'The default LinkedIn provider' enabled: false type: oauth2 provider_id: linkedin client_id: ${env:LINKEDIN_CLIENT_ID} client_secret: ${env:LINKEDIN_CLIENT_SECRET} - id: default-microsoft description: 'The default Microsoft provider' enabled: false type: oauth2 provider_id: microsoft client_id: ${env:MICROSOFT_CLIENT_ID} client_secret: ${env:MICROSOFT_CLIENT_SECRET} - id: default-reddit description: 'The default Reddit provider' enabled: false type: oauth2 provider_id: reddit client_id: ${env:REDDIT_CLIENT_ID} client_secret: ${env:REDDIT_CLIENT_SECRET} - id: default-slack description: 'The default Slack provider' enabled: false type: oauth2 provider_id: slack client_id: ${env:SLACK_CLIENT_ID} client_secret: ${env:SLACK_CLIENT_SECRET} - id: default-spotify description: 'The default Spotify provider' enabled: false type: oauth2 provider_id: spotify client_id: ${env:SPOTIFY_CLIENT_ID} client_secret: ${env:SPOTIFY_CLIENT_SECRET} - id: default-twitch description: 'The default Twitch provider' enabled: false type: oauth2 provider_id: twitch client_id: ${env:TWITCH_CLIENT_ID} client_secret: ${env:TWITCH_CLIENT_SECRET} - id: default-x description: 'The default X provider' enabled: false type: oauth2 provider_id: x client_id: ${env:X_CLIENT_ID} client_secret: ${env:X_CLIENT_SECRET} - id: default-zoom description: 'The default Zoom provider' enabled: false type: oauth2 provider_id: zoom client_id: ${env:ZOOM_CLIENT_ID} client_secret: ${env:ZOOM_CLIENT_SECRET} llm: models: - id: my-openai-model-provider openai: api_key: ${env:OPENAI_API_KEY} #- id: my-anthropic-model-provider # anthropic: # api_key: ${env:ANTHROPIC_API_KEY} # - id: my-ollama-model-provider # openai: # base_url: http://localhost:11434 # chat_endpoint: /v1/chat/completions # model: llama3.2 # api_key: ollama #- id: my-groq-model-provider # openai: # base_url: 'https://api.groq.com/openai/v1' # api_key: ${env:GROQ_API_KEY} security: root_keys: - id: key1 default: true value: ${env:ROOT_KEY_1} storage: postgres: user: ${env:POSTGRES_USER} password: ${env:POSTGRES_PASSWORD} host: ${env:POSTGRES_HOST} port: ${env:POSTGRES_PORT} db: ${env:POSTGRES_DB} sslmode: require telemetry: environment: ${env:TELEMETRY_ENVIRONMENT} logging: # debug, info, warn, error level: ${env:TELEMETRY_LOGGING_LEVEL} encoding: ${env:TELEMETRY_LOGGING_ENCODING} tools: directors: - id: default enabled: true max_tools: 64 workers: - id: worker enabled: true http: uri: ${env:ARCADE_WORKER_URI} timeout: 30 retry: 3 secret: ${env:ARCADE_WORKER_SECRET} ``` ### engine.env [Permalink for this section](https://docs.arcade.dev/home/local-deployment/configure/templates\#engineenv) ```nextra-code ### Engine configuration ### API_DEVELOPMENT=true ARCADE_API_HOST=localhost ARCADE_API_PORT=9099 ANALYTICS_ENABLED=true # Encryption keys (change this when deploying to production) ROOT_KEY_1=default-key-value ### Model Provider API keys ### # OPENAI_API_KEY= # ANTHROPIC_API_KEY= # GROQ_API_KEY= ### Security configuration ### ROOT_KEY_1= ### Storage configuration ### # POSTGRES_USER= # POSTGRES_PASSWORD= # POSTGRES_HOST= # POSTGRES_PORT= # POSTGRES_DB= ### Telemetry (OTEL) configuration ### TELEMETRY_ENVIRONMENT=local TELEMETRY_LOGGING_LEVEL=debug TELEMETRY_LOGGING_ENCODING=console ### Worker Configuration ### ARCADE_WORKER_URI=http://localhost:8002 ARCADE_WORKER_SECRET=dev # OAuth Providers ATLASSIAN_CLIENT_ID="" ATLASSIAN_CLIENT_SECRET= DISCORD_CLIENT_ID="" DISCORD_CLIENT_SECRET= DROPBOX_CLIENT_ID="" DROPBOX_CLIENT_SECRET= GITHUB_CLIENT_ID="" GITHUB_CLIENT_SECRET= GOOGLE_CLIENT_ID="" GOOGLE_CLIENT_SECRET= LINKEDIN_CLIENT_ID="" LINKEDIN_CLIENT_SECRET= MICROSOFT_CLIENT_ID="" MICROSOFT_CLIENT_SECRET= REDDIT_CLIENT_ID="" REDDIT_CLIENT_SECRET= SLACK_CLIENT_ID="" SLACK_CLIENT_SECRET= SPOTIFY_CLIENT_ID="" SPOTIFY_CLIENT_SECRET= TWITCH_CLIENT_ID="" SPOTIFY_CLIENT_SECRET= X_CLIENT_ID="" X_CLIENT_SECRET= ZOOM_CLIENT_ID="" ZOOM_CLIENT_SECRET= ``` [Configuring Arcade Deploy](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy "Configuring Arcade Deploy") [Overview](https://docs.arcade.dev/home/auth-providers "Overview") ## Jira Environment Variables [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Jira](https://docs.arcade.dev/toolkits/productivity/jira "Jira") Environment Variables # Jira Environment Variables ### `JIRA_MAX_CONCURRENT_REQUESTS` [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira/environment_variables\#jira_max_concurrent_requests) Arcade uses asynchronous calls to request Jira API endpoints. In some tools, multiple concurrent HTTP requests may be made to speed up execution. This environment variable controls the maximum number of concurrent requests to Jira API in any tool execution. The value must be a numeric string with an integer greater than or equal to 1. **Default:** `3` ### `JIRA_API_REQUEST_TIMEOUT` [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira/environment_variables\#jira_api_request_timeout) Controls the maximum number of seconds to wait for a response from the Jira API. This is also applied, in some cases, as a global max timeout for multiple requests that are made in a single tool execution. For instance, when a tool needs to paginate results from a given endpoint, this timeout may apply to the entire pagination process in total, not only to the individual requests. The value must be a numeric string with an integer greater than or equal to 1. **Default:** `30` ### `JIRA_CACHE_MAX_ITEMS` [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/jira/environment_variables\#jira_cache_max_items) The caching strategy does not involve caching Jira API responses that go into tool output, but only internal values. The Arcade Jira toolkit will cache some values that are repeatedly used in tool execution to enable better performance. This environment variable controls the maximum number of items to hold in each cache. The value must be a numeric string with an integer greater than or equal to 1. **Default:** `5000` [Jira](https://docs.arcade.dev/toolkits/productivity/jira "Jira") [Reference](https://docs.arcade.dev/toolkits/productivity/jira/reference "Reference") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Clients Overview [Home](https://docs.arcade.dev/home "Home") Arcade Clients # Arcade Clients Arcade provides clients for several languages. These clients make it easy to use Arcade’s tools within your agents and applications. ## Python Client [Permalink for this section](https://docs.arcade.dev/home/arcade-clients\#python-client) Install with: `pip install arcadepy` Learn more about the [Python Client](https://github.com/ArcadeAI/arcade-py). ## JavaScript / TypeScript Client [Permalink for this section](https://docs.arcade.dev/home/arcade-clients\#javascript--typescript-client) Install with: `npm install @arcadeai/arcadejs` Learn more about the [JavaScript / TypeScript Client](https://github.com/ArcadeAI/arcade-js). ## Go Client [Permalink for this section](https://docs.arcade.dev/home/arcade-clients\#go-client) Install with: `go get -u 'github.com/ArcadeAI/arcade-go'` Learn more about the [Go Client](https://github.com/ArcadeAI/arcade-go). [Arcade CLI](https://docs.arcade.dev/home/arcade-cli "Arcade CLI") [Overview](https://docs.arcade.dev/home/hosting-overview "Overview") ## GitHub Toolkit Reference [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Developer Tools](https://docs.arcade.dev/toolkits/development/code-sandbox "Developer Tools") [GitHub](https://docs.arcade.dev/toolkits/development/github/github "GitHub") Reference # Reference for GitHub Toolkit ## PRSortProperty [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#prsortproperty) Specifies the property to sort pull requests by. - **`CREATED`**: Sort by creation date. - **`UPDATED`**: Sort by last update date. - **`POPULARITY`**: Sort by popularity. - **`LONG_RUNNING`**: Sort by how long the pull request has been open. ## PRState [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#prstate) Specifies the state of pull requests to return. - **`OPEN`**: Open pull requests. - **`CLOSED`**: Closed pull requests. - **`ALL`**: All pull requests. ## ReviewCommentSortProperty [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#reviewcommentsortproperty) Specifies the property to sort review comments by. - **`CREATED`**: Sort by creation date. - **`UPDATED`**: Sort by last update date. ## ReviewCommentSubjectType [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#reviewcommentsubjecttype) Specifies the type of subject for review comments. - **`FILE`**: Comments on the entire file. - **`LINE`**: Comments on a specific line. ## DiffSide [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#diffside) Specifies the side of the diff that the pull request’s changes appear on. - **`LEFT`**: For deletions that appear in red. - **`RIGHT`**: For additions that appear in green or unchanged lines that appear in white and are shown for context. ## RepoType [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#repotype) Specifies the type of repositories to return. - **`ALL`**: All repositories. - **`PUBLIC`**: Public repositories only. - **`PRIVATE`**: Private repositories only. - **`FORKS`**: Forked repositories only. - **`SOURCES`**: Source repositories only (not forks). - **`MEMBER`**: Repositories to which the user has explicit permission. ## RepoSortProperty [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#reposortproperty) Specifies the property to sort repositories by. - **`CREATED`**: Sort by creation date. - **`UPDATED`**: Sort by last update date. - **`PUSHED`**: Sort by last push date. - **`FULL_NAME`**: Sort by full name. ## RepoTimePeriod [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#repotimeperiod) Specifies the time period to filter by when listing repository activities. - **`DAY`**: Activities from the last day. - **`WEEK`**: Activities from the last week. - **`MONTH`**: Activities from the last month. - **`QUARTER`**: Activities from the last quarter. - **`YEAR`**: Activities from the last year. ## ActivityType [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#activitytype) Specifies the activity type to filter by when listing repository activities. - **`PUSH`**: Regular push events. - **`FORCE_PUSH`**: Force push events. - **`BRANCH_CREATION`**: Branch creation events. - **`BRANCH_DELETION`**: Branch deletion events. - **`PR_MERGE`**: Pull request merge events. - **`MERGE_QUEUE_MERGE`**: Merge queue merge events. ## SortDirection [Permalink for this section](https://docs.arcade.dev/toolkits/development/github/reference\#sortdirection) Specifies the direction to sort results. - **`ASC`**: Sort in ascending order. - **`DESC`**: Sort in descending order. [GitHub](https://docs.arcade.dev/toolkits/development/github/github "GitHub") [Reference](https://docs.arcade.dev/toolkits/development/web/reference "Reference") ## Arcade V2 Migration [Home](https://docs.arcade.dev/home "Home") Migrate to V2 # Migration Guide If your project does not have its dependency on `arcade-ai` pinned to the v1 major version, you must pin it to the v1 major version immediately to prevent potential breakages. ## Release Timeline [Permalink for this section](https://docs.arcade.dev/home/migrate-to-v2\#release-timeline) Version 2.0.0 of the Arcade CLI was released on **Tuesday, June 17th**. Make sure to pin your project’s dependency on `arcade-ai` to the v1 major version before this date to avoid any disruptions. ## Package Changes [Permalink for this section](https://docs.arcade.dev/home/migrate-to-v2\#package-changes) With the release of version 2.0.0, the [arcade-ai PyPI package](https://pypi.org/project/arcade-ai/) has been divided into three distinct packages. Previously, `arcade-ai` was a monolithic package that included: - Tool Development Kit (TDK) - Core execution engine and catalog functionality - FastAPI/MCP server/worker components - CLI functionality - Evaluation framework Now, the `arcade-ai` package serves as Arcade.dev’s CLI, allowing you to create ‘starter’ toolkits, serve and deploy toolkits, chat, and more via the command line. Also, two new packages have been introduced: `arcade-serve` and `arcade-tdk`. This means faster build times, lighter dependencies, and better performance. ## Package Overview [Permalink for this section](https://docs.arcade.dev/home/migrate-to-v2\#package-overview) - **arcade-ai**: - To get [the CLI](https://docs.arcade.dev/home/arcade-cli), install via: `pip install arcade-ai` - To get [the evaluation framework](https://docs.arcade.dev/home/build-tools/evaluation-framework), install via: `pip install 'arcade-ai[evals]'` - To get everything including the TDK and Serve, install via: `pip install 'arcade-ai[all]'` - **arcade-tdk**: - If you’re [writing your own](https://docs.arcade.dev/home/build-tools/create-a-toolkit) Arcade tools/toolkits. - Install via: `pip install arcade-tdk` - **arcade-serve**: - If you’re [writing your own](https://docs.arcade.dev/home/serve-tools/modal-worker) custom worker. - Install via: `pip install arcade-serve` ## Code Migration Steps [Permalink for this section](https://docs.arcade.dev/home/migrate-to-v2\#code-migration-steps) Migrating from v1 to v2 is straightforward with a few find-and-replace actions: 1. Replace all occurrences of `arcade.sdk.eval` with `arcade_evals`. 2. Replace all remaining occurrences of `arcade.sdk` with `arcade_tdk`. 3. Replace all occurrences of `arcade.worker` with `arcade_serve`. 4. Remove your project’s required dependency on `arcade-ai`. 5. Add `arcade_tdk>=2.0.0,<3.0.0` as a required dependency if you replaced `arcade.sdk` with `arcade_tdk` in step 2. 6. Add `arcade-ai[evals]>=2.0.0,<3.0.0` as an optional dev dependency if you use the evaluation framework or the CLI. 7. Add `arcade-serve>=2.0.0,<3.0.0` as an optional dev dependency if you use the `arcade serve` CLI command. [Registry Early Access](https://docs.arcade.dev/home/registry-early-access "Registry Early Access") ## Salesforce Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Salesforce # Salesforce Auth Provider At this time, Arcade does not offer a default Salesforce Auth Provider and cannot support Salesforce auth in the Arcade Cloud. To use Salesforce auth, the [Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce), or to develop your [custom Salesforce tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit), you must [self-host the Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) and create a custom Auth Provider with your own Salesforce OAuth 2.0 credentials as described below. The Salesforce auth provider enables tools and agents to call Salesforce APIs on behalf of a user. Behind the scenes, the Arcade Engine and the Salesforce auth provider seamlessly manage Salesforce OAuth 2.0 authorization for your users. ## What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#whats-documented-here) This page describes how to use and configure Salesforce auth with Arcade. This auth provider is used by: - The [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce), which provides pre-built tools for interacting with Salesforce services - Your [app code](https://docs.arcade.dev/home/auth-providers/salesforce#calling-salesforce-apis-directly) that needs to call Salesforce APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/salesforce#create-your-own-salesforce-tools) that need to call Salesforce APIs ## Create a Salesforce app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#create-a-salesforce-app) Salesforce has two types of apps: **Connected App** and **Lightning App**. For this guide, we’ll create a **Connected App**. Make sure to follow the instructions below while you [create your Connected App](https://help.salesforce.com/s/articleView?id=xcloud.connected_app_create.htm&type=5). When creating your app, make sure to: - Under “API (Enable OAuth Settings)”, check the **Enable OAuth Settings** box - Set the callback URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - In the **Available OAuth Scopes**, add the two following scopes: - “Manage User Data Via APIs (api)” - “Perform requests at any time (refresh\_token, offline\_access)” - Uncheck the **Require Proof Key for Code Exchange (PKCE)** option, unless you want to use PKCE (in which case, you’ll also need to enable PKCE in the Salesforce auth configuration as [described below](https://docs.arcade.dev/home/auth-providers/salesforce#configuring-salesforce-auth)) - Check “Enable Token Exchange Flow” - Check “Enable Refresh Token Rotation” - Leave all other settings as default and save your app Right after creating the app, Salesforce will redirect you to the app’s page. In the “API (Enable OAuth Settings)” section, click on the **Manage Consumer Details** button and take note of the **API Key** and **Client Secret** values. Then, go back to the App’s page and click on the **Manage** button at the top, then click on the **Edit Policies** button, at the top of the Manage page, and follow the instructions below: - In “IP Relaxation”, select **Relax IP Restrictions**. - In “Refresh Token Policy”, make sure the option **Refresh token is valid until revoked** is checked. With that, your Salesforce app is ready to be used with Arcade. ## Get your Salesforce Org Subdomain [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#get-your-salesforce-org-subdomain) Follow the steps below to find your Salesforce Org Subdomain: 1. In the Setup menu, click on **Quick Find** in the top left corner and type `"my domain"`. 2. In the search results, under **Company Settings**, click on **My Domain**. 3. Under **My Domain Details**, check the value of the **Current My Domain URL** field. Your **Salesforce Org Subdomain** is the value before the `.my.salesforce.com` part. For example, if your Salesforce domain is `https://acme-inc.my.salesforce.com`, your Salesforce Org Subdomain is `acme-inc`. If you have a developer account, your URL might look like `https://acme-inc.develop.my.salesforce.com`. In this case, your Salesforce Org Subdomain is `acme-inc.develop`. Take note of your Salesforce Org Subdomain. You will need this value in the next steps. ## Set the Salesforce Org Subdomain Environment Variable [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#set-the-salesforce-org-subdomain-environment-variable) Refer to the [previous step](https://docs.arcade.dev/home/auth-providers/salesforce#get-your-salesforce-org-subdomain) to find your Salesforce Org Subdomain. Set the `SALESFORCE_ORG_SUBDOMAIN` environment variable in the same runtime where your Arcade Worker is executed: ```nextra-code export SALESFORCE_ORG_SUBDOMAIN={your-salesforce-subdomain} ``` ## Create and Assign Custom Scopes to your Connected App [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#create-and-assign-custom-scopes-to-your-connected-app) The Salesforce API requires the App developer to create [OAuth custom scopes](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_customscopes.htm&type=5) defining granular permissions for their application users to authorize. The custom scopes required by the [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce) are listed below, along with their descriptions: The custom scopes listed below are only required if you are using the [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce). If you’re creating your own [custom Salesforce tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) or using Arcade to authorize users and call Salesforce APIs directly, you are free to define custom scope(s) that fit best your application use cases. Observe that you must have at least one custom scope assigned to your Salesforce app in order to use the Salesforce API. - `read_account`: Read access to account data. - `read_contact`: Read access to contact data. - `read_lead`: Read access to lead data. - `read_note`: Read access to note data. - `read_opportunity`: Read access to opportunity data. - `read_task`: Read access to task data. - `write_contact`: Write access to create contact. Follow the [Create an OAuth Custom Scope](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_customscopes_create.htm&type=5) and [Assign an OAuth Custom Scope to a Connected App](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_customscopes_assign.htm&type=5) Salesforce documentation to understand how to define and assign these scopes to your Salesforce app. The scope names aren’t really attached to any endpoint or action. It’s the developer’s job to honor the permissions communicated to the user when authorizing the app. You could, in theory, assign one single scope (e.g. `fullaccess`) and use it to query any Salesforce API endpoint. ## Configuring Salesforce Auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#configuring-salesforce-auth) Refer to [Installing Arcade Locally](https://docs.arcade.dev/home/local-deployment/install/local) for more information on how to install and run the Arcade Engine. You can either configure Salesforce auth from the Arcade Engine Dashboard graphical interface or in the `engine.yaml` file. We describe both options below. Dashboard GUIEngine Configuration YAML ### Configure Salesforce Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#access-the-arcade-dashboard) By default, the Arcade Dashboard will be available at `http://localhost:9099/dashboard` (if you’re accessing it from the same machine where it’s running). Change the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Custom Provider** tab at the top. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#enter-the-provider-details) - Enter `salesforce` as the **ID** for your provider (the ID must be `salesforce` in order to use the [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce)). - Optionally enter a **Description**. - Enter your **Client ID** and **Client Secret** from your Salesforce app. #### Configure the auth endpoints [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#configure-the-auth-endpoints) Replace `salesforce-org-subdomain` with your [Salesforce Org Subdomain](https://docs.arcade.dev/home/auth-providers/salesforce#get-your-salesforce-org-subdomain). - Enter the auth endpoints: - **Authorization Endpoint**: `https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/authorize` - **Token Endpoint**: `https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/token` - Under **Refresh Token Settings**: - Enter the **Refresh Token Endpoint**: `https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/token` - In **Response Content Type**, select `application/json`. - Under **Token Introspection Settings**: - Check the **Enable Token Introspection** option. - Enter the **Token Introspection Endpoint**: `https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/introspect` - In **HTTP Method**, select `POST` - In **Authentication Method**, select `Client Secret Basic` - In **Request Content Type**, select `application/x-www-form-urlencoded`. - Under **Request Parameters** section, add the following key-value pair: - **Key**: `token` - **Value**: `{{access_token}}` - In **Response Content Type**, select `application/json`. - In **Expiration Format**, select `Absolute Unix Timestamp`. - Under the **Response Map** section: - Set the **expires\_in** field to `$.exp` - Set the **scope** field to `$.scope` - Leave the other fields as default - Under **Triggers** section, enable the **On Token Grant** and **On Token Refresh** options. #### Optional Auth Settings [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#optional-auth-settings) - Under **PKCE Settings**, check the **Enable PKCE** option if you have enabled PKCE when creating your Salesforce app. - Leave the **Authorization Settings** and **Token Settings** sections as default. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#create-the-provider) Click the **Create** button and the provider will be ready to be used in the Arcade Engine. ### Configure Salesforce Auth Using the Engine Configuration YAML Refer to [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. To find where the `engine.yaml` file is located in your OS after installing the Arcade Engine, check the [Engine configuration file](https://docs.arcade.dev/home/local-deployment/configure/overview#engine-configuration-file) documentation. #### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#set-environment-variables) Set the following environment variables: ```nextra-code export SALESFORCE_CLIENT_ID="" export SALESFORCE_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code SALESFORCE_CLIENT_ID="" SALESFORCE_CLIENT_SECRET="" ``` #### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#edit-the-engine-configuration) In the YAML code demonstrated below, replace `salesforce-org-subdomain` in the endpoint URLs with your [Salesforce Org Subdomain](https://docs.arcade.dev/home/auth-providers/salesforce#get-your-salesforce-org-subdomain). Edit the `engine.yaml` file and add a Salesforce item to the `auth.providers` section: The `id` must be set to `salesforce` in order to use the [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce). Replace `salesforce-org-subdomain` with your [Salesforce Org Subdomain](https://docs.arcade.dev/home/auth-providers/salesforce#get-your-salesforce-org-subdomain). ```nextra-code auth: providers: - id: salesforce description: "Custom Salesforce provider" enabled: true type: oauth2 client_id: ${env:SALESFORCE_CLIENT_ID} client_secret: ${env:SALESFORCE_CLIENT_SECRET} oauth2: authorize_request: endpoint: 'https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/authorize' params: client_id: '{{client_id}}' redirect_uri: '{{redirect_uri}}' scope: '{{scopes}}' response_type: code token_request: endpoint: 'https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/token' params: grant_type: authorization_code client_id: '{{client_id}}' client_secret: '{{client_secret}}' redirect_uri: '{{redirect_uri}}' refresh_request: endpoint: 'https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/token' params: grant_type: refresh_token client_id: '{{client_id}}' client_secret: '{{client_secret}}' refresh_token: '{{refresh_token}}' token_introspection_request: enabled: false endpoint: 'https://salesforce-org-subdomain.my.salesforce.com/services/oauth2/introspect' method: POST params: token: '{{access_token}}' auth_method: 'client_secret_basic' request_content_type: application/x-www-form-urlencoded response_content_type: application/json response_map: expires_in: '$.exp' scope: '$.scope' expiration_format: absolute_unix_timestamp triggers: on_token_grant: true on_token_refresh: true ``` #### Optionally Enable PKCE [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#optionally-enable-pkce) If you have enabled PKCE when creating your Salesforce app, you must also enable PKCE in the Salesforce auth provider configuration by setting the `pkce` option to `true`. ```nextra-code auth: providers: - id: salesforce description: "Custom Salesforce provider" enabled: true pkce: true ... ``` #### Restart the Arcade Engine [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#restart-the-arcade-engine) If the Arcade Engine is already running, you will need to restart it for the changes to take effect. ## Using the Arcade Salesforce Toolkit [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#using-the-arcade-salesforce-toolkit) The [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce) provides tools to interact with various Salesforce objects, such as accounts, contacts, leads, opportunities, notes, tasks, email messages, call logs, etc. Refer to the [toolkit documentation and examples](https://docs.arcade.dev/toolkits/sales/salesforce) to learn how to use the toolkit to build agents and AI apps that interact with Salesforce services. Check our introductory documentation to understand what are tools and how [tool calling works](https://docs.arcade.dev/home/use-tools/tools-overview). ## Calling Salesforce APIs directly [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#calling-salesforce-apis-directly) Use the Salesforce auth provider to get a user authorization token and call Salesforce API endpoints directly, without the use of any tools. See [How Arcade helps with Agent Authorization](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#prerequisites) 1. Create an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=salesforce-auth-provider) 2. Get an [Arcade API key](https://docs.arcade.dev/home/api-keys). 3. Set the `ARCADE_API_KEY` environment variable with `export ARCADE_API_KEY=`. 4. Make sure to have Python 3.10+ or Node.js 18+ installed. PythonJavaScript ### Install the Arcade Python Client [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#install-the-arcade-python-client) ```nextra-code pip install arcadepy ``` ### Import necessary modules and instantiate the client [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#import-necessary-modules-and-instantiate-the-client) Create a new script called `salesforce_example.py`. Import the necessary modules and instantiate the Arcade client: The Arcade Engine service is available at `http://localhost:9099` by default. Replace the host and port, if necessary, to match your environment. ```nextra-code import requests from arcadepy import Arcade client = Arcade(base_url="http://localhost:9099") # Automatically finds the `ARCADE_API_KEY` env variable ``` ### Set the values required for the Salesforce API call [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#set-the-values-required-for-the-salesforce-api-call) ```nextra-code salesforce_provider_id = "salesforce" salesforce_org_subdomain = "salesforce-org-subdomain" user_id = "user@example.com" scopes = ["read_account"] ``` Here’s a break down of each value: - **`salesforce_provider_id`**: the ID you entered when setting up the [Salesforce auth provider](https://docs.arcade.dev/home/auth-providers/salesforce#configuring-salesforce-auth); - **`salesforce_org_subdomain`**: your [Salesforce Org Subdomain](https://docs.arcade.dev/home/auth-providers/salesforce#get-your-salesforce-org-subdomain); - **`user_id`**: an internal identifier for your application user (it could be an email address, a username, UUID, etc); for demonstration purposes, in this example, enter your own email address; - **`scopes`**: the list of scopes you want to request from the user; if you assigned the [custom scopes required by the Arcade Salesforce toolkit](https://docs.arcade.dev/home/auth-providers/salesforce#create-and-assign-custom-scopes-to-your-connected-app) use `["read_account"]` in this example. ### Start the authorization process and wait for completion [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#start-the-authorization-process-and-wait-for-completion) The Arcade client will prompt the user to access a URL and authorize the app to access their Salesforce data. At the end of the auth process, you will have a token that can be used to call Salesforce APIs on behalf of that user. ```nextra-code auth_response = client.auth.start( user_id=user_id, provider=salesforce_provider_id, scopes=scopes, ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token if not token: raise ValueError("No token found in auth response") ``` If the same scopes have already been authorized by the user before and the token is still valid, the auth process will be skipped and the token will be returned immediately, without prompting with the authorization URL. The Arcade Engine associates a previously authorized token with the `user_id` you provided. ### Call the Salesforce API [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#call-the-salesforce-api) We will now call the Salesforce `/parameterizedSearch` API endpoint to search and retrieve account data. Replace the `q` value of `"acme"` with any keyword combination of your choice. In a real-world scenario, this value would most likely come from a user’s input. Observe that the `q` argument must be a string with two or more characters. ```nextra-code response = requests.post( f"https://{salesforce_org_subdomain}.my.salesforce.com/services/data/v63.0/parameterizedSearch", headers={"Authorization": f"Bearer {token}"}, json={ "q": "acme", "sobjects": [\ {"name": "Account", "fields": ["Id", "Name", "Website", "Phone"]},\ ], "in": "ALL", "overallLimit": 10, "offset": 0, }, ) if not response.ok: raise ValueError( f"Failed to retrieve Salesforce data: {response.status_code} - {response.text}" ) ``` Click to view the full example ### Install the Arcade JavaScript Client [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#install-the-arcade-javascript-client) ```nextra-code npm install @arcadeai/arcadejs ``` ### Import necessary modules and instantiate the client [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#import-necessary-modules-and-instantiate-the-client-1) Create a new script called `salesforce_example.js`. Import the necessary modules and instantiate the Arcade client: Replace `http://localhost:9099` with the URL of your Arcade Engine. ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade((baseURL = "http://localhost:9099")); // Automatically finds the `ARCADE_API_KEY` env variable ``` ### Set the values required for the Salesforce API call [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#set-the-values-required-for-the-salesforce-api-call-1) ```nextra-code const salesforceProviderId = "salesforce"; const salesforceOrgSubdomain = "salesforce-org-subdomain"; const userId = "user@example.com"; const scopes = ["read_account"]; ``` Here’s a break down of each value: - **`salesforceProviderId`**: the ID you entered when setting up the [Salesforce auth provider](https://docs.arcade.dev/home/auth-providers/salesforce#configuring-salesforce-auth); - **`salesforceOrgSubdomain`**: your [Salesforce Org Subdomain](https://docs.arcade.dev/home/auth-providers/salesforce#get-your-salesforce-org-subdomain); - **`userId`**: an internal identifier for your application user (it could be an email address, a username, UUID, etc); for demonstration purposes, in this example, enter your own email address; - **`scopes`**: the list of scopes you want to request from the user; if you assigned the [custom scopes required by the Arcade Salesforce toolkit](https://docs.arcade.dev/home/auth-providers/salesforce#create-and-assign-custom-scopes-to-your-connected-app) use `["read_account"]` in this example. ### Start the authorization process and wait for completion [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#start-the-authorization-process-and-wait-for-completion-1) The Arcade client will prompt the user to access a URL and authorize the app to access their Salesforce data. At the end of the auth process, you will have a token that can be used to call Salesforce APIs on behalf of that user. ```nextra-code let authResponse = await client.auth.start(userId, { provider: salesforceProviderId, scopes: scopes, }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); if (!authResponse.context.token) { throw new Error("No token found in auth response"); } const token = authResponse.context.token; if (!token) { throw new Error("No token found in auth response"); ``` If the same scopes have already been authorized by the user before and the token is still valid, the auth process will be skipped and the token will be returned immediately, without prompting with the authorization URL. The Arcade Engine associates a previously authorized token with the `user_id` you provide. ### Call the Salesforce API [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#call-the-salesforce-api-1) We will now call the Salesforce `/parameterizedSearch` API endpoint to search and retrieve account data. Replace the `q` value of `"acme"` with any keyword combination of your choice. In a real-world scenario, this value would most likely come from a user’s input. Observe that the `q` argument must be a string with two or more characters. ```nextra-code // Use the Salesforce API const response = await fetch( `https://${salesforceOrgSubdomain}.my.salesforce.com/services/data/v63.0/parameterizedSearch`, { headers: { Authorization: `Bearer ${token}`, }, method: "POST", body: JSON.stringify({ q: "acme", sobjects: [\ { name: "Account", fields: ["Id", "Name", "Website", "Phone"] },\ ], in: "ALL", overallLimit: 10, offset: 0, }), }, ); if (!response.ok) { throw new Error( `HTTP error! status: ${response.status} - ${await response.text()}`, ); ``` Click to view the full example ## Create your own Salesforce Tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/salesforce\#create-your-own-salesforce-tools) If the pre-built tools in the [Arcade Salesforce toolkit](https://docs.arcade.dev/toolkits/sales/salesforce) don’t meet your needs, you can create your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Salesforce APIs. The code implemented in the Arcade Salesforce tools is the best guide for you to understand how to implement your own. Check the [Contact](https://github.com/ArcadeAI/arcade-ai/blob/main/toolkits/salesforce/arcade_salesforce/tools/crm/contact.py) and [Account](https://github.com/ArcadeAI/arcade-ai/blob/main/toolkits/salesforce/arcade_salesforce/tools/crm/account.py) tools in our public Github repository. [Reddit](https://docs.arcade.dev/home/auth-providers/reddit "Reddit") [Slack](https://docs.arcade.dev/home/auth-providers/slack "Slack") ## Google Docs Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Productivity & Docs](https://docs.arcade.dev/toolkits/productivity/asana "Productivity & Docs") [Google](https://docs.arcade.dev/toolkits/productivity/google/calendar "Google") Docs # Docs **Description:** Enable agents to interact with Google Docs documents. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/google) **Auth:** User authorizationvia the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) This Toolkit is not available in Arcade Cloud. You can use these tools with a [self-hosted](https://docs.arcade.dev/home/local-deployment/install/overview) instance of Arcade. [![PyPI Version](https://img.shields.io/pypi/v/arcade_google)](https://pypi.org/project/arcade_google/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_google)](https://pypi.org/project/arcade_google/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_google)](https://pypi.org/project/arcade_google/)[![Downloads](https://img.shields.io/pypi/dm/arcade_google)](https://pypi.org/project/arcade_google/) The Arcade Docs toolkit provides a pre-built set of tools for interacting with Google Docs. These tools make it easy to build agents and AI apps that can: - Create, update, list, and delete documents ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/docs\#available-tools) These tools are currently available in the Arcade Docs toolkit. | Tool Name | Description | | --- | --- | | Google.GetDocumentById | Retrieve a Google Docs document by ID. Note: This tool currently requires a self-hosted instance of Arcade. | | Google.InsertTextAtEndOfDocument | Insert text at the end of a Google Docs document. Note: This tool currently requires a self-hosted instance of Arcade. | | Google.CreateBlankDocument | Create a new blank Google Docs document with a title. Note: This tool currently requires a self-hosted instance of Arcade. | | Google.CreateDocumentFromText | Create a new Google Docs document with specified text content. Note: This tool currently requires a self-hosted instance of Arcade. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Google auth\\ provider](https://docs.arcade.dev/home/auth-providers/google#using-google-auth-in-custom-tools). ## Google.GetDocumentById [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/docs\#googlegetdocumentbyid) See Example > Get the latest version of the specified Google Docs document. **Parameters** - **`document_id`** _(string, required)_ The ID of the document to retrieve. * * * ## Google.InsertTextAtEndOfDocument [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/docs\#googleinserttextatendofdocument) See Example > Insert text at the end of an existing Google Docs document. **Parameters** - **`document_id`** _(string, required)_ The ID of the document to update. - **`text_content`** _(string, required)_ The text content to insert into the document. * * * ## Google.CreateBlankDocument [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/docs\#googlecreateblankdocument) See Example > Create a blank Google Docs document with the specified title. **Parameters** - **`title`** _(string, required)_ The title of the blank document to create. * * * ## Google.CreateDocumentFromText [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/docs\#googlecreatedocumentfromtext) See Example > Create a Google Docs document with the specified title and text content. **Parameters** - **`title`** _(string, required)_ The title of the document to create. - **`text_content`** _(string, required)_ The text content to insert into the document. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/productivity/google/docs\#auth) The Arcade Docs toolkit uses the [Google auth provider](https://docs.arcade.dev/home/auth-providers/google) to connect to users’ Google accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the Google auth provider](https://docs.arcade.dev/home/auth-providers/google#configuring-google-auth) with your own Google app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_google\\ ```](https://docs.arcade.dev/home/hosting-overview) [Contacts](https://docs.arcade.dev/toolkits/productivity/google/contacts "Contacts") [Drive](https://docs.arcade.dev/toolkits/productivity/google/drive "Drive") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Run Evaluations [Home](https://docs.arcade.dev/home "Home") [Evaluate tools](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools "Evaluate tools") Run evaluations # Run evaluations with the Arcade CLI The Arcade Evaluation Framework allows you to run evaluations of your tool-enabled language models conveniently using the command-line interface (CLI). This enables you to execute your evaluation suites, gather results, and analyze the performance of your models in an efficient and streamlined manner. ### Using the `arcade evals` Command [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#using-the-arcade-evals-command) To run evaluations, use the `arcade evals` command provided by the Arcade CLI. This command searches for evaluation files in the specified directory, executes any functions decorated with `@tool_eval`, and displays the results. #### Basic Usage [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#basic-usage) ```nextra-code arcade evals ``` - ``: The directory containing your evaluation files. By default, it searches the current directory ( `.`). For example, to run evaluations in the current directory: ```nextra-code arcade evals . ``` The Arcade Evaluation Framework also supports running a single evaluation file: ```nextra-code arcade evals ``` #### Evaluation File Naming Convention [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#evaluation-file-naming-convention) The `arcade evals` command looks for Python files that start with `eval_` and end with `.py` (e.g., `eval_math_tools.py`, `eval_slack_messaging.py`). These files should contain your evaluation suites. #### Command Options [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#command-options) The `arcade evals` command supports several options to customize the evaluation process: - `--details`, `-d`: Show detailed results for each evaluation case, including critic feedback. Example: ```nextra-code arcade evals . --details ``` - `--models`, `-m`: Specify the models to use for evaluation. Provide a comma-separated list of model names. Example: ```nextra-code arcade evals . --models gpt-4o,gpt-3.5 ``` - `--max-concurrent`, `-c`: Set the maximum number of concurrent evaluations to run in parallel. Example: ```nextra-code arcade evals . --max-concurrent 4 ``` - `--host`, `-h`: Specify the Arcade Engine address to send evaluation requests to. - `--port`, `-p`: Specify the port of the Arcade Engine. - `--tls`: Force TLS for the connection to the Arcade Engine. - `--no-tls`: Disable TLS for the connection to the Arcade Engine. #### Example Command [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#example-command) Running evaluations in the `toolkits/math/evals` directory, showing detailed results, using the `gpt-4o` model: ```nextra-code arcade evals toolkits/math/evals --details --models gpt-4o ``` ### Execution Process [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#execution-process) When you run the `arcade evals` command, the following steps occur: 1. **Preparation**: The CLI loads the evaluation suites from the specified directory, looking for files that match the naming convention. 2. **Execution**: The evaluation suites are executed asynchronously. Each suite’s evaluation function, decorated with `@tool_eval`, is called with the appropriate configuration, including the model and concurrency settings. 3. **Concurrency**: Evaluations can run concurrently based on the `--max-concurrent` setting, improving efficiency. 4. **Result Aggregation**: Results from all evaluation cases and models are collected and aggregated. ### Displaying Results [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#displaying-results) After the evaluations are complete, the results are displayed in a concise and informative format, similar to testing frameworks like `pytest`. The output includes: - **Summary**: Shows the total number of cases, how many passed, failed, or issued warnings. Example: ```nextra-code Summary -- Total: 5 -- Passed: 4 -- Failed: 1 ``` - **Detailed Case Results**: For each evaluation case, the status (PASSED, FAILED, WARNED), the case name, and the score are displayed. Example: ```nextra-code PASSED Add two large numbers -- Score: 1.00 FAILED Send DM with ambiguous username -- Score: 0.75 ``` - **Critic Feedback**: If the `--details` flag is used, detailed feedback from each critic is provided, highlighting matches, mismatches, and scores for each evaluated field. Example: ```nextra-code Details: user_name: Match: False, Score: 0.00/0.50 Expected: johndoe Actual: john_doe message: Match: True, Score: 0.50/0.50 ``` ### Interpreting the Results [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#interpreting-the-results) - **Passed**: The evaluation case met or exceeded the fail threshold specified in the rubric. - **Failed**: The evaluation case did not meet the fail threshold. - **Warnings**: If the score is between the warn threshold and the fail threshold, a warning is issued. Use the detailed feedback to understand where the model’s performance can be improved, particularly focusing on mismatches identified by critics. ### Customizing Evaluations [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#customizing-evaluations) You can customize the evaluation process by adjusting: - **Rubrics**: Modify fail and warn thresholds, and adjust weights to emphasize different aspects of evaluation. - **Critics**: Add or modify critics in your evaluation cases to target specific arguments or behaviors. - **Concurrency**: Adjust the `--max-concurrent` option to optimize performance based on your environment. ### Handling Multiple Models [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#handling-multiple-models) You can evaluate multiple models in a single run by specifying them in the `--models` option as a comma-separated list. This allows you to compare the performance of different models across the same evaluation suites. Example: ```nextra-code arcade evals . --models gpt-4o,gpt-3.5 ``` ### Considerations [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#considerations) - **Engine Availability**: Ensure the Arcade Engine is running and accessible. You can specify the host and port if running the engine locally or on a different server. - **Authentication**: Make sure you are logged in and have the necessary API keys configured. - **Evaluation Files**: Ensure your evaluation files are correctly named and contain the evaluation suites decorated with `@tool_eval`. ## Conclusion [Permalink for this section](https://docs.arcade.dev/home/evaluate-tools/run-evaluations\#conclusion) Running evaluations using the Arcade CLI provides a powerful and convenient way to assess the tool-calling capabilities of your language models. By leveraging the `arcade evals` command, you can efficiently execute your evaluation suites, analyze results, and iterate on your models and toolkits. Integrating this evaluation process into your development workflow helps ensure that your models interact with tools as expected, enhances reliability, and builds confidence in deploying actionable language models in production environments. [Create an evaluation suite](https://docs.arcade.dev/home/evaluate-tools/create-an-evaluation-suite "Create an evaluation suite") [Arcade Deploy](https://docs.arcade.dev/home/serve-tools/arcade-deploy "Arcade Deploy") ## Arcade Quickstart Guide [Home](https://docs.arcade.dev/home "Home") Quickstart # Arcade Quickstart This guide will walk you through the process of getting started with Arcade.dev. First, we will go over Direct Tool Calling, a simple way to call tools directly from your agent. Direct tool calling is useful in situations where you already know what tool is needed or when there is no prompt for an LLM to interpret and decide on the tool calling. It also gives you full control over what is executed by the Arcade Engine and how. [iframe](https://www.youtube.com/embed/USoqJOOUP6c?si=ontrjjatjmqMfTHN) ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/quickstart\#prerequisites) 1. Create an [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=call-tools-directly) 2. Get an [Arcade API key](https://docs.arcade.dev/home/api-keys) and take note, you’ll need it in the next steps. ### Install the Arcade client [Permalink for this section](https://docs.arcade.dev/home/quickstart\#install-the-arcade-client) PythonJavaScript ```nextra-code pip install arcadepy ``` ```nextra-code npm install @arcadeai/arcadejs ``` ### Instantiate and use the client [Permalink for this section](https://docs.arcade.dev/home/quickstart\#instantiate-and-use-the-client) PythonJavaScript Create a new script called `example.py`: ```nextra-code from arcadepy import Arcade # You can also set the `ARCADE_API_KEY` environment variable instead of passing it as a parameter. client = Arcade(api_key="arcade_api_key") # Arcade needs a unique identifier for your application user (this could be an email address, a UUID, etc). # In this example, simply use your email address as the user ID: user_id = "user@example.com" # Let's use the `Math.Sqrt` tool from the Arcade Math toolkit to get the square root of a number. response = client.tools.execute( tool_name="Math.Sqrt", input={"a": '625'}, user_id=user_id, ) print(f"The square root of 625 is {response.output.value}") # Now, let's use a tool that requires authentication to star a GitHub repository auth_response = client.tools.authorize( tool_name="GitHub.SetStarred", user_id=user_id, ) if auth_response.status != "completed": print(f"Click this link to authorize: `{auth_response.url}`. The process will continue once you have authorized the app." ) # Wait for the user to authorize the app client.auth.wait_for_completion(auth_response.id); response = client.tools.execute( tool_name="GitHub.SetStarred", input={ "owner": "ArcadeAI", "name": "arcade-ai", "starred": True, }, user_id=user_id, ) print(response.output.value) ``` Create a new script called `example.mjs`: ```nextra-code import Arcade from "@arcadeai/arcadejs"; // You can also set the `ARCADE_API_KEY` environment variable instead of passing it as a parameter. const client = new Arcade({ apiKey: "arcade_api_key", }); // Arcade needs a unique identifier for your application user (this could be an email address, a UUID, etc). // In this example, simply use your email address as the user ID: let userId = "you@example.com"; // Let's use the `Math.Sqrt` tool from the Arcade Math toolkit to get the square root of a number. const response_sqrt = await client.tools.execute({ tool_name: "Math.Sqrt", input: { a: "625" }, user_id: userId, }); console.log(response_sqrt.output.value); // Now, let's use a tool that requires authentication const authResponse = await client.tools.authorize({ tool_name: "GitHub.SetStarred", user_id: userId, }); if (authResponse.status !== "completed") { console.log( `Click this link to authorize: \`${authResponse.url}\`. The process will continue once you have authorized the app.`, ); // Wait for the user to authorize the app await client.auth.waitForCompletion(authResponse.id); } const response_github = await client.tools.execute({ tool_name: "GitHub.SetStarred", input: { owner: "ArcadeAI", name: "arcade-ai", starred: true, }, user_id: userId, }); console.log(response_github.output.value); ``` ### Run the code [Permalink for this section](https://docs.arcade.dev/home/quickstart\#run-the-code) PythonJavaScript ```nextra-code python3 example.py > The square root of 625 is 25 > Successfully starred the repository ArcadeAI/arcade-ai ``` ```nextra-code node example.mjs > The square root of 625 is 25 > Successfully starred the repository ArcadeAI/arcade-ai ``` ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/quickstart\#next-steps) In this simple example, we call the tool methods directly. In your real applications and agents, you’ll likely be letting the LLM decide which tools to call - lean more about using Arcade with Frameworks in the [Frameworks](https://docs.arcade.dev/home/langchain/use-arcade-tools) section, or [how to build your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). [Contact us](https://docs.arcade.dev/home/contact-us "[object Object]") [Get an API key](https://docs.arcade.dev/home/api-keys "Get an API key") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## User Authorization Guide [Home](https://docs.arcade.dev/home "Home") [Build tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit "Build tools") Create a tool with auth # Adding user authorization to your tools In this guide, you’ll learn how to add user authorization to your custom tools, using Arcade. You’ll create a tool that sends a message on behalf of a user via Slack. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth\#prerequisites) - [Set up Arcade](https://docs.arcade.dev/home/quickstart) - Install the Arcade SDK and any third-party SDKs you need (e.g., Slack SDK): - [Understand Tool Context](https://docs.arcade.dev/home/build-tools/tool-context) uvpip ```nextra-code uv pip install arcade-ai slack_sdk ``` ```nextra-code pip install arcade-ai slack_sdk ``` ### Define your authorized tool [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth\#define-your-authorized-tool) Create a new Python file, e.g., `slack_tools.py`, and import the necessary modules: ```nextra-code from typing import Annotated from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Slack from arcade_tdk.errors import RetryableToolError from slack_sdk import WebClient ``` Now, define your tool using the `@tool` decorator and specify the required authorization, in this case, by using the built-in `Slack` auth provider: ```nextra-code @tool( requires_auth=Slack( scopes=[\ "chat:write",\ "im:write",\ "users.profile:read",\ "users:read",\ ], ) ) def send_dm_to_user( context: ToolContext, user_name: Annotated[str, "The Slack username of the person you want to message"], message: Annotated[str, "The message you want to send"], ) -> Annotated[str, "A confirmation message that the DM was sent"]: """Send a direct message to a user in Slack.""" slack_client = WebClient(token=context.authorization.token) # Retrieve the user ID based on username user_list_response = slack_client.users_list() user_id = None for user in user_list_response["members"]: if user["name"].lower() == user_name.lower(): user_id = user["id"] break if not user_id: raise RetryableToolError( "User not found", developer_message=f"User with username '{user_name}' not found." ) # Open a conversation and send the message im_response = slack_client.conversations_open(users=[user_id]) dm_channel_id = im_response["channel"]["id"] slack_client.chat_postMessage(channel=dm_channel_id, text=message) return "DM sent successfully" ``` Arcade offers a number of [built-in auth providers](https://docs.arcade.dev/home/auth-providers), including Slack, Google, and GitHub. You can also require authorization with a custom auth provider, using the `OAuth2` class, a subclass of the `ToolAuthorization` class: ```nextra-code @tool( requires_auth=OAuth2( id="your-oauth-provider-id", scopes=["scope1", "scope2"], ) ) ``` The `OAuth2` class requires an `id` parameter to identify the auth provider in the Arcade Engine. For built-in providers like `Slack`, you can skip the `id` \- the Arcade Engine will find the right provider using your credentials. While you can specify an `id` for built-in providers, only do this for private tools that won’t be shared. ### Use your authorized tool with Arcade [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth\#use-your-authorized-tool-with-arcade) Now you can use your custom authorized tool with Arcade in your application. Here’s an example of how to use your tool: ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Use the tool response = client.tools.execute( tool_name="Slack.SendDmToUser", input={ "user_name": "johndoe", "message": "Hello!", }, user_id=user_id, ) print(response.output.value) ``` ### Handle authorization [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth\#handle-authorization) Since your tool requires authorization, the first time you use it, the user (identified by `user_id`) needs to authorize access. Arcade handles the authorization flow, prompting the user to visit a URL to grant permissions. Your application should guide the user through this process. ### How it works [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth\#how-it-works) By specifying the `requires_auth` parameter in the `@tool` decorator, you indicate that the tool needs user authorization. Arcade manages the OAuth flow, and provides the token in `context.authorization.token` when the tool is executed. Arcade also remembers the user’s authorization tokens, so they won’t have to go through the authorization process again until the auth expires or is revoked. ### Next steps [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth\#next-steps) Try adding more authorized tools, or explore how to handle different authorization providers and scopes. [Tool Context](https://docs.arcade.dev/home/build-tools/tool-context "Tool Context") [Create a tool with secrets](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets "Create a tool with secrets") ## Create Arcade Toolkit [Home](https://docs.arcade.dev/home "Home") Build toolsCreate a toolkit # Creating a Toolkit This guide walks you through the complete process of creating a custom toolkit for Arcade - from initial setup to publishing on PyPI. You’ll build a simple arithmetic toolkit with operations like addition, subtraction, and multiplication. When creating or extending an Arcade toolkit, we make it easy to develop the tool alongside your agent, providing a pleasant local development experience. As your agent will be loading its available tools from the Arcade Engine, you can mix existing tools and your locally developed tool by following this guide. You’ll be running your local worker with the Arcade CLI and registering it with the Engine so that your agent can find and use your tool. [iframe](https://www.youtube.com/embed/EcCb_1W9Gb4?si=rCt30twDTEgoIVi2) ## Prerequisites [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#prerequisites) Before starting, make sure you have: - An [Arcade account](https://api.arcade.dev/signup?utm_source=docs&utm_medium=page&utm_campaign=custom-tools) - For this guide, we’ll use [uv](https://docs.astral.sh/uv/getting-started/installation/) as our package manager. ## Generate a toolkit template [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#generate-a-toolkit-template) Run the following command to start creating your toolkit: ```nextra-code uv tool run --from arcade-ai arcade new arithmetic ``` Enter the optional information when prompted: - **Description**: Provide a brief explanation of what your toolkit will do - **Author GitHub username and email**: Your contact information - **Generate test and evaluation directories**: Whether you want additional directories created for you After completion, a directory with your toolkit name (arithmetic) will be created with the following structure: ```nextra-code arithmetic/ ├── arcade_arithmetic/ # Core package directory │ ├── __init__.py │ └── tools/ # Directory for your tools │ ├── __init__.py │ └── hello.py # Example tool ├── evals/ # Evaluation directory │ └── eval_arithmetic.py # Example evaluation file ├── tests/ # Test directory │ ├── __init__.py │ └── test_arithmetic.py # Example test file ├── pyproject.toml # uv project configuration ├── README.md └── Makefile # uv helper commands ``` Navigate to your toolkit directory: ```nextra-code cd arithmetic ``` ## Set up the development environment [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#set-up-the-development-environment) An active virtual environment for your shell(s) is required to run the local development commands. ```nextra-code uv venv --seed -p 3.13 ``` Install dependencies and pre-commit hooks: ```nextra-code make install ``` This installs all dependencies specified in `pyproject.toml`, pre-commit hooks for code quality, and your toolkit in development mode. The Makefile provides several helpful commands: - `build` \- Build wheel file using uv - `bump-version` \- Bump the version in the pyproject.toml file by a patch version - `check` \- Run code quality tools - `clean-build` \- Clean build artifacts - `coverage` \- Generate coverage report - `install` \- Install the uv environment and install all packages with dependencies - `install-local` \- Install Arcade components (CLI, TDK, etc.) from source in editable mode. Only use this when you are developing against the latest unreleased code from the [arcade-ai repo](https://github.com/ArcadeAI/arcade-ai) main branch instead of the published packages - `test` \- Test the code with pytest ## Define your tools [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#define-your-tools) Create a Python file for your tools in the `arcade_arithmetic/tools` directory. The following example shows a simple math toolkit with three tools: `add`, `subtract`, and `multiply`: ```nextra-code # arcade_arithmetic/tools/operations.py from typing import Annotated from arcade_tdk import tool @tool def add( a: Annotated[int, "The first number"], b: Annotated[int, "The second number"] ) -> Annotated[int, "The sum of the two numbers"]: """ Add two numbers together Examples: add(3, 4) -> 7 add(-1, 5) -> 4 """ return a + b @tool def subtract( a: Annotated[int, "The first number"], b: Annotated[int, "The second number"] ) -> Annotated[int, "The difference of the two numbers"]: """ Subtract the second number from the first Examples: subtract(10, 4) -> 6 subtract(5, 7) -> -2 """ return a - b @tool def multiply( a: Annotated[int, "The first number"], b: Annotated[int, "The second number"] ) -> Annotated[int, "The product of the two numbers"]: """ Multiply two numbers together Examples: multiply(3, 4) -> 12 multiply(-2, 5) -> -10 """ return a * b ``` Update the package initialization files to expose your tools: ```nextra-code # arcade_arithmetic/tools/__init__.py from arcade_arithmetic.tools.operations import add, multiply, subtract __all__ = ["add", "multiply", "subtract"] ``` ```nextra-code # arcade_arithmetic/__init__.py from arcade_arithmetic.tools import add, multiply, subtract __all__ = ["add", "multiply", "subtract"] ``` ## Test your toolkit [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#test-your-toolkit) Write tests for your tools in the `tests` directory: ```nextra-code # tests/test_operations.py import pytest from arcade_arithmetic.tools.operations import add, multiply, subtract def test_add(): assert add(3, 4) == 7 assert add(-1, 5) == 4 assert add(0, 0) == 0 def test_subtract(): assert subtract(10, 4) == 6 assert subtract(5, 7) == -2 assert subtract(0, 0) == 0 def test_multiply(): assert multiply(3, 4) == 12 assert multiply(-2, 5) == -10 assert multiply(0, 5) == 0 ``` Run the tests: ```nextra-code make test ``` Check code quality: ```nextra-code make check ``` Generate a coverage report (optional): ```nextra-code make coverage ``` ## Verify local installation [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#verify-local-installation) Your toolkit should already be installed locally from the `make install` command. Verify it’s properly registered: ```nextra-code arcade show --local ``` You should see your toolkit listed in the output. ## Test your tools locally [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#test-your-tools-locally) Serve your toolkit locally with the Arcade CLI: ```nextra-code arcade serve ``` You can use the `--reload` flag to automatically reload the server when you make changes to your toolkit: ```nextra-code arcade serve --reload ``` Visit [http://localhost:8002/worker/health](http://localhost:8002/worker/health) to see that your worker is running. ## Connect your toolkit to the Arcade Engine [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#connect-your-toolkit-to-the-arcade-engine) In another terminal, use a service like [ngrok](https://ngrok.com/docs/), [tailscale](https://tailscale.com/kb/1223/funnel), or [cloudflare](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/create-local-tunnel/) to give your local worker a public URL. ngrokTailscaleCloudflare ```nextra-code ngrok http 8002 ``` ```nextra-code tailscale funnel 8002 ``` ```nextra-code cloudflared tunnel --url http://localhost:8002 ``` Then in your Arcade dashboard: 1. Navigate to the [Workers](https://api.arcade.dev/dashboard/workers) page. 2. Click **Add Worker**. 3. Fill in the form with the following values: - **ID**: `my-arithmetic-worker` - **Worker Type**: `Arcade` - **URL**: your public URL from ngrok, tailscale, or cloudflare - **Secret**: `dev` - **Timeout** and **Retry**: can be left at default values 4. Click **Create**. Now, in the [Playground](https://api.arcade.dev/dashboard/playground), you can see your tools in action. ## Deploy your toolkit to the Arcade Engine [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#deploy-your-toolkit-to-the-arcade-engine) Alternatively, you can deploy your toolkit to Arcade’s cloud instead of tunneling to it locally. Find the `worker.toml` file in your toolkit’s root directory (where you ran `uv tool run --from arcade-ai arcade new arithmetic`): ```nextra-code [[worker]] [worker.config] id = "demo-worker" # Choose a unique ID enabled = true timeout = 30 retries = 3 secret = "" # This is randomly generated for you by `uv tool run --from arcade-ai arcade new arithmetic` [worker.local_source] packages = ["./arithmetic"] # Path to your toolkit directory ``` See [Configuring Arcade Deploy](https://docs.arcade.dev/home/local-deployment/configure/arcade-deploy) for more configuration options. From the root of your toolkit, deploy your toolkit to Arcade’s cloud with: This may take a while your first time. ```nextra-code arcade deploy ``` Verify the deployment: ```nextra-code arcade worker list ``` ## Package and publish to PyPI [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#package-and-publish-to-pypi) Clean any previous build artifacts: ```nextra-code make clean-build ``` If you’re updating an existing package, bump the version: ```nextra-code make bump-version ``` Create a comprehensive README.md file that explains your toolkit’s purpose, installation, and usage. Build your package: ```nextra-code make build ``` Publish to PyPI: ```nextra-code uv publish --token YOUR_PYPI_TOKEN_HERE ``` ## Using your published toolkit [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#using-your-published-toolkit) Now that your toolkit is published, you can use it in any Arcade application: ```nextra-code from arcadepy import Arcade # Initialize the Arcade client client = Arcade() # Use your Tools response = client.tools.execute( tool_name="Arithmetic.Add", input={ "a": 12, "b": 34 }, ) print(response.output.value) ``` ## Ongoing toolkit maintenance [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#ongoing-toolkit-maintenance) As you continue to develop your toolkit, use these Makefile commands to maintain it: - `make check` \- Run code quality checks before committing changes - `make test` \- Run tests to ensure your changes don’t break existing functionality - `make coverage` \- Monitor test coverage as you add new features - `make bump-version` \- Update the version when releasing new changes - `make build` \- Build new distribution packages - `make clean-build` \- Clean up build artifacts when needed ## Next steps [Permalink for this section](https://docs.arcade.dev/home/build-tools/create-a-toolkit\#next-steps) - **Add more tools**: Expand your toolkit with more complex operations - **Add authentication**: [Learn how to create tools with authentication](https://docs.arcade.dev/home/build-tools/create-a-tool-with-auth) - **Add secrets**: [Learn how to create tools with secrets](https://docs.arcade.dev/home/build-tools/create-a-tool-with-secrets) - **Evaluate your tools**: [Explore how to evaluate tool performance](https://docs.arcade.dev/home/evaluate-tools/why-evaluate-tools) - **Set up CI/CD**: Automate testing and deployment with continuous integration [Get an API key](https://docs.arcade.dev/home/api-keys "Get an API key") [Tool Context](https://docs.arcade.dev/home/build-tools/tool-context "Tool Context") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## LinkedIn Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Linkedin # LinkedIn auth provider The LinkedIn auth provider enables tools and agents to call the LinkedIn API on behalf of a user. Behind the scenes, the Arcade Engine and the LinkedIn auth provider seamlessly manage LinkedIn OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#whats-documented-here) This page describes how to use and configure LinkedIn auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/linkedin#using-linkedin-auth-in-app-code) that needs to call LinkedIn APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/linkedin#using-linkedin-auth-in-custom-tools) that need to call LinkedIn APIs ## Configuring LinkedIn auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#configuring-linkedin-auth) In a production environment, you will most likely want to use your own LinkedIn app credentials. This way, your users will see your application’s name requesting permission. You can use your own LinkedIn credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your LinkedIn app credentials, let’s go through the steps to create a LinkedIn app. ### Create a LinkedIn app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#create-a-linkedin-app) - Follow LinkedIn’s guide to [setting up user authorization](https://learn.microsoft.com/en-us/linkedin/shared/authentication/authentication) - On the Products tab, add the products you need for your app (e.g. “Share on LinkedIn”) - At a minimum, you _must_ add the “Sign In with LinkedIn using OpenID Connect” product - On the Auth tab, set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the client ID and client secret to use below Next, add the LinkedIn app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own LinkedIn Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#configuring-your-own-linkedin-auth-provider-in-arcade) There are two ways to configure your LinkedIn app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure LinkedIn Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **LinkedIn**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-linkedin-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your LinkedIn app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require LinkedIn auth using your Arcade account credentials, the Arcade Engine will automatically use this LinkedIn OAuth provider. If you have multiple LinkedIn providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring LinkedIn auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#set-environment-variables) Set the following environment variables: ```nextra-code export LINKEDIN_CLIENT_ID="" export LINKEDIN_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code LINKEDIN_CLIENT_ID="" LINKEDIN_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `linkedin` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-linkedin description: "The default LinkedIn provider" enabled: true type: oauth2 provider_id: linkedin client_id: ${env:LINKEDIN_CLIENT_ID} client_secret: ${env:LINKEDIN_CLIENT_SECRET} ``` ## Using LinkedIn auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#using-linkedin-auth-in-app-code) Use the LinkedIn auth provider in your own agents and AI apps to get a user token for LinkedIn APIs. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for LinkedIn APIs: PythonJavaScript ```nextra-code import requests from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" """ In this example, we will use Arcade to authenticate with LinkedIn and post a message to the user's LinkedIn feed. There is a tool for that in the Arcade SDK, which simplifies the process for you to post messages to the user's LinkedIn feed either through our Python or JavaScript SDKs or via LLM tool calling. Below we are just showing how to use Arcade as an auth provider, if you ever need to. """ # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="linkedin", scopes=["w_member_social"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) if not auth_response.context.token: raise ValueError("No token found in auth response") token = auth_response.context.token user_id = ( None if not auth_response.context.authorization else auth_response.context.authorization.user_info.get("sub") ) if not user_id: raise ValueError("User ID not found.") # Prepare the payload data for the LinkedIn API message = "Hello, from Arcade.dev!" payload = { "author": f"urn:li:person:{user_id}", "lifecycleState": "PUBLISHED", "specificContent": { "com.linkedin.ugc.ShareContent": { "shareCommentary": {"text": message}, "shareMediaCategory": "NONE", } }, "visibility": {"com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"}, } response = requests.post( "https://api.linkedin.com/v2/ugcPosts", headers={"Authorization": f"Bearer {token}"}, json=payload, ) response.raise_for_status() print(response.json()) ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; /* In this example, we will use Arcade to authenticate with LinkedIn and post a message to the user's LinkedIn feed. There is a tool for that in the Arcade SDK, which simplifies the process for you to post messages to the user's LinkedIn feed either through our Python or JavaScript SDKs or via LLM tool calling. Below we are just showing how to use Arcade as an auth provider, if you ever need to. */ // Start the authorization process let authResponse = await client.auth.start(userId, "linkedin", { scopes: ["w_member_social"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); if (!authResponse.context.token) { throw new Error("No token found in auth response"); } const token = authResponse.context.token; const linkedInUserId = authResponse.context.authorization?.user_info?.sub; if (!linkedInUserId) { throw new Error("User ID not found."); } // Prepare the payload data for the LinkedIn API const message = "Hello, from Arcade.dev!"; const payload = { author: `urn:li:person:${linkedInUserId}`, lifecycleState: "PUBLISHED", specificContent: { "com.linkedin.ugc.ShareContent": { shareCommentary: { text: message }, shareMediaCategory: "NONE", }, }, visibility: { "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC" }, }; const response = await fetch("https://api.linkedin.com/v2/ugcPosts", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log(data); ``` ## Using LinkedIn auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/linkedin\#using-linkedin-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with LinkedIn APIs. Use the `LinkedIn()` auth class to specify that a tool requires authorization with LinkedIn. The `context.authorization.token` field will be automatically populated with the user’s LinkedIn token: ```nextra-code from typing import Annotated import httpx from arcade_tdk.errors import ToolExecutionError from arcade_tdk import ToolContext, tool from arcade_tdk.auth import LinkedIn @tool( requires_auth=LinkedIn( scopes=["w_member_social"], ) ) async def create_text_post( context: ToolContext, text: Annotated[str, "The text content of the post"], ) -> Annotated[str, "URL of the shared post"]: """Share a new text post to LinkedIn.""" endpoint = "/ugcPosts" # The LinkedIn user ID is required to create a post, even though we're using the user's access token. # Arcade Engine gets the current user's info from LinkedIn and automatically populates context.authorization.user_info. # LinkedIn calls the user ID "sub" in their user_info data payload. See: # https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2#api-request-to-retreive-member-details user_id = context.authorization.user_info.get("sub") if not user_id: raise ToolExecutionError( "User ID not found.", developer_message="User ID not found in `context.authorization.user_info.sub`", ) headers = {"Authorization": f"Bearer {context.authorization.token}"} author_id = f"urn:li:person:{user_id}" payload = { "author": author_id, "lifecycleState": "PUBLISHED", "specificContent": { "com.linkedin.ugc.ShareContent": { "shareCommentary": {"text": text}, "shareMediaCategory": "NONE", } }, "visibility": {"com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"}, } async with httpx.AsyncClient() as client: response = await client.post( url=f"https://api.linkedin.com/v2/{endpoint}", headers=headers, json=payload, ) response.raise_for_status() share_id = response.json().get("id") return f"https://www.linkedin.com/feed/update/{share_id}/" ``` [Hubspot](https://docs.arcade.dev/home/auth-providers/hubspot "Hubspot") [Microsoft](https://docs.arcade.dev/home/auth-providers/microsoft "Microsoft") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Hubspot CRM Integration [Integrations](https://docs.arcade.dev/toolkits "Integrations") SalesHubspot # Hubspot **Description:** Enable agents to interact with the Hubspot CRM. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/hubspot) **Auth:** OAuth 2.0 [![PyPI Version](https://img.shields.io/pypi/v/arcade_hubspot)](https://pypi.org/project/arcade_hubspot/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_hubspot)](https://pypi.org/project/arcade_hubspot/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_hubspot)](https://pypi.org/project/arcade_hubspot/)[![Downloads](https://img.shields.io/pypi/dm/arcade_hubspot)](https://pypi.org/project/arcade_hubspot/) The Arcade Hubspot toolkit provides a pre-built set of tools for interacting with the Hubspot CRM. These tools make it easy to build agents and AI apps that can: - Search and retrieve company data and associated objects (deals, calls, email messages, etc) - Search and retrieve contact data and associated objects (calls, email messages, notes, tasks, etc) - Create contacts ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#available-tools) | Tool Name | Description | | --- | --- | | Hubspot.GetCompanyDataByKeywords | Retrieve data about companies in Hubspot using full-text search. | | Hubspot.GetContactDataByKeywords | Retrieve data about contacts in Hubspot using full-text search. | | Hubspot.CreateContact | Create a contact in Hubspot. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Hubspot.GetCompanyDataByKeywords [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#hubspotgetcompanydatabykeywords) See Example > Retrieve company data with associated contacts, deals, calls, emails, meetings, notes, and tasks. **Parameters** - **keywords** _(string, required)_ The keywords to search for companies. It will match against the company name, phone, and website. - **limit** _(int, optional, Defaults to `10`)_ The maximum number of companies to return. Defaults to 10. Max is 10. - **next\_page\_token** _(string, optional)_ The token to get the next page of results. Defaults to None (returns first page of results) ## Hubspot.GetContactDataByKeywords [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#hubspotgetcontactdatabykeywords) See Example > Retrieve contact data with associated companies, deals, calls, emails, meetings, notes, and tasks. **Parameters** - **keywords** _(string, required)_ The keywords to search for. E.g. ‘quarterly report’ - **limit** _(int, optional, Defaults to `10`)_ The maximum number of contacts to return. Defaults to 10. Max is 10. - **next\_page\_token** _(string, optional)_ The token to get the next page of results. Defaults to None (returns first page of results) ## Hubspot.CreateContact [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#hubspotcreatecontact) See Example > Create a contact associated with a company. **Parameters** - **company\_id** _(string, required)_ The ID of the company to create the contact for. - **first\_name** _(string, required)_ The first name of the contact. - **last\_name** _(string, optional)_ The last name of the contact. - **email** _(string, optional)_ The email address of the contact. - **phone** _(string, optional)_ The phone number of the contact. - **mobile\_phone** _(string, optional)_ The mobile phone number of the contact. - **job\_title** _(string, optional)_ The job title of the contact. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#auth) The Arcade Hubspot toolkit uses the [Hubspot auth provider](https://docs.arcade.dev/home/auth-providers/hubspot) to connect to users’ Hubspot accounts. ### Arcade Cloud [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#arcade-cloud) The Arcade Cloud offers a default Hubspot auth provider. If you use it, there’s nothing to configure. Your users will see `Arcade` as the name of the application requesting permission. Alternatively, you can [configure a custom Hubspot auth provider](https://docs.arcade.dev/home/auth-providers/hubspot#use-your-own-hubspot-app-credentials) with your own Hubspot app credentials. This way, your users will see your application’s name requesting permission. ### Self-hosted Arcade Engine [Permalink for this section](https://docs.arcade.dev/toolkits/sales/hubspot\#self-hosted-arcade-engine) With a [self-hosted installation of Arcade](https://docs.arcade.dev/home/local-deployment/install/local), you must [configure the Hubspot auth provider](https://docs.arcade.dev/home/auth-providers/hubspot) with your own Hubspot app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_hubspot\\ ```](https://docs.arcade.dev/home/hosting-overview) [Youtube](https://docs.arcade.dev/toolkits/search/youtube "Youtube") [Salesforce](https://docs.arcade.dev/toolkits/sales/salesforce "Salesforce") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Salesforce CRM Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Sales](https://docs.arcade.dev/toolkits/sales/hubspot "Sales") Salesforce # Salesforce CRM At this time, Arcade does not offer a default Salesforce Auth Provider. To use Salesforce auth and toolkit, you must create a custom Auth Provider with your own Salesforce OAuth 2.0 credentials as documented in [Salesforce Auth Provider](https://docs.arcade.dev/home/auth-providers/salesforce). **Description:** Enable agents to interact with accounts, leads, contacts, etc in the Salesforce CRM. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/salesforce) **Auth:** OAuth 2.0 [![PyPI Version](https://img.shields.io/pypi/v/arcade_salesforce)](https://pypi.org/project/arcade_salesforce/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_salesforce)](https://pypi.org/project/arcade_salesforce/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_salesforce)](https://pypi.org/project/arcade_salesforce/)[![Downloads](https://img.shields.io/pypi/dm/arcade_salesforce)](https://pypi.org/project/arcade_salesforce/) The Arcade Salesforce CRM toolkit provides a pre-built set of tools for interacting with Accounts, Leads, Contacts, etc in the Salesforce CRM. These tools make it easy to build agents and AI apps that can: - Search for Accounts and Contacts by keywords or retrieve them by ID - Read information about Accounts, such as company metadata, opportunities, deals, etc. - Read information about Contacts, such as name, email addresses, phone numbers, email messages, call logs, notes, meetings, tasks, etc. - Create contacts ## Install and Run the Arcade Engine [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#install-and-run-the-arcade-engine) At this time, you need to [self-host](https://docs.arcade.dev/home/auth-providers/salesforce) the Arcade Engine to use the Salesforce toolkit. Follow the step-by-step instructions in the [Salesforce Auth Provider](https://docs.arcade.dev/home/auth-providers/salesforce) page. ## Install [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#install) ```nextra-code pip install arcade_salesforce ``` ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#available-tools) | Tool Name | Description | | --- | --- | | Salesforce.GetAccountDataByKeywords | Searches for accounts in Salesforce and returns them with related info: contacts, leads, notes, calls, opportunities, tasks, emails, and events. | | Salesforce.GetAccountDataByID | Gets the account with related info (contacts, leads, notes, calls, etc). | | Salesforce.CreateContact | Creates a contact in Salesforce associated with an account. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). In order to use the Salesforce toolkit, you must [self-host the Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) and [configure the Salesforce auth provider](https://docs.arcade.dev/home/auth-providers/salesforce). The Arcade Engine is available at `http://localhost:9099` by default. In the code examples below, if necessary, adjust the `base_url` (in Python) or `baseURL` (in JavaScript) parameter in the `Arcade` client constructor to match your environment. ## Salesforce.GetAccountDataByKeywords [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#salesforcegetaccountdatabykeywords) See Example > Searches for accounts in Salesforce and returns them with related info: contacts, leads, notes, calls, opportunities, tasks, emails, and events (up to 10 items of each type). **Parameters** - **query** _(string, required)_ The query to search for accounts. MUST be longer than one character. It will match the keywords against all account fields, such as name, website, phone, address, etc. E.g. ‘Acme’. - **limit** _(int, optional, Defaults to `10`)_ The maximum number of accounts to return. Defaults to 10. Maximum allowed is 10. - **page** _(string, optional)_ The page number to return. Defaults to 1 (first page of results).” ## Salesforce.GetAccountDataByID [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#salesforcegetaccountdatabyid) See Example > Gets the account with related info: contacts, leads, notes, calls, opportunities, tasks, emails, and events (up to 10 items of each type). **Parameters** - **account\_id** _(string, required)_ The ID of the account to get data for. ## Salesforce.CreateContact [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#salesforcecreatecontact) See Example > Creates a contact in Salesforce associated with an account. **Parameters** - **account\_id** _(string, required)_ The ID of the account to create the contact for. - **first\_name** _(string, required)_ The first name of the contact. - **last\_name** _(string, required)_ The last name of the contact. - **email** _(string, required)_ The email address of the contact. - **phone** _(string, optional)_ The phone number of the contact. - **mobile\_phone** _(string, optional)_ The mobile phone number of the contact. - **title** _(string, optional)_ The title of the contact. E.g. ‘CEO’, ‘Sales Director’, ‘CTO’, etc. - **department** _(string, optional)_ The department of the contact. E.g. ‘Marketing’, ‘Sales’, ‘IT’, etc.”. - **description** _(string, optional)_ A description of the contact. ## Self-hosting the Arcade Engine with Salesforce Auth [Permalink for this section](https://docs.arcade.dev/toolkits/sales/salesforce\#self-hosting-the-arcade-engine-with-salesforce-auth) At this time, Arcade Cloud does not support Salesforce auth. In order to use the Salesforce toolkit (or develop custom tools for Salesforce), you have to [self-host the Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) and [configure the Salesforce auth provider](https://docs.arcade.dev/home/auth-providers/salesforce) in your engine configuration. [Hubspot](https://docs.arcade.dev/toolkits/sales/hubspot "Hubspot") [Contribute a toolkit](https://docs.arcade.dev/toolkits/contribute-a-toolkit "Contribute a toolkit") ## Custom Docker Worker Guide [Home](https://docs.arcade.dev/home "Home") [Serve tools](https://docs.arcade.dev/home/serve-tools/arcade-deploy "Serve tools") Docker # Build custom worker images with docker This guide shows you how to build a custom Worker image using Arcade’s base Worker image. It takes you through creating a Dockerfile, installing toolkits, and running the resulting container. ### Requirements [Permalink for this section](https://docs.arcade.dev/home/serve-tools/docker-worker\#requirements) - Docker installed on your machine ### Create your Dockerfile [Permalink for this section](https://docs.arcade.dev/home/serve-tools/docker-worker\#create-your-dockerfile) Create a Dockerfile in your project directory: ```nextra-code ARG VERSION=latest FROM ghcr.io/arcadeai/worker-base:${VERSION} # Copy the file that lists all your desired toolkits COPY toolkits.txt ./ # Install these toolkits RUN pip install -r toolkits.txt ``` With this Dockerfile, we start from the Arcade worker base image, copy in a file named toolkits.txt, and install each toolkit listed there. * * * ## List Your Toolkits [Permalink for this section](https://docs.arcade.dev/home/serve-tools/docker-worker\#list-your-toolkits) Create a file named toolkits.txt in the same directory. Add the toolkits you want installed: ```nextra-code arcade-google arcade-web arcade-zoom ``` Adjust this file as needed. Each line in toolkits.txt should specify a Python package name and version. * * * ## 3\. Build the Image [Permalink for this section](https://docs.arcade.dev/home/serve-tools/docker-worker\#3-build-the-image) From the directory containing the Dockerfile and toolkits.txt, run: ```nextra-code docker build -t custom-worker:0.1.0 . ``` This command creates a Docker image named custom-worker with the tag 0.1.0 using the instructions in your Dockerfile. * * * ## Run the Worker [Permalink for this section](https://docs.arcade.dev/home/serve-tools/docker-worker\#run-the-worker) To start the worker container: ```nextra-code docker run -p 8002:8002 \ -e ARCADE_WORKER_SECRET="your_secret_here" \ custom-worker:0.1.0 ``` Replace “your\_secret\_here” with a secret of your choice. Your engine will need access to this secret to call your worker. The worker will be accessible on port 8002 of your local machine. * * * ## Next Steps [Permalink for this section](https://docs.arcade.dev/home/serve-tools/docker-worker\#next-steps) - Set environment variables (like ARCADE\_WORKER\_SECRET) securely for production use. - Deploy your container to a suitable environment (Docker Swarm, Kubernetes, or another container orchestration platform). Happy coding with Arcade! [Arcade Deploy](https://docs.arcade.dev/home/serve-tools/arcade-deploy "Arcade Deploy") [Modal](https://docs.arcade.dev/home/serve-tools/modal-worker "Modal") ## Google Shopping Search [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google Shopping # Google Shopping Search **Description:** Enable agents to search for products with Google Shopping. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google Shopping Search toolkit provides a pre-built set of tools for interacting with Google Shopping. These tools make it easy to build agents and AI apps that can: - Search for products on Google Shopping; ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_shopping\#available-tools) | Tool Name | Description | | --- | --- | | search.SearchShoppingProducts | Search for products on Google Shopping. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## search.SearchShoppingProducts [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_shopping\#searchsearchshoppingproducts) See Example > Search for products on Google Shopping. **Parameters** - **keywords** _(string, required)_ Keywords to search for. E.g. ‘apple iphone’ or ‘samsung galaxy’ - **`country_code`** _(string, optional, Defaults to ‘us’ United States)_ 2-character country code to use in the Google Shopping search. A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). - **`language_code`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to use in the Google Shopping search. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_shopping\#auth) The Arcade Google Shopping Search toolkit uses the [SerpAPI](https://serpapi.com/) to get product information from Google Shopping. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Default parameter values [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_shopping\#default-parameter-values) Language and Country are configurable through environment variables. When set, they will be used as default for YouTube tools. Providing a different value as `language_code` or `country_code` argument in a tool call will override the default value set in the environment variables. **Language** The language code is a 2-character code that determines the language in which the API will search and return video information. There are two environment variables: - `ARCADE_GOOGLE_LANGUAGE`: a default value for all Google Search tools. If not set, defaults to ‘en’ (English). - `ARCADE_GOOGLE_SHOPPING_LANGUAGE`: a default value for the Google Shopping Search tools. If not set, defaults to `ARCADE_GOOGLE_LANGUAGE`. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). **Country** The country code is a 2-character code that determines the country in which the API will search for videos: - `ARCADE_GOOGLE_COUNTRY`: a default value for all Google Search tools. If not set, defaults to `None`. - `ARCADE_GOOGLE_SHOPPING_COUNTRY`: a default value for the Google Shopping Search tools. If not set, defaults to `ARCADE_GOOGLE_COUNTRY`. If `ARCADE_GOOGLE_COUNTRY` is not set, the default country for Google Shopping tools will be `us` (United States). A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google Search](https://docs.arcade.dev/toolkits/search/google_search "Google Search") [Reference](https://docs.arcade.dev/toolkits/search/reference "Reference") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Twilio Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") TwilioReadme # Arcade Twilio A handy toolkit for easily sending SMS and WhatsApp messages with Twilio. ## Features [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/readme\#features) - Send SMS messages via Twilio - Send WhatsApp messages via Twilio - Built for Arcade integration ## Prerequisites [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/readme\#prerequisites) A Twilio account with: - Account SID - API Key SID - API Key Secret - A Twilio phone number - WhatsApp enabled on your Twilio number (for WhatsApp functionality) To set up your Twilio account and acquire the required credentials, please refer to the Twilio documentation: [Create an API Key](https://www.twilio.com/docs/iam/api-keys#create-an-api-key). This guide will walk you through the process of creating an account and generating the necessary API keys. ## Configuration [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/readme\#configuration) By default, the configuration is loaded from an `engine.env` file in your project root, but you can specify a different file if needed. Ensure the file contains the following variables: ```nextra-code TWILIO_ACCOUNT_SID=your_account_sid TWILIO_API_KEY_SID=your_api_key_sid TWILIO_API_KEY_SECRET=your_api_key_secret TWILIO_PHONE_NUMBER=your_twilio_phone_number MY_PHONE_NUMBER=your_personal_phone_number ``` ## Usage Examples [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/twilio/readme\#usage-examples) Explore the versatility of this toolkit with the following example prompts: - **📩 Send an SMS to your personal number:** _Prompt:_ “Send an SMS to my number saying ‘Hello from Arcade!’” - **💬 Dispatch a WhatsApp message:** _Prompt:_ “Send a WhatsApp message to +19999999999 with the top 10 movies of all time.” - **⏰ Schedule a reminder SMS:** _Prompt:_ “Send an SMS to my number reminding me about the meeting at 3 PM tomorrow.” - **💡 Share a motivational quote via WhatsApp:** _Prompt:_ “Send a WhatsApp message to +19999999999 with the quote ‘The only way to do great work is to love what you do. - Steve Jobs’” - **🌤️ Provide a weather update via SMS:** _Prompt:_ “Send an SMS to +19999999999 with today’s weather forecast for New York City.” - **🎉 Send a birthday greeting via WhatsApp:** _Prompt:_ “Send a WhatsApp message to +19999999999 saying ‘Happy Birthday! Hope you have a fantastic day!’” [Slack](https://docs.arcade.dev/toolkits/social-communication/slack "Slack") [Reference](https://docs.arcade.dev/toolkits/social-communication/twilio/reference "Reference") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Maps Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google Maps # Google Maps **Description:** Enable agents to get directions between two locations with Google Maps. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google Maps toolkit provides a pre-built set of tools for interacting with Google Maps. These tools make it easy to build agents and AI apps that can: - Get directions to a location using an address or latitude/longitude. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_maps\#available-tools) | Tool Name | Description | | --- | --- | | Search.GetDirectionsBetweenAddresses | Get directions between two addresses. | | Search.GetDirectionsBetweenCoordinates | Get directions between two latitude/longitude coordinates. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.GetDirectionsBetweenAddresses [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_maps\#searchgetdirectionsbetweenaddresses) See Example > Get directions between two addresses. **Parameters** - **`origin_address`** _(string, required)_ The origin address. Example: ‘123 Main St, New York, NY 10001’. - **`destination_address`** _(string, required)_ The destination address. Example: ‘456 Main St, New York, NY 10001’. - **`language`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to use in the Google Maps search. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). - **`country`** _(string, optional, Defaults to `None`)_ 2-character country code to use in the Google Maps search. A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). - **`distance_unit`** _(enum ( [GoogleMapsDistanceUnit](https://docs.arcade.dev/toolkits/search/reference#googlemapsdistanceunit)), optional, Defaults to `GoogleMapsDistanceUnit.KM`)_ Distance unit to use in the Google Maps search. - **`travel_mode`** _(enum ( [GoogleMapsTravelMode](https://docs.arcade.dev/toolkits/search/reference#googlemapstravelmode)), optional, Defaults to `GoogleMapsTravelMode.BEST`)_ Travel mode to use in the Google Maps search. ## Search.GetDirectionsBetweenCoordinates [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_maps\#searchgetdirectionsbetweencoordinates) See Example > Get directions between two latitude/longitude coordinates. **Parameters** - **`origin_latitude`** _(float, required)_ The origin latitude. - **`origin_longitude`** _(float, required)_ The origin longitude. - **`destination_latitude`** _(float, required)_ The destination latitude. - **`destination_longitude`** _(float, required)_ The destination longitude. - **`language`** _(string, optional, Defaults to ‘en’ English)_ 2-character language code to use in the Google Maps search. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). - **`country`** _(string, optional, Defaults to `None`)_ 2-character country code to use in the Google Maps search. A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). - **`distance_unit`** _(enum ( [GoogleMapsDistanceUnit](https://docs.arcade.dev/toolkits/search/reference#googlemapsdistanceunit)), optional, Defaults to `GoogleMapsDistanceUnit.KM`)_ Distance unit to use in the Google Maps search. - **`travel_mode`** _(enum ( [GoogleMapsTravelMode](https://docs.arcade.dev/toolkits/search/reference#googlemapstravelmode)), optional, Defaults to `GoogleMapsTravelMode.BEST`)_ Travel mode to use in the Google Maps search. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_maps\#auth) The Arcade Google Maps toolkit uses the [SerpAPI](https://serpapi.com/) to get directions. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Default parameters [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_maps\#default-parameters) Language, Country, Distance Unit, and Travel Mode are configurable through environment variables. When set, they will be used as default for Google Maps tools. Providing a different value as `language`, `country`, `distance_unit`, or `travel_mode` argument in a tool call will override the default value. **Language** The language code is a 2-character code that determines the language in which the API will search and return directions. There are two environment variables: - `ARCADE_GOOGLE_LANGUAGE`: a default value for all Google tools. If not set, defaults to ‘en’ (English). - `ARCADE_GOOGLE_MAPS_LANGUAGE`: a default value for the Google Maps tools. If not set, defaults to `ARCADE_GOOGLE_LANGUAGE`. A list of supported language codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#languagecodes). **Country** The country code is a 2-character code that determines the country in which the API will search for directions: - `ARCADE_GOOGLE_MAPS_COUNTRY`: a default value for the Google Maps tools. If not set, defaults to `None`. A list of supported country codes can be found [here](https://docs.arcade.dev/toolkits/search/reference#countrycodes). **Distance Unit** The distance unit is a string that determines the unit of distance to use in the Google Maps search: - `ARCADE_GOOGLE_MAPS_DISTANCE_UNIT`: a default value for the Google Maps tools. If not set, defaults to `GoogleMapsDistanceUnit.KM`. A list of supported distance units can be found [here](https://docs.arcade.dev/toolkits/search/reference#googlemapsdistanceunit). **Travel Mode** The travel mode is a string that determines the mode of travel to use in the Google Maps search: - `ARCADE_GOOGLE_MAPS_TRAVEL_MODE`: a default value for the Google Maps tools. If not set, defaults to `GoogleMapsTravelMode.BEST`. A list of supported travel modes can be found [here](https://docs.arcade.dev/toolkits/search/reference#googlemapstravelmode). - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google Jobs](https://docs.arcade.dev/toolkits/search/google_jobs "Google Jobs") [Google News](https://docs.arcade.dev/toolkits/search/google_news "Google News") ## Slack Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Slack # Slack auth provider The Slack auth provider enables tools and agents to call [Slack APIs](https://api.slack.com/docs) on behalf of a user. Behind the scenes, the Arcade Engine and the Slack auth provider seamlessly manage Slack OAuth 2.0 authorization for your users. Want to quickly get started with Slack in your agent or AI app? The pre-built [Arcade Slack toolkit](https://docs.arcade.dev/toolkits/social-communication/slack) is what you want! ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#whats-documented-here) This page describes how to use and configure Slack auth with Arcade. This auth provider is used by: - The [Arcade Slack toolkit](https://docs.arcade.dev/toolkits/social-communication/slack), which provides pre-built tools for interacting with Slack - Your [app code](https://docs.arcade.dev/home/auth-providers/slack#using-slack-auth-in-app-code) that needs to call the Slack API - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/slack#using-slack-auth-in-custom-tools) that need to call the Slack API ## Configuring Slack auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#configuring-slack-auth) In a production environment, you will most likely want to use your own Slack app credentials. This way, your users will see your application’s name requesting permission. You can use your own Slack credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Slack app credentials, let’s go through the steps to create a Slack app. ### Create a Slack app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#create-a-slack-app) In May 29, 2025, [Slack announced](https://api.slack.com/changelog/2025-05-terms-rate-limit-update-and-faq) changes to their API rate-limits and terms of service for apps that are not approved for the Slack Marketplace. The `conversations.history` and `conversations.replies` endpoints are now limited to 1 request/minute and up to 15 objects returned per request. This affects various tools in the [Arcade Slack toolkit](https://docs.arcade.dev/toolkits/social-communication/slack). Additionally, the [API Terms of Service](https://slack.com/terms-of-service/api) now requires [Slack Marketplace](https://api.slack.com/slack-marketplace/using) approval for commercial distribution. - Follow Slack’s guide to [registering a Slack app](https://api.slack.com/quickstart) - Choose the scopes (permissions) you need for your app - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the client ID and client secret Next, add the Slack app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Slack Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#configuring-your-own-slack-auth-provider-in-arcade) There are two ways to configure your Slack app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Slack Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Slack**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-slack-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Slack app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Slack auth using your Arcade account credentials, the Arcade Engine will automatically use this Slack OAuth provider. If you have multiple Slack providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Slack auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#set-environment-variables) Set the following environment variables: ```nextra-code export SLACK_CLIENT_ID="" export SLACK_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code SLACK_CLIENT_ID="" SLACK_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `slack` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-slack description: "The default Slack provider" enabled: true type: oauth2 provider_id: slack client_id: ${env:SLACK_CLIENT_ID} client_secret: ${env:SLACK_CLIENT_SECRET} ``` ## Using Slack auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#using-slack-auth-in-app-code) Use the Slack auth provider in your own agents and AI apps to get a user token for the Slack API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the Slack API: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="slack", scopes=[\ "chat:write",\ "im:write",\ "users.profile:read",\ "users:read",\ ], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "slack", { scopes: ["chat:write", "im:write", "users.profile:read", "users:read"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // Do something interesting with the token... ``` ## Using Slack auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/slack\#using-slack-auth-in-custom-tools) You can use the pre-built [Arcade Slack toolkit](https://docs.arcade.dev/toolkits/social-communication/slack) to quickly build agents and AI apps that interact with Slack. If the pre-built tools in the Slack toolkit don’t meet your needs, you can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the Slack API. Use the `Slack()` auth class to specify that a tool requires authorization with Slack. The `context.authorization.token` field will be automatically populated with the user’s Slack token: ```nextra-code from typing import Annotated from slack_sdk import WebClient from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Slack from arcade_tdk.errors import RetryableToolError @tool( requires_auth=Slack( scopes=[\ "chat:write",\ "im:write",\ "users.profile:read",\ "users:read",\ ], ) ) def send_dm_to_user( context: ToolContext, user_name: Annotated[\ str,\ "The Slack username of the person you want to message. Slack usernames are ALWAYS lowercase.",\ ], message: Annotated[str, "The message you want to send"], ): """Send a direct message to a user in Slack.""" slackClient = WebClient(token=context.authorization.token) # Retrieve the user's Slack ID based on their username userListResponse = slackClient.users_list() user_id = None for user in userListResponse["members"]: if user["name"].lower() == user_name.lower(): user_id = user["id"] break if not user_id: raise RetryableToolError( "User not found", developer_message=f"User with username '{user_name}' not found.", ) # Step 2: Retrieve the DM channel ID with the user im_response = slackClient.conversations_open(users=[user_id]) dm_channel_id = im_response["channel"]["id"] # Step 3: Send the message as if it's from you (because we're using a user token) slackClient.chat_postMessage(channel=dm_channel_id, text=message) ``` [Salesforce](https://docs.arcade.dev/home/auth-providers/salesforce "Salesforce") [Spotify](https://docs.arcade.dev/home/auth-providers/spotify "Spotify") ## Microsoft Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") Microsoft # Microsoft auth provider At this time, Arcade does not offer a default Microsoft Auth Provider. To use Microsoft auth, you must create a custom Auth Provider with your own Microsoft OAuth 2.0 credentials as described below. The Microsoft auth provider enables tools and agents to call the Microsoft Graph API on behalf of a user. Behind the scenes, the Arcade Engine and the Microsoft auth provider seamlessly manage Microsoft OAuth 2.0 authorization for your users. ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#whats-documented-here) This page describes how to use and configure Microsoft auth with Arcade. This auth provider is used by: - Your [app code](https://docs.arcade.dev/home/auth-providers/microsoft#using-microsoft-auth-in-app-code) that needs to call Microsoft Graph APIs - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/microsoft#using-microsoft-auth-in-custom-tools) that need to call Microsoft Graph APIs ## Configuring Microsoft auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#configuring-microsoft-auth) In a production environment, you will most likely want to use your own Microsoft app credentials. This way, your users will see your application’s name requesting permission. You can use your own Microsoft credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your Microsoft app credentials, let’s go through the steps to create a Microsoft app. ### Create a Microsoft app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#create-a-microsoft-app) - Follow Microsoft’s guide to [registering an app with the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) - Choose the permissions (scopes) you need for your app - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Copy the client ID and client secret to use below Next, add the Microsoft app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own Microsoft Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#configuring-your-own-microsoft-auth-provider-in-arcade) There are two ways to configure your Microsoft app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure Microsoft Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **Microsoft**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-microsoft-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your Microsoft app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require Microsoft auth using your Arcade account credentials, the Arcade Engine will automatically use this Microsoft OAuth provider. If you have multiple Microsoft providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring Microsoft auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#set-environment-variables) Set the following environment variables: ```nextra-code export MICROSOFT_CLIENT_ID="" export MICROSOFT_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code MICROSOFT_CLIENT_ID="" MICROSOFT_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `microsoft` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-microsoft description: "The default Microsoft provider" enabled: true type: oauth2 provider_id: microsoft client_id: ${env:MICROSOFT_CLIENT_ID} client_secret: ${env:MICROSOFT_CLIENT_SECRET} ``` ## Using Microsoft auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#using-microsoft-auth-in-app-code) Use the Microsoft auth provider in your own agents and AI apps to get a user token for Microsoft Graph APIs. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for Microsoft Graph APIs: PythonJavaScript ```nextra-code from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="microsoft", scopes=["User.Read", "Files.Read"], ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) token = auth_response.context.token # TODO: Do something interesting with the token... ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); const userId = "user@example.com"; // Start the authorization process let authResponse = await client.auth.start(userId, "microsoft", { scopes: ["User.Read", "Files.Read"], }); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); const token = authResponse.context.token; // TODO: Do something interesting with the token... ``` ## Using Microsoft auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/microsoft\#using-microsoft-auth-in-custom-tools) You can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with Microsoft Graph APIs. Use the `Microsoft()` auth class to specify that a tool requires authorization with Microsoft. The `context.authorization.token` field will be automatically populated with the user’s Microsoft token: ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Microsoft @tool( requires_auth=Microsoft( scopes=["User.Read", "Files.Read"], ) ) async def get_file_contents( context: ToolContext, file_id: Annotated[str, "The ID of the file to get the contents of"], ) -> Annotated[str, "The contents of the file"]: """Get the contents of a file from Microsoft Graph.""" url = f"https://graph.microsoft.com/v1.0/me/drive/items/{file_id}" headers = {"Authorization": f"Bearer {context.authorization.token}"} async with httpx.AsyncClient() as client: response = await client.get( url=url, headers=headers, ) response.raise_for_status() return response.json() ``` [Linkedin](https://docs.arcade.dev/home/auth-providers/linkedin "Linkedin") [Notion](https://docs.arcade.dev/home/auth-providers/notion "Notion") ## Arcade Registry Overview [Home](https://docs.arcade.dev/home "Home") Registry Early Access # The Arcade Registry The **Arcade Registry** is how agentic tool developers share their work with the world. Arcade.dev is collecting all the integrations that agents will ever need in one place - think HuggingFace or Pypi but for LLM tools. A powerful community of open source and for-profit developers building out robust and evaluated workflows is how agents can be elevated to being _truly_ useful. Take the survey **_The components of the Arcade Registry_**![The Arcade Registry diagram](https://docs.arcade.dev/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fregistry.d8b58aa5.png&w=3840&q=75&dpl=dpl_7X7SFSaKe9V7iRHd3Et4a6gD5tMs) Unlike traditional read-only tool libraries, Arcade.dev couples the runtime with the registry. This way we can collect real metrics and usage information about your tools, sharing meaningful information and feedback back to the developers. You’ll get error reports and statistics about how your tools are getting used. Arcade.dev also makes it possible for developers to optionally choose to sell their tools with a markup on top of the Arcade platform fees. Thanks to the Arcade Engine, your toolkits will be available via all the protocols Arcade supports - be that MCP for locally-running applications, OXP for server applications, and whatever comes next. Use the open-source Arcade SDKs to future-proof your tools. We are seeking beta testers who are interested in building, maintaining, and sharing toolkits with the world in either a free-to-use or for-profit manner. Sign up today to join the Arcade Registry Beta. ## Early Access Registry Survey Loading... [Changelog](https://docs.arcade.dev/home/changelog "Changelog") ## Using Arcade Tools [Home](https://docs.arcade.dev/home "Home") [OpenAI Agents](https://docs.arcade.dev/home/oai-agents/overview "OpenAI Agents") Using Arcade tools ## Use Arcade with OpenAI Agents [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#use-arcade-with-openai-agents) In this guide, let’s explore how to integrate Arcade tools into your OpenAI Agents application. Follow the step-by-step instructions below. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Set up your environment [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#set-up-your-environment) Install the required packages, and ensure your environment variables are set with your Arcade API key: PythonJavaScript ```nextra-code pip install agents-arcade arcadepy ``` ```nextra-code npm install @openai/agents @arcadeai/arcadejs ``` ### Configure API keys [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#configure-api-keys) Provide your Arcade API key. You can store it in environment variables or directly in your code: > Need an Arcade API key? Visit the [Get an API key](https://docs.arcade.dev/home/api-keys) page to create one. PythonJavaScript ```nextra-code import os os.environ["ARCADE_API_KEY"] = "YOUR_ARCADE_API_KEY" # Or set it directly when initializing the client ``` ```nextra-code # In your .env file ARCADE_API_KEY=YOUR_ARCADE_API_KEY ``` ### Create and manage Arcade tools [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#create-and-manage-arcade-tools) PythonJavaScript Use the `get_arcade_tools` function to retrieve tools from specific toolkits: ```nextra-code from arcadepy import AsyncArcade from agents_arcade import get_arcade_tools # Initialize the Arcade client client = AsyncArcade() # Get all tools from the "Google" toolkit tools = await get_arcade_tools(client, toolkits=["google"]) # You can request multiple toolkits at once tools = await get_arcade_tools(client, toolkits=["google", "github", "linkedin"]) # You can request specific tools tools = await get_arcade_tools(client, tools=["Google_ListEmails", "Slack_ListUsers", "Slack_SendDmToUser"]) ``` ```nextra-code import Arcade from '@arcadeai/arcadejs'; import { executeOrAuthorizeZodTool, toZod } from "@arcadeai/arcadejs/lib"; import { tool } from '@openai/agents'; const client = new Arcade(); // Option 1: Get tools from a single toolkit const googleTools = await client.tools.list({ toolkit: "google", limit: 30 }); const toolsFromGoogle = googleTools.items; // Option 2: Get tools from multiple toolkits const [google, github, linkedin] = await Promise.all([\ client.tools.list({ toolkit: "google", limit: 30 }),\ client.tools.list({ toolkit: "github", limit: 30 }),\ client.tools.list({ toolkit: "linkedin", limit: 30 })\ ]); const toolsFromMultiple = [...google.items, ...github.items, ...linkedin.items]; // Option 3: Get specific tools by name const specificTools = await Promise.all([\ client.tools.get("Google_ListEmails"),\ client.tools.get("Slack_ListUsers"),\ client.tools.get("Slack_SendDmToUser"),\ ]); // Convert any of the above to OpenAI Agents format const convertToAgents = (arcadeTools) => { return toZod({ tools: arcadeTools, client, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) executeFactory: executeOrAuthorizeZodTool, }).map(tool); }; // Use with any of the options above const tools = convertToAgents(toolsFromGoogle); // or toolsFromMultiple or specificTools ``` ### Set up the agent with Arcade tools [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#set-up-the-agent-with-arcade-tools) Create an agent and provide it with the Arcade tools: PythonJavaScript ```nextra-code from agents import Agent, Runner # Create an agent with Google tools google_agent = Agent( name="Google agent", instructions="You are a helpful assistant that can assist with Google API calls.", model="gpt-4o-mini", tools=tools, ) ``` ```nextra-code import { Agent, Runner, tool } from '@openai/agents'; // Create an agent with Arcade tools const googleAgent = new Agent({ name: "Google agent", instructions: "You are a helpful assistant that can assist with Google API calls.", model: "gpt-4o-mini", tools }); ``` ### Run the agent [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#run-the-agent) PythonJavaScript Run the agent, providing a user\_id for tool authorization: ```nextra-code try: result = await Runner.run( starting_agent=google_agent, input="What are my latest emails?", context={"user_id": "user@example.com"}, ) print("Final output:\n\n", result.final_output) except AuthorizationError as e: print("Please Login to Google:", e) ``` ```nextra-code const result = await run(googleAgent, "What are my latest emails?"); ``` ### Handle authentication [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#handle-authentication) PythonJavaScript If a tool requires authorization, an `AuthorizationError` will be raised with an authorization URL: ```nextra-code from agents_arcade.errors import AuthorizationError try: # Run agent code from earlier examples # ... except AuthorizationError as e: print(f"Please visit this URL to authorize: {e}") # The URL contained in the error will take the user to the authorization page ``` If a tool requires authorization, the agent will show a message like this: ```nextra-code [Authorize Gmail Access](https://accounts.google.com/o/oauth2/v2/auth?access_type=offline...) Once you have authorized access, I can retrieve your latest emails. ``` ### Complete example [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#complete-example) Here’s a complete example putting everything together: PythonJavaScript ```nextra-code from agents import Agent, Runner from arcadepy import AsyncArcade from agents_arcade import get_arcade_tools from agents_arcade.errors import AuthorizationError async def main(): client = AsyncArcade() tools = await get_arcade_tools(client, toolkits=["google"]) google_agent = Agent( name="Google agent", instructions="You are a helpful assistant that can assist with Google API calls.", model="gpt-4o-mini", tools=tools, ) try: result = await Runner.run( starting_agent=google_agent, input="What are my latest emails?", context={"user_id": "user@example.com"}, ) print("Final output:\n\n", result.final_output) except AuthorizationError as e: print("Please Login to Google:", e) if __name__ == "__main__": import asyncio asyncio.run(main()) ``` Check out the complete working example in our [GitHub repository](https://github.com/ArcadeAI/arcade-ai/tree/main/examples/openai-agents-ts/src/index.ts). ```nextra-code import Arcade from '@arcadeai/arcadejs'; import { executeOrAuthorizeZodTool, toZod } from "@arcadeai/arcadejs/lib"; import { Agent, run, tool } from '@openai/agents'; // 1) Initialize Arcade client const client = new Arcade(); // 2) Fetch Google toolkit from Arcade and prepare tools for OpenAI Agents const googleToolkit = await client.tools.list({ toolkit: "google", limit: 30 }); const tools = toZod({ tools: googleToolkit.items, client, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) executeFactory: executeOrAuthorizeZodTool, }).map(tool); // 3) Create a new agent with the Google toolkit const googleAgent = new Agent({ name: "Google agent", instructions: "You are a helpful assistant that can assist with Google API calls.", model: "gpt-4o-mini", tools }); // 4) Run the agent const result = await run(googleAgent, "What are my latest emails?"); // 5) Print the result console.log(result.finalOutput); ``` ## Tips for selecting tools [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#tips-for-selecting-tools) - **Relevance**: Pick only the tools you need. Avoid using all tools at once. - **User identification**: Always provide a unique and consistent `user_id` for each user. Use your internal or database user ID, not something entered by the user. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/oai-agents/use-arcade-tools\#next-steps) Now that you have integrated Arcade tools into your OpenAI Agents application, you can: - Experiment with different toolkits, such as “github” or “linkedin” - Customize the agent’s instructions for specific tasks - Try out multi-agent systems using different Arcade tools - Build your own custom tools with the Arcade Tool SDK Enjoy exploring Arcade and building powerful AI-enabled Python applications! [Overview](https://docs.arcade.dev/home/oai-agents/overview "Overview") [Managing user authorization](https://docs.arcade.dev/home/oai-agents/user-auth-interrupts "Managing user authorization") ## Google Finance Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") Search ToolsGoogle Finance # Google Finance **Description:** Empower your agents to retrieve stock data using Arcade. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Google Finance toolkit lets you fetch real-time and historical stock data with ease. Use these tools to build intelligent agents and applications that fetch: - Stock summary data. - Historical stock data. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_finance\#available-tools) | Tool Name | Description | | --- | --- | | Search.GetStockSummary | Retrieve current price and recent price movement of a stock. | | Search.GetStockHistoricalData | Fetch historical stock price and volume data for a specified time window. | If you need an action that’s not listed here, please [contact us](mailto:contact@arcade.dev) to request a new tool, or [create your own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.GetStockSummary [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_finance\#searchgetstocksummary) Retrieve summary information for a given stock using the Google Finance API via SerpAPI. This tool returns the current price and price change from the most recent trading day. **Parameters** - **`ticker_symbol`** _(string, required)_: The stock ticker, e.g., ‘GOOG’. - **`exchange_identifier`** _(string, required)_: The market identifier, e.g., ‘NASDAQ’. See Example > ## Search.GetStockHistoricalData [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_finance\#searchgetstockhistoricaldata) Fetch historical data for a given stock over a defined time window. This tool returns the stock’s price and volume data along with key events when available. **Parameters** - **`ticker_symbol`** _(string, required)_: The stock ticker, e.g., ‘GOOG’. - **`exchange_identifier`** _(string, required)_: The market identifier, e.g., ‘NASDAQ’ or ‘NYSE’. - **`window`** _(enum ( [GoogleFinanceWindow](https://docs.arcade.dev/toolkits/search/reference#googlefinancewindow)), optional, defaults to ONE\_MONTH)_: Time window for the graph data. See Example > ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_finance\#auth) The Arcade Google Finance toolkit uses the [SerpAPI](https://serpapi.com/) to get stock data from Google Finance. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Stripe](https://docs.arcade.dev/toolkits/payments/stripe "Stripe") [Google Flights](https://docs.arcade.dev/toolkits/search/google_flights "Google Flights") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## User Authorization Workflow [Home](https://docs.arcade.dev/home "Home") [LangChain](https://docs.arcade.dev/home/langchain/use-arcade-tools "LangChain") User authorization ## User Authorization in LangGraph [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#user-authorization-in-langgraph) In this guide, you will create a LangGraph workflow that requires user authorization before running certain Arcade tools. When a tool needs authorization, the graph displays an authorization URL and waits for the user’s approval. This ensures that only the tools you explicitly authorize are available to the language model. For complete working examples, see our [Python](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain/langgraph_with_user_auth.py) and [JavaScript](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain-ts/langgraph-with-user-auth.ts) examples. ### Prerequisites [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#prerequisites) - [Obtain an Arcade API key](https://docs.arcade.dev/home/api-keys) ### Install the required packages [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#install-the-required-packages) Set up your environment with the following installations: PythonJavaScript ```nextra-code pip install langchain-arcade langchain-openai langgraph ``` ```nextra-code npm install @arcadeai/arcadejs @langchain/openai @langchain/core @langchain/langgraph ``` ### Configure your Arcade environment [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#configure-your-arcade-environment) Make sure you have set your Arcade API key (and any other relevant keys) in the environment, or assign them directly in the code: > Need an Arcade API key? Visit the [Get an API key](https://docs.arcade.dev/home/api-keys) page to create one. PythonJavaScript ```nextra-code import os # Import necessary classes and modules from langchain_arcade import ArcadeToolManager from langchain_openai import ChatOpenAI from langgraph.checkpoint.memory import MemorySaver from langgraph.graph import END, START, MessagesState, StateGraph from langgraph.prebuilt import ToolNode arcade_api_key = os.environ["ARCADE_API_KEY"] # Initialize the tool manager and fetch tools compatible with langgraph tool_manager = ArcadeToolManager(api_key=arcade_api_key) tools = tool_manager.get_tools(toolkits=["Google"]) tool_node = ToolNode(tools) # Create a language model instance and bind it with the tools model = ChatOpenAI(model="gpt-4o") model_with_tools = model.bind_tools(tools) ``` Here are the main code elements: - arcade\_api\_key is your Arcade key. - tool\_manager fetches your Arcade tools, for example the “Google” toolkit. - tool\_node encapsulates these tools for usage in LangGraph. - model\_with\_tools binds your tools to the “gpt-4o” language model, enabling tool calls. ```nextra-code import { pathToFileURL } from "node:url"; import { Arcade } from "@arcadeai/arcadejs"; import { toZod } from "@arcadeai/arcadejs/lib"; import type { AIMessage } from "@langchain/core/messages"; import { tool } from "@langchain/core/tools"; import { MessagesAnnotation, StateGraph } from "@langchain/langgraph"; import { ToolNode } from "@langchain/langgraph/prebuilt"; import { ChatOpenAI } from "@langchain/openai"; // Initialize Arcade with API key from environment const arcade = new Arcade(); // Replace with your application's user ID (e.g. email address, UUID, etc.) const USER_ID = "user@example.com"; // Initialize tools from Google toolkit const googleToolkit = await arcade.tools.list({ toolkit: "google", limit: 30 }); const arcadeTools = toZod({ tools: googleToolkit.items, client: arcade, userId: USER_ID, }); // Convert Arcade tools to LangGraph tools const tools = arcadeTools.map(({ name, description, execute, parameters }) => tool(execute, { name, description, schema: parameters, }), ); // Initialize the prebuilt tool node const toolNode = new ToolNode(tools); // Create a language model instance and bind it with the tools const model = new ChatOpenAI({ model: "gpt-4o", apiKey: process.env.OPENAI_API_KEY, }); const modelWithTools = model.bindTools(tools); ``` Here are the main code elements: - arcade.tools.list fetches your Arcade tools, for example the “Google” toolkit. - toZod converts Arcade tools to Zod schemas, which are required by LangGraph. - ToolNode encapsulates these tools for usage in LangGraph. - modelWithTools binds your tools to the “gpt-4o” language model, enabling tool calls. ### Define the workflow steps [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#define-the-workflow-steps) You will create three primary functions to handle AI interaction, tool authorization, and flow control. PythonJavaScript ```nextra-code # Function to invoke the model and get a response def call_agent(state: MessagesState): messages = state["messages"] response = model_with_tools.invoke(messages) # Return the updated message history return {"messages": [response]} # Function to determine the next step in the workflow based on the last message def should_continue(state: MessagesState): if state["messages"][-1].tool_calls: for tool_call in state["messages"][-1].tool_calls: if tool_manager.requires_auth(tool_call["name"]): return "authorization" return "tools" # Proceed to tool execution if no authorization is needed return END # End the workflow if no tool calls are present # Function to handle authorization for tools that require it def authorize(state: MessagesState, config: dict): user_id = config["configurable"].get("user_id") for tool_call in state["messages"][-1].tool_calls: tool_name = tool_call["name"] if not tool_manager.requires_auth(tool_name): continue auth_response = tool_manager.authorize(tool_name, user_id) if auth_response.status != "completed": # Prompt the user to visit the authorization URL print(f"Visit the following URL to authorize: {auth_response.url}") # Wait for the user to complete the authorization # and then check the authorization status again tool_manager.wait_for_auth(auth_response.id) if not tool_manager.is_authorized(auth_response.id): # This stops execution if authorization fails raise ValueError("Authorization failed") return {"messages": []} ``` Explanations for these functions: - call\_agent: Invokes the language model using the latest conversation state. - should\_continue: Checks the last AI message for any tool calls. If a tool requires authorization, the flow transitions to authorization. Otherwise, it goes straight to tool execution or ends if no tools are called. - authorize: Prompts the user to authorize any required tools, blocking until authorization is completed successfully or fails. ```nextra-code // Function to check if a tool requires authorization async function requiresAuth(toolName: string): Promise<{ needsAuth: boolean; id: string; authUrl: string; }> { const authResponse = await arcade.tools.authorize({ tool_name: toolName, user_id: USER_ID, }); return { needsAuth: authResponse.status === "pending", id: authResponse.id ?? "", authUrl: authResponse.url ?? "", }; } // Function to invoke the model and get a response async function callAgent( state: typeof MessagesAnnotation.State, ): Promise { const messages = state.messages; const response = await modelWithTools.invoke(messages); return { messages: [response] }; } // Function to determine the next step in the workflow based on the last message async function shouldContinue( state: typeof MessagesAnnotation.State, ): Promise { const lastMessage = state.messages[state.messages.length - 1] as AIMessage; if (lastMessage.tool_calls?.length) { for (const toolCall of lastMessage.tool_calls) { const { needsAuth } = await requiresAuth(toolCall.name); if (needsAuth) { return "authorization"; } } return "tools"; // Proceed to tool execution if no authorization is needed } return "__end__"; // End the workflow if no tool calls are present } // Function to handle authorization for tools that require it async function authorize( state: typeof MessagesAnnotation.State, ): Promise { const lastMessage = state.messages[state.messages.length - 1] as AIMessage; for (const toolCall of lastMessage.tool_calls || []) { const toolName = toolCall.name; const { needsAuth, id, authUrl } = await requiresAuth(toolName); if (needsAuth) { // Prompt the user to visit the authorization URL console.log(`Visit the following URL to authorize: ${authUrl}`); // Wait for the user to complete the authorization const response = await arcade.auth.waitForCompletion(id); if (response.status !== "completed") { throw new Error("Authorization failed"); } } } return { messages: [] }; } ``` Explanations for these functions: - requiresAuth: Checks if a tool requires authorization. - callAgent: Invokes the language model using the latest conversation state. - shouldContinue: Checks the last AI message for any tool calls. If a tool requires authorization, the flow transitions to authorization. Otherwise, it goes straight to tool execution or ends if no tools are called. - authorize: Prompts the user to authorize any required tools, blocking until authorization is completed successfully or fails. ### Build and compile your LangGraph workflow [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#build-and-compile-your-langgraph-workflow) Use StateGraph to assemble the nodes and edges, then compile the graph with a MemorySaver. PythonJavaScript ```nextra-code if __name__ == "__main__": # Build the workflow graph using StateGraph workflow = StateGraph(MessagesState) # Add nodes (steps) to the graph workflow.add_node("agent", call_agent) workflow.add_node("tools", tool_node) workflow.add_node("authorization", authorize) # Define the edges and control flow between nodes workflow.add_edge(START, "agent") workflow.add_conditional_edges("agent", should_continue, ["authorization", "tools", END]) workflow.add_edge("authorization", "tools") workflow.add_edge("tools", "agent") # Set up memory for checkpointing the state memory = MemorySaver() # Compile the graph with the checkpointer graph = workflow.compile(checkpointer=memory) ``` ```nextra-code // Build the workflow graph const workflow = new StateGraph(MessagesAnnotation) .addNode("agent", callAgent) .addNode("tools", toolNode) .addNode("authorization", authorize) .addEdge("__start__", "agent") .addConditionalEdges("agent", shouldContinue, [\ "authorization",\ "tools",\ "__end__",\ ]) .addEdge("authorization", "tools") .addEdge("tools", "agent"); // Compile the graph const graph = workflow.compile(); ``` ### Provide inputs and run the graph [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#provide-inputs-and-run-the-graph) Finally, define user-supplied messages, authorization config, and stream the outputs. The graph will pause for any required tool authorization. PythonJavaScript ```nextra-code # Define the input messages from the user inputs = { "messages": [\ {\ "role": "user",\ "content": "Check and see if I have any important emails in my inbox",\ }\ ], } # Configuration with thread and user IDs for authorization purposes config = {"configurable": {"thread_id": "4", "user_id": "user@example.com"}} # Run the graph and stream the outputs for chunk in graph.stream(inputs, config=config, stream_mode="values"): # Pretty-print the last message in the chunk chunk["messages"][-1].pretty_print() ``` ```nextra-code const inputs = { messages: [\ {\ role: "user",\ content: "Check and see if I have any important emails in my inbox",\ },\ ], }; // Run the graph and stream the outputs const stream = await graph.stream(inputs, { streamMode: "values" }); for await (const chunk of stream) { // Print the last message in the chunk console.log(chunk.messages[chunk.messages.length - 1].content); } ``` In this example: - The user prompts the agent to check emails. - The message triggers a potential need for the “Google” tools. - If authorization is required, the code prints a URL and waits until you permit the tool call. ## Next steps [Permalink for this section](https://docs.arcade.dev/home/langchain/user-auth-interrupts\#next-steps) - Experiment with more Arcade toolkits for expanded capabilities. - Explore advanced authorization logic, such as multi-user or role-based checks. - Integrate additional nodes to handle more complex flows or multi-step tasks in your LangGraph. By combining Arcade’s authorization features with stateful management in LangGraph, you can build AI-driven workflows that respect user permissions at every step. Have fun exploring Arcade! [Using Arcade tools](https://docs.arcade.dev/home/langchain/use-arcade-tools "Using Arcade tools") [Authorizing existing tools](https://docs.arcade.dev/home/langchain/auth-langchain-tools "Authorizing existing tools") ## GitHub Auth Provider [Home](https://docs.arcade.dev/home "Home") [Customizing Auth](https://docs.arcade.dev/home/auth-providers "Customizing Auth") GitHub # GitHub auth provider The GitHub auth provider enables tools and agents to call [GitHub APIs](https://docs.github.com/en/rest/overview/resources-in-the-rest-api) on behalf of a user. Behind the scenes, the Arcade Engine and the GitHub auth provider seamlessly manage GitHub OAuth 2.0 authorization for your users. Want to quickly get started with GitHub in your agent or AI app? The pre-built [Arcade GitHub toolkit](https://docs.arcade.dev/toolkits/development/github/github) is what you want! ### What’s documented here [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#whats-documented-here) This page describes how to use and configure GitHub auth with Arcade. This auth provider is used by: - The [Arcade GitHub toolkit](https://docs.arcade.dev/toolkits/development/github/github), which provides pre-built tools for interacting with GitHub - Your [app code](https://docs.arcade.dev/home/auth-providers/github#using-github-auth-in-app-code) that needs to call the GitHub API - Or, your [custom tools](https://docs.arcade.dev/home/auth-providers/github#using-github-auth-in-custom-tools) that need to call the GitHub API ## Configuring GitHub auth [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#configuring-github-auth) In a production environment, you will most likely want to use your own GitHub app credentials. This way, your users will see your application’s name requesting permission. You can use your own GitHub credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](https://docs.arcade.dev/home/local-deployment/install/local) instance. Before showing how to configure your GitHub app credentials, let’s go through the steps to create a GitHub app. ### Create a GitHub app [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#create-a-github-app) - Follow GitHub’s guide to [registering a GitHub app](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) - Choose the permissions you need for your app - At a minimum, you must enable read-only access to the Account > Email addresses permission - To access repo data, you must enable at least the Repository > Contents permission - Set the redirect URL to: `https://cloud.arcade.dev/api/v1/oauth/callback` - Leave “Request user authorization (OAuth) during installation” **unchecked** - Leave “Setup URL” blank and “Redirect on update” **unchecked** - Ensure Optional features > User-to-server token expiration is enabled - Copy the client ID and generate a client secret to use below If you need to access private repositories in an organization, you must also: 1. Make the app public via Advanced > Make public 2. Add the app to the organization via Install app Next, add the GitHub app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance). ## Configuring your own GitHub Auth Provider in Arcade [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#configuring-your-own-github-auth-provider-in-arcade) There are two ways to configure your GitHub app credentials in Arcade: 1. From the Arcade Dashboard GUI 2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine) We show both options step-by-step below. Dashboard GUIEngine Configuration YAML ### Configure GitHub Auth Using the Arcade Dashboard GUI #### Access the Arcade Dashboard [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#access-the-arcade-dashboard) To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment. #### Navigate to the OAuth Providers page [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#navigate-to-the-oauth-providers-page) - Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. - Click **Add OAuth Provider** in the top right corner. - Select the **Included Providers** tab at the top. - In the **Provider** dropdown, select **GitHub**. #### Enter the provider details [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#enter-the-provider-details) - Choose a unique **ID** for your provider (e.g. “my-github-provider”). - Optionally enter a **Description**. - Enter the **Client ID** and **Client Secret** from your GitHub app. #### Create the provider [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#create-the-provider) Hit the **Create** button and the provider will be ready to be used in the Arcade Engine. When you use tools that require GitHub auth using your Arcade account credentials, the Arcade Engine will automatically use this GitHub OAuth provider. If you have multiple GitHub providers, see [using multiple auth providers of the same type](https://docs.arcade.dev/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. ### Configuring GitHub auth in self-hosted Arcade Engine configuration ### Set environment variables [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#set-environment-variables) Set the following environment variables: ```nextra-code export GITHUB_CLIENT_ID="" export GITHUB_CLIENT_SECRET="" ``` Or, you can set these values in a `.env` file: ```nextra-code GITHUB_CLIENT_ID="" GITHUB_CLIENT_SECRET="" ``` See [Engine configuration](https://docs.arcade.dev/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine. ### Edit the Engine configuration [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#edit-the-engine-configuration) Edit the `engine.yaml` file and add a `github` item to the `auth.providers` section: ```nextra-code auth: providers: - id: default-github description: "The default GitHub provider" enabled: true type: oauth2 provider_id: github client_id: ${env:GITHUB_CLIENT_ID} client_secret: ${env:GITHUB_CLIENT_SECRET} ``` ## Using GitHub auth in app code [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#using-github-auth-in-app-code) Use the GitHub auth provider in your own agents and AI apps to get a user token for the GitHub API. See [authorizing agents with Arcade](https://docs.arcade.dev/home/auth/how-arcade-helps) to understand how this works. Use `client.auth.start()` to get a user token for the GitHub API: PythonJavaScript ```nextra-code import requests from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "user@example.com" """ In this example, we will use Arcade to authenticate with GitHub and retrieve the number of stargazers of the ArcadeAI/arcade-ai repository. There is a tool for that in the Arcade SDK, which simplifies the process for you to interact with GitHub either through our Python or JavaScript SDKs or via LLM tool calling. Below we are just showing how to use Arcade as an auth provider, if you ever need to. """ # Start the authorization process auth_response = client.auth.start( user_id=user_id, provider="github", ) if auth_response.status != "completed": print("Please complete the authorization challenge in your browser:") print(auth_response.url) # Wait for the authorization to complete auth_response = client.auth.wait_for_completion(auth_response) if not auth_response.context.token: raise ValueError("No token found in auth response") token = auth_response.context.token owner = "ArcadeAI" name = "arcade-ai" headers = { "Accept": "application/vnd.github+json", "Authorization": f"Bearer {token}", "X-GitHub-Api-Version": "2022-11-28", } url = f"https://api.github.com/repos/{owner}/{name}" response = requests.get(url, headers=headers) response.raise_for_status() print(response.json().get("stargazers_count")) ``` ```nextra-code import { Arcade } from "@arcadeai/arcadejs"; const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "user@example.com"; /* In this example, we will use Arcade to authenticate with GitHub and retrieve the number of stargazers of the ArcadeAI/arcade-ai repository. There is a tool for that in the Arcade SDK, which simplifies the process for you to interact with GitHub either through our Python or JavaScript SDKs or via LLM tool calling. Below we are just showing how to use Arcade as an auth provider, if you ever need to. */ // Start the authorization process let authResponse = await client.auth.start(userId, "github"); if (authResponse.status !== "completed") { console.log("Please complete the authorization challenge in your browser:"); console.log(authResponse.url); } // Wait for the authorization to complete authResponse = await client.auth.waitForCompletion(authResponse); if (!authResponse.context.token) { throw new Error("No token found in auth response"); } const token = authResponse.context.token; const owner = "ArcadeAI"; const name = "arcade-ai"; const headers = { Accept: "application/vnd.github+json", Authorization: `Bearer ${token}`, "X-GitHub-Api-Version": "2022-11-28", }; const url = `https://api.github.com/repos/${owner}/${name}`; const response = await fetch(url, { headers }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log(data.stargazers_count); ``` ## Using GitHub auth in custom tools [Permalink for this section](https://docs.arcade.dev/home/auth-providers/github\#using-github-auth-in-custom-tools) You can use the pre-built [Arcade GitHub toolkit](https://docs.arcade.dev/toolkits/development/github/github) to quickly build agents and AI apps that interact with GitHub. If the pre-built tools in the GitHub toolkit don’t meet your needs, you can author your own [custom tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) that interact with the GitHub API. Use the `GitHub()` auth class to specify that a tool requires authorization with GitHub. The `context.authorization.token` field will be automatically populated with the user’s GitHub token: ```nextra-code from typing import Annotated import httpx from arcade_tdk import ToolContext, tool from arcade_tdk.auth import GitHub @tool(requires_auth=GitHub()) async def count_stargazers( context: ToolContext, owner: Annotated[str, "The owner of the repository"], name: Annotated[str, "The name of the repository"], ) -> Annotated[int, "The number of stargazers (stars) for the specified repository"]: """Count the number of stargazers (stars) for a GitHub repository.""" if not context.authorization or not context.authorization.token: raise ValueError("No token found in context") headers = { "Accept": "application/vnd.github+json", "Authorization": f"Bearer {context.authorization.token}", "X-GitHub-Api-Version": "2022-11-28", } url = f"https://api.github.com/repos/{owner}/{name}" async with httpx.AsyncClient() as client: response = await client.get(url, headers=headers) response.raise_for_status() return response.json().get("stargazers_count", 0) ``` [Dropbox](https://docs.arcade.dev/home/auth-providers/dropbox "Dropbox") [Google](https://docs.arcade.dev/home/auth-providers/google "Google") ## Spotify Toolkit Overview [Integrations](https://docs.arcade.dev/toolkits "Integrations") EntertainmentSpotify # Spotify **Description:** Enable agents to interact with Spotify tracks. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/spotify) **Auth:** User authorizationvia the [Spotify auth provider](https://docs.arcade.dev/home/auth-providers/spotify) This Toolkit is not available in Arcade Cloud. You can use these tools with a [self-hosted](https://docs.arcade.dev/home/local-deployment/install/overview) instance of Arcade. [![PyPI Version](https://img.shields.io/pypi/v/arcade_spotify)](https://pypi.org/project/arcade_spotify/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_spotify)](https://pypi.org/project/arcade_spotify/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_spotify)](https://pypi.org/project/arcade_spotify/)[![Downloads](https://img.shields.io/pypi/dm/arcade_spotify)](https://pypi.org/project/arcade_spotify/) The Arcade Spotify toolkit provides a pre-built set of tools for interacting with Spotify. These tools make it easy to build agents and AI apps that can: - Get information about tracks - Search for tracks - Control playback ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#available-tools) These tools are currently available in the Arcade Spotify toolkit. | Tool Name | Description | | --- | --- | | Spotify.GetTrackFromId | Get information about a track | | Spotify.AdjustPlaybackPosition | Adjust the playback position within the currently playing track. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.SkipToPreviousTrack | Skip to the previous track in the user's queue, if any. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.SkipToNextTrack | Skip to the next track in the user's queue, if any. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.PausePlayback | Pause the currently playing track, if any. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.ResumePlayback | Resume the currently playing track, if any. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.StartTracksPlaybackById | Start playback of a list of tracks (songs). Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.GetPlaybackState | Get information about the user's current playback state, including track or episode, and active device. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.GetCurrentlyPlaying | Get information about the user's currently playing track. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.PlayArtistByName | Plays a song by an artist and queues four more songs by the same artist. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.PlayTrackByName | Plays a song by name. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.GetAvailableDevices | Get the available devices. Note: This tool currently requires a self-hosted instance of Arcade. | | Spotify.Search | Search Spotify catalog information. Note: This tool currently requires a self-hosted instance of Arcade. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [Spotify auth\\ provider](https://docs.arcade.dev/home/auth-providers/spotify#using-spotify-auth-in-customtools). ## Spotify.GetTrackFromId [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifygettrackfromid) See Example > Get information about a track **Parameters** - `track_id` _(string, required)_ The Spotify ID of the track * * * ## Spotify.AdjustPlaybackPosition [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifyadjustplaybackposition) See Example > Adjust the playback position within the currently playing track. Knowledge of the current playback state is NOT needed to use this tool as it handles clamping the position to valid start/end boundaries to prevent overshooting or negative values. This tool allows you to seek to a specific position within the currently playing track. You can either provide an absolute position in milliseconds or a relative position from the current playback position in milliseconds. Note: Either absolute\_position\_ms or relative\_position\_ms must be provided, but not both. **Parameters** - `absolute_position_ms` _(integer, optional)_ The absolute position in milliseconds to seek to - `relative_position_ms` _(integer, optional)_ The relative position from the current playback position in milliseconds to seek to * * * ## Spotify.SkipToPreviousTrack [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifyskiptoprevioustrack) See Example > Skip to the previous track in the user’s queue, if any * * * ## Spotify.SkipToNextTrack [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifyskiptonexttrack) See Example > Skip to the next track in the user’s queue, if any * * * ## Spotify.PausePlayback [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifypauseplayback) See Example > Pause the currently playing track, if any * * * ## Spotify.ResumePlayback [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifyresumeplayback) See Example > Resume the currently playing track, if any * * * ## Spotify.StartTracksPlaybackById [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifystarttracksplaybackbyid) See Example > Start playback of a list of tracks (songs) **Parameters** - `track_ids` _(array, required)_ A list of Spotify track (song) IDs to play. Order of execution is not guarenteed. - `position_ms` _(integer, optional)_ The position in milliseconds to start the first track from * * * ## Spotify.GetPlaybackState [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifygetplaybackstate) See Example > Get information about the user’s current playback state, including track or episode, and active device. This tool does not perform any actions. Use other tools to control playback. * * * ## Spotify.GetCurrentlyPlaying [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifygetcurrentlyplaying) See Example > Get information about the user’s currently playing track * * * ## Spotify.PlayArtistByName [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifyplayartistbyname) See Example > Plays a song by an artist and queues four more songs by the same artist **Parameters** - `name` _(string, required)_ The name of the artist to play * * * ## Spotify.PlayTrackByName [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifyplaytrackbyname) See Example > Plays a song by name **Parameters** - `track_name` _(string, required)_ The name of the track to play - `artist_name` _(string, optional)_ The name of the artist of the track ## Spotify.GetAvailableDevices [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifygetavailabledevices) See Example > Get the available devices * * * ## Spotify.Search [Permalink for this section](https://docs.arcade.dev/toolkits/entertainment/spotify\#spotifysearch) See Example > Search Spotify catalog information Explanation of the q parameter: You can narrow down your search using field filters. The available filters are album, artist, track, year, upc, tag:hipster, tag:new, isrc, and genre. Each field filter only applies to certain result types. The artist and year filters can be used while searching albums, artists and tracks. You can filter on a single year or a range (e.g. 1955-1960). The album filter can be used while searching albums and tracks. The genre filter can be used while searching artists and tracks. The isrc and track filters can be used while searching tracks. The upc, tag:new and tag:hipster filters can only be used while searching albums. The tag:new filter will return albums released in the past two weeks and tag:hipster can be used to return only albums with the lowest 10% popularity. Example: q=“remaster track:Doxy artist:Miles Davis” **Parameters** - `q` _(string, required)_ The search query - `types` _(array, required)_ The types of results to return, Valid values are ‘album’, ‘artist’, ‘playlist’, ‘track’, ‘show’, ‘episode’, ‘audiobook’ - `limit` _(integer, optional)_ The maximum number of results to return. Defaults to `1`. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_spotify\\ ```](https://docs.arcade.dev/home/hosting-overview) [Reddit](https://docs.arcade.dev/toolkits/social-communication/reddit "Reddit") [Twitch](https://docs.arcade.dev/toolkits/entertainment/twitch "Twitch") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Google Search Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Search Tools](https://docs.arcade.dev/toolkits/search/google_finance "Search Tools") Google Search # Google Search **Description:** Enable agents to perform Google searches using SerpAPI. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/search) **Auth:** API Key [![PyPI Version](https://img.shields.io/pypi/v/arcade_search)](https://pypi.org/project/arcade_search/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_search)](https://pypi.org/project/arcade_search/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_search)](https://pypi.org/project/arcade_search/)[![Downloads](https://img.shields.io/pypi/dm/arcade_search)](https://pypi.org/project/arcade_search/) The Arcade Search toolkit provides a pre-built set of tools for interacting with Google search results. These tools make it easy to build agents and AI apps that can: - Search Google and return results. ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_search\#available-tools) | Tool Name | Description | | --- | --- | | Search.SearchGoogle | Search Google and return organic results. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit). ## Search.SearchGoogle [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_search\#searchsearchgoogle) See Example > Search Google using SerpAPI and return organic search results. **Parameters** - **`query`** _(string, required)_ The search query. - **`n_results`** _(integer, optional, Defaults to 5)_ Number of results to retrieve. ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/search/google_search\#auth) The Arcade Google Search toolkit uses the [SerpAPI](https://serpapi.com/) to get get results from a Google search. - **Secret:** - `SERP_API_KEY`: Your SerpAPI API key. Setting the `SERP_API_KEY` secret is only required if you are [self-hosting](https://docs.arcade.dev/home/local-deployment/install/overview) Arcade. If you’re using Arcade Cloud, the secret is already set for you. To manage your secrets, go to the [Secrets page](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_search\\ ```](https://docs.arcade.dev/home/hosting-overview) [Google News](https://docs.arcade.dev/toolkits/search/google_news "Google News") [Google Shopping](https://docs.arcade.dev/toolkits/search/google_shopping "Google Shopping") ## LinkedIn Toolkit [Integrations](https://docs.arcade.dev/toolkits "Integrations") [Social & Communication](https://docs.arcade.dev/toolkits/social-communication/discord "Social & Communication") LinkedIn # LinkedIn **Description:** Enable agents to interact with LinkedIn. **Author:** Arcade **Code:** [GitHub](https://github.com/ArcadeAI/arcade-ai/tree/main/toolkits/linkedin) **Auth:** User authorizationvia the [LinkedIn auth provider](https://docs.arcade.dev/home/auth-providers/linkedin) [![PyPI Version](https://img.shields.io/pypi/v/arcade_linkedin)](https://pypi.org/project/arcade_linkedin/)[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/arcadeai/arcade-ai/blob/main/LICENSE)[![Python Versions](https://img.shields.io/pypi/pyversions/arcade_linkedin)](https://pypi.org/project/arcade_linkedin/)[![Wheel Status](https://img.shields.io/pypi/wheel/arcade_linkedin)](https://pypi.org/project/arcade_linkedin/)[![Downloads](https://img.shields.io/pypi/dm/arcade_linkedin)](https://pypi.org/project/arcade_linkedin/) The Arcade LinkedIn toolkit provides a pre-built set of tools for interacting with LinkedIn. These tools make it easy to build agents and AI apps that can: - Create a post ## Available Tools [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/linkedin\#available-tools) These tools are currently available in the Arcade LinkedIn toolkit. | Tool Name | Description | | --- | --- | | Linkedin.CreateTextPost | Share a new text post to LinkedIn. | If you need to perform an action that’s not listed here, you can [get in touch\\ with us](mailto:contact@arcade.dev) to request a new tool, or [create your\\ own tools](https://docs.arcade.dev/home/build-tools/create-a-toolkit) with the [LinkedIn auth\\ provider](https://docs.arcade.dev/home/auth-providers/linkedin#using-linkedin-auth-in-custom-tools). ## Linkedin.CreateTextPost [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/linkedin\#linkedincreatetextpost) See Example > Share a new text post to LinkedIn. **Parameters** - **`text`** _(string, required)_ The text content of the post. * * * ## Auth [Permalink for this section](https://docs.arcade.dev/toolkits/social-communication/linkedin\#auth) The Arcade LinkedIn toolkit uses the [LinkedIn auth provider](https://docs.arcade.dev/home/auth-providers/linkedin) to connect to users’ LinkedIn accounts. With the hosted Arcade Engine, there’s nothing to configure. Your users will see `Arcade` as the name of the application that’s requesting permission. With a self-hosted installation of Arcade, you need to [configure the LinkedIn auth provider](https://docs.arcade.dev/home/auth-providers/linkedin#configuring-linkedin-auth) with your own LinkedIn app credentials. ## Get Building [Use tools hosted on Arcade Cloud\\ \\ Arcade tools are hosted by our cloud platform and ready to be used in your agents. Learn how.](https://docs.arcade.dev/home/quickstart) [Self Host Arcade tools\\ \\ Arcade tools can be self-hosted on your own infrastructure. Learn more about self-hosting.\\ \\ ```\\ pip install arcade_linkedin\\ ```](https://docs.arcade.dev/home/hosting-overview) [Discord](https://docs.arcade.dev/toolkits/social-communication/discord "Discord") [Slack](https://docs.arcade.dev/toolkits/social-communication/slack "Slack") [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## Arcade Deployment Guide # 404 ## This page could not be found. ## 404 Page Not Found # 404 ## This page could not be found. ## Arcade Installation Overview # 404 ## This page could not be found. [iframe](https://0mzkp2fbz2l7.statuspage.io/embed/frame) ## 404 Error Page # 404 ## This page could not be found. ## 404 Page Not Found # 404 ## This page could not be found. ## 404 Error Page # 404 ## This page could not be found. ## Calling Tools with Models # 404 ## This page could not be found. ## 404 Error - Not Found # 404 ## This page could not be found. ## 404 Page Not Found # 404 ## This page could not be found.