Commit graph

189 commits

Author SHA1 Message Date
Renato Byrro
63bc281abc
Freshservice Starter MCP Server tools (#623) 2025-10-14 22:27:58 -03:00
jottakka
4d0ae0cdce
[MOAR][AIRTABLE] Adding AirTable starter tools (+49) (#615)
Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-10-13 15:13:39 -03:00
jottakka
fe94efaed7
[Moar][Miro] Miro tools added (#602)
Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-10-13 15:11:56 -03:00
jottakka
8b4d6b773b
[MOAR][PAGERDUTY] Adding PagerDuty Tools (#609)
Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-10-13 15:10:26 -03:00
jottakka
64fb783cdd
[MOAR][Calendly] Adding Calendly starter toolkit (#605)
Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-10-10 17:23:09 -03:00
jottakka
b89ba3372c
[MOAR][SquareUP] Adding square up toolkit (#596)
Adding square up toolkit

---------

Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-10-10 17:03:56 -03:00
Renato Byrro
103732cc2e
Xero API Starter MCP server (#603) 2025-10-10 16:35:55 -03:00
jottakka
d74af74cef
[MOAR][TRELLO] Adding trello tools (#591)
No Oauth, uses Oauth1 and needs a Token and a Api key as secrets.

---------

Co-authored-by: Francisco Liberal <francisco@arcade.dev>
Co-authored-by: Renato Byrro <rmbyrro@gmail.com>
2025-10-06 13:09:49 -03:00
Renato Byrro
565bbe0aa5
Box.com Starter MCP Server (#584)
Starter MCP Server generated from the official Box.com OpenAPI
specifications for versions
[2025.0](https://github.com/box/box-openapi/blob/main/openapi/openapi-v2025.0.json)
and
[2024.0](https://github.com/box/box-openapi/blob/main/openapi/openapi.json)
2025-10-01 23:05:16 -03:00
Renato Byrro
c518aa1319
Stripe Starter toolkit (#590)
Stripe Starter toolkit auto-generated from the official [OpenAPI
specification](https://raw.githubusercontent.com/stripe/openapi/refs/heads/master/openapi/spec3.json).
2025-10-01 21:42:38 -03:00
Eric Gustin
9e4d36b8e3
Local MCP Fixes and Address General Feedback (#586)
# Release Candidate 2
## This PR:
- [x] No more confusing 307 redirect logs when using `/mcp` instead of
`/mcp/` (requested by @shubcodes)
- [x] Fix bug in `arcade configure` for Python < 3.12 (reported by
@evantahler
- [x] Fix bug where tools with unsatisfied secret requirements could
still be executed (reported by @evantahler, @shubcodes)
- [x] Auth providers can now be imported via `from
arcade_mcp_server.auth import Reddit` (requested by @shubcodes)
- [x] Add complete E2E oauth flow for tool calls with informational
errors about how to log into arcade and where to go to authorize
(requested by @evantahler, @shubcodes)
- [x] Add OAuth tool in `arcade new`'s generated server (requested by
@shubcodes)
- [x] Standardize on defaulting to running servers on port 8000
- [x] Improve credentials.yaml reading logic
- [x] CLI user friendliness (requested by @Spartee)
- [x] Remove `arcade serve` CLI command
- [x] Fix race condition in `arcade logout`
- [x] Update docs for desired developer onboarding flow

## Next PRs:
- Get `arcade deploy` working for MCP servers. (Command is hidden for
now)
- Rename all occurrences of `toolkit` to `server`/`tools` and rename all
occurrences of `worker` to `server`
2025-09-29 16:00:47 -07:00
Eric Gustin
3424ec8219
MCP Local (#563)
Versions:
* arcade-mcp\==1.0.0rc1
* arcade-mcp-server\==1.0.0rc1
* arcade-core\==2.5.0rc1
* arcade-tdk\==2.6.0rc1
* arcade-serve\==2.2.0rc1

### Summary
Adds first-class MCP support across Arcade, introduces a new MCP server
and CLI, unifies the project under the arcade-mcp name, overhauls
templates/scaffolding, and improves developer tooling, secrets
management, and examples.

### Highlights
- **MCP Server & Core**
- New MCP server with stdio and HTTP/SSE transports, session management,
resumability, and lifecycle handling.
- FastAPI-like `MCPApp` for building servers with lazy init; integrated
worker+MCP HTTP app option.
- Middleware system (logging and error handling), robust exception
hierarchy, and Pydantic-based settings.
- Async-safe managers for tools, resources, and prompts backed by
registries and locks.
- Developer-facing, transport-agnostic runtime context interfaces (logs,
tools, prompts, resources, sampling, UI, notifications).
- Conversion from Arcade ToolDefinition to MCP tool schema; OpenAI JSON
tool schema converter.
  - Parser supports `@app.tool`/`@app.tool(...)` decorators.

- **CLI**
  - New `mcp` command to run MCP servers with stdio or HTTP/SSE.
- New `secret` command to set/list/unset tool secrets (supports .env
input, preserves original casing for lookups).
- `new` command refactored; option to create a full toolkit package with
scaffolding.
  - `chat` command removed.
- `serve.py` imports updated to `arcade_serve.fastapi.telemetry`;
version retrieval now uses `arcade-mcp`.
  - `show.py` refactor to use new local catalog utilities.
- `display_tool_details` improved: adds “Default” column and handles
nested properties.

- **Configuration & Discovery**
- New `configure.py` to set up Claude Desktop, Cursor, and VS Code to
connect to local or Arcade Cloud MCP servers.
- Discovery utilities to find/install toolkits, build `ToolCatalog`s,
analyze files for tools, load kits from directories (pyproject parsing),
and build minimal toolkits.
- Better handling of provider API key resolution and evaluation suite
loading.

- **Templates & Scaffolding**
- Reorganized template structure (minimal vs full); moved
`.pre-commit-config.yaml`, `.ruff.toml`, license, Makefile, README,
tests, and tools layout to correct paths.
  - Minimal template adds `.env.example` for runtime secret injection.
- Template pyproject updated for MCP servers; includes sample server
with greeting and secret-reveal tools.
  - Authorization flow in templates simplified.

- **Repo-wide Renaming & Examples**
- Migrates references from `arcade-ai` to `arcade-mcp` across READMEs,
scripts, and package metadata.
- Examples updated (LangChain/LangGraph/AI SDK/TypeScript) and package
name changed to `arcade-mcp-sdk`.

- **Evals & Core Utilities**
- Evals now use OpenAI tooling format (`OpenAIToolList`, `to_openai`);
`tool_eval` takes `provider_api_key`.
- Core utilities: fixed `does_function_return_value` by dedenting before
parse; version bump to `2.5.0rc1` and dependency cleanup.

- **Tooling & CI**
- `setup-uv-env` action splits toolkit vs contrib dependency
installation.
- Pre-commit: excludes `libs/arcade-mcp-server/mkdocs.yml` and
`libs/tests/` from YAML and Ruff hooks; Ruff per-file ignores (e.g.,
C901 in `libs/**/*.py`, TRY400 in server docs paths).
- Makefile updates for uv env setup, quality checks, tests, builds, and
new `shell` target.
  - Added Makefile to MCP server library to streamline dev workflow.

- **Cleanup**
  - Removed `claude.json` config.
- Simplified stdio entrypoint; removed unused imports (`arcade_gmail`,
`arcade_search`).

### Breaking Changes
- **CLI**: `chat` command removed; use `mcp`, `secret`, and updated
`new`.
- **Naming**: All users should update references from `arcade-ai` to
`arcade-mcp`.
- **Templates**: File paths moved; downstream scripts referencing old
template locations may need updates.

### Getting Started
- Run an MCP server:
  - `arcade mcp --stdio --toolkits your_toolkit`
  - `arcade mcp --http --toolkits your_toolkit`
- Manage secrets:
  - `arcade secret set your_toolkit KEY=value`
  - `arcade secret list your_toolkit`
  - `arcade secret unset your_toolkit KEY`
- Configure clients:
- `arcade configure` to set up Claude Desktop, Cursor, and VS Code for
local/Arcade Cloud MCP.

---------

Co-authored-by: Sam Partee <sam@arcade-ai.com>
Co-authored-by: Shub <125150494+shubcodes@users.noreply.github.com>
2025-09-25 15:28:15 -07:00
jottakka
b446390acf
[READY][PROD-215][toolkits/ZENDESK]updating error handling (#578)
# [PROD-215](https://app.clickup.com/t/9014390315/PROD-215) 🎫 

## Changes
- Removed some try catch blocks from Zendesk tools so the default Httpx
error adaptor can deal with them.

Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-09-24 15:09:37 -03:00
Renato Byrro
25718bbf77
Slack wrapper toolkit in Python with JSON definitions (#574)
finally!
2025-09-23 13:48:21 -03:00
Evan Tahler
766a262a25
MongoDB analytics toolkit (#548)
Design System: https://github.com/ArcadeAI/Design-System/pull/31
Docs: https://github.com/ArcadeAI/docs/pull/439

<img width="832" height="797" alt="Screenshot 2025-09-11 at 2 35 36 PM"
src="https://github.com/user-attachments/assets/198f194f-d41c-41a0-bedf-b77bccd70dfa"
/>
2025-09-12 18:41:23 -07:00
jottakka
9c1b2b9275
[Ready][toolkit/zendesk] Adding WhoAmI tool to zendesk (#544)
Zendesk who_am_i tool.

---------

Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-09-10 18:22:09 -03:00
Evan Tahler
a85fa76997
Clickhouse Toolkit (#527)
Generated from the postgres toolkit
2025-08-05 14:05:09 -07:00
Eric Gustin
ca11ec9fa3
Add toolkits (#514)
Add Linkedin, Zendesk, Math, and Postgres toolkits
2025-07-25 15:44:06 -07:00
Eric Gustin
b50726d044
Remove Toolkits (#512)
As of today, Arcade's toolkits are moving to closed-source.  

Toolkit source code remains available upon request for our paying
customers. The history of this repository contains the toolkits as of
their most recent publication under their previous license terms.
2025-07-24 16:45:24 -07:00
Sam Partee
27a6cd31a3
Support Tool Output in ValueSchema of ToolDefinition (#487)
## Before

### Tool: ``GoogleNews.SearchNewsStories``

```python
@tool(requires_secrets=["SERP_API_KEY"])
async def search_news_stories(
    context: ToolContext,
    keywords: Annotated[
        str,
        "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
    ],
    country_code: Annotated[
        CountryCode | None,
        "2-character country code to search for news articles. "
        "E.g. 'us' (United States). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_COUNTRY}'.",
    ] = None,
    language_code: Annotated[
        LanguageCode,
        "2-character language code to search for news articles. E.g. 'en' (English). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_LANGUAGE}'.",
    ] = DEFAULT_GOOGLE_NEWS_LANGUAGE,
    limit: Annotated[
        int | None,
        "Maximum number of news articles to return. Defaults to None "
        "(returns all results found by the API).",
    ] = None,
) -> Annotated[dict[str, Any]]:
    """Search for news articles related to a given query."""
    ...
```


### Tool Definition: ``GoogleNews.SearchNewsStories``
```
  {
    "name": "SearchNewsStories",
    "fully_qualified_name": "GoogleNews.SearchNewsStories",
    "description": "Search for news articles related to a given query.",
    "toolkit": {
      "name": "GoogleNews",
      "description": "Arcade.dev LLM tools for getting new via Google News",
      "version": "2.0.0"
    },
    "input": {
      "parameters": [
        {
          "name": "keywords",
          "required": true,
          "description": "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
          },
          "inferrable": true
        },
        {
          "name": "country_code",
          "required": false,
          "description": "2-character country code to search for news articles. E.g. 'us' (United States). Defaults to 'None'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
          },
          "inferrable": true
        },
        {
          "name": "language_code",
          "required": false,
          "description": "2-character language code to search for news articles. E.g. 'en' (English). Defaults to 'en'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
          },
          "inferrable": true
        },
        {
          "name": "limit",
          "required": false,
          "description": "Maximum number of news articles to return. Defaults to None (returns all results found by the API).",
          "value_schema": {
            "val_type": "integer",
            "inner_val_type": null,
            "enum": null,

          },
          "inferrable": true
        }
      ]
    },
    "output": {
      "description": "News search results with article details.",
      "available_modes": [
        "value",
        "error"
      ],
      "value_schema": {
        "val_type": "json"
      }
    },
    "requirements": {
      "authorization": null,
      "secrets": [
        {
          "key": "serp_api_key"
        }
      ],
      "metadata": null
    },
    "deprecation_message": null
  },
```

## After

### Enhanced Tool: ``GoogleNews.SearchNewsStories``

```python

"""Type definitions for Google News API responses and parameters."""

from typing_extensions import TypedDict

CountryCode = str
LanguageCode = str


class SearchNewsParams(TypedDict):
    """Input parameters for searching news articles."""

    keywords: str
    """Search query terms to find relevant news articles \
    (e.g., 'Apple launches new iPhone')."""

    country_code: CountryCode | None
    """Optional 2-letter country code to filter news by region \
    (e.g., 'us' for United States, 'uk' for United Kingdom)."""

    language_code: LanguageCode | None
    """Optional 2-letter language code to filter news by language \
    (e.g., 'en' for English, 'es' for Spanish)."""

    limit: int | None
    """Optional maximum number of news articles to return. \
    If not specified, returns all results from the API."""


class SourceInfo(TypedDict, total=False):
    """Information about the news source/publication."""

    name: str
    """Name of the publication (e.g., 'CNN', 'BBC News', 'The New York Times')."""

    icon: str
    """URL to the source's favicon or logo image."""

    authors: list[str]
    """List of author names for the article, if available."""


class NewsResult(TypedDict, total=False):
    """Individual news article from the Google News API response."""

    position: int
    """Ranking position of this result in the search results."""

    title: str
    """Headline or title of the news article."""

    link: str
    """Full URL to the original news article."""

    source: SourceInfo
    """Information about the publication source."""

    date: str
    """Publication date and time (e.g., '2 hours ago', 'Dec 15, 2023')."""

    snippet: str
    """Brief excerpt or summary from the article content."""

    thumbnail: str
    """URL to a high-resolution thumbnail image for the article."""

    thumbnail_small: str
    """URL to a low-resolution thumbnail image for the article."""

    story_token: str
    """Token for accessing full coverage of this news story across multiple sources."""

    stories: list["NewsResult"]
    """Related news stories from other sources covering the same topic."""

    highlight: dict
    """Additional highlighted information about the story."""


class SearchMetadata(TypedDict, total=False):
    """Metadata about the search request and processing."""

    id: str
    """Unique identifier for this search request within SerpApi."""

    status: str
    """Current processing status ('Processing', 'Success', or 'Error')."""

    json_endpoint: str
    """URL to retrieve the JSON results for this search."""

    created_at: str
    """Timestamp when the search request was created."""

    processed_at: str
    """Timestamp when the search request was processed."""

    google_news_url: str
    """Original Google News URL that would return these results."""

    total_time_taken: float
    """Total time in seconds taken to process this search."""


class SearchParameters(TypedDict, total=False):
    """Parameters used for the search request."""

    engine: str
    """Search engine used (always 'google_news' for this API)."""

    q: str
    """Search query string."""

    gl: str
    """Country code used for geographic filtering."""

    hl: str
    """Language code used for language filtering."""

    topic_token: str
    """Token for accessing specific news topics (e.g., 'World', 'Business', 'Technology')."""

    publication_token: str
    """Token for accessing news from specific publishers."""


class MenuLink(TypedDict):
    """Navigation link for news categories or topics."""

    title: str
    """Display text for the menu item (e.g., 'Technology', 'Sports', 'Business')."""

    topic_token: str
    """Token to access this specific topic or category."""

    serpapi_link: str
    """SerpApi URL to search within this topic."""


class TopStoriesLink(TypedDict):
    """Link to top stories section."""

    topic_token: str
    """Token to access top stories."""

    serpapi_link: str
    """SerpApi URL to retrieve top stories."""


class GoogleNewsResponse(TypedDict, total=False):
    """Complete response from the Google News API."""

    search_metadata: SearchMetadata
    """Metadata about the search request and processing."""

    search_parameters: SearchParameters
    """Parameters that were used for this search."""

    news_results: list[NewsResult]
    """List of news articles matching the search criteria."""

    menu_links: list[MenuLink]
    """Navigation links to different news categories and topics."""

    top_stories_link: TopStoriesLink
    """Link to access top stories."""

    title: str
    """Title of the page or topic being displayed."""


class SimplifiedNewsResult(TypedDict):
    """Simplified news article format for tool output."""

    title: str
    """Headline of the news article."""

    link: str
    """URL to the full article."""

    source: str | None
    """Name of the publication source."""

    date: str | None
    """When the article was published."""

    snippet: str | None
    """Brief excerpt from the article."""


class SearchNewsOutput(TypedDict):
    """Output format for the search_news_stories tool."""

    news_results: list[SimplifiedNewsResult]
    """List of news articles in simplified format."""

@tool(requires_secrets=["SERP_API_KEY"])
async def search_news_stories(
    context: ToolContext,
    keywords: Annotated[
        str,
        "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
    ],
    country_code: Annotated[
        CountryCode | None,
        "2-character country code to search for news articles. "
        "E.g. 'us' (United States). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_COUNTRY}'.",
    ] = None,
    language_code: Annotated[
        LanguageCode,
        "2-character language code to search for news articles. E.g. 'en' (English). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_LANGUAGE}'.",
    ] = DEFAULT_GOOGLE_NEWS_LANGUAGE,
    limit: Annotated[
        int | None,
        "Maximum number of news articles to return. Defaults to None "
        "(returns all results found by the API).",
    ] = None,
) -> Annotated[SearchNewsOutput, "News search results with article details."]:
    """Search for news articles related to a given query."""
    ...

```

### Enhanced Tool Definition: ``GoogleNews.SearchNewsStories`` 

```json

  {
    "name": "SearchNewsStories",
    "fully_qualified_name": "GoogleNews.SearchNewsStories",
    "description": "Search for news articles related to a given query.",
    "toolkit": {
      "name": "GoogleNews",
      "description": "Arcade.dev LLM tools for getting new via Google News",
      "version": "2.0.0"
    },
    "input": {
      "parameters": [
        {
          "name": "keywords",
          "required": true,
          "description": "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        },
        {
          "name": "country_code",
          "required": false,
          "description": "2-character country code to search for news articles. E.g. 'us' (United States). Defaults to 'None'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        },
        {
          "name": "language_code",
          "required": false,
          "description": "2-character language code to search for news articles. E.g. 'en' (English). Defaults to 'en'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        },
        {
          "name": "limit",
          "required": false,
          "description": "Maximum number of news articles to return. Defaults to None (returns all results found by the API).",
          "value_schema": {
            "val_type": "integer",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        }
      ]
    },
    "output": {
      "description": "News search results with article details.",
      "available_modes": [
        "value",
        "error"
      ],
      "value_schema": {
        "val_type": "json",
        "inner_val_type": null,
        "enum": null,
        "properties": {
          "news_results": {
            "val_type": "array",
            "inner_val_type": "json",
            "enum": null,
            "properties": null,
            "inner_properties": {
              "title": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "Headline of the news article."
              },
              "link": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "URL to the full article."
              },
              "source": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "Name of the publication source."
              },
              "date": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "When the article was published."
              },
              "snippet": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "Brief excerpt from the article."
              }
            },
            "description": "List of news articles in simplified format."
          }
        },
        "inner_properties": null,
        "description": null
      }
    },
    "requirements": {
      "authorization": null,
      "secrets": [
        {
          "key": "serp_api_key"
        }
      ],
      "metadata": null
    },
    "deprecation_message": null
  },

```

---------

Co-authored-by: Eric Gustin <eric@arcade.dev>
2025-07-24 15:32:35 -07:00
Evan Tahler
4144a42392
Make the postgres toolikit better (#509)
Per the discussions in the [blog
post](https://docs.google.com/document/d/1wZi1yKWKOyg1dpueA2eBvTtYlUjqqp7e_M1nuAoF8NY/edit?tab=t.0),
let's update the postgres toolkit!

<img width="2141" height="1364" alt="Screenshot 2025-07-22 at 5 28
06 PM"
src="https://github.com/user-attachments/assets/1b6a5e0a-9429-4c16-9a0c-ac36ea520bea"
/>
2025-07-23 15:28:57 -07:00
Renato Byrro
30739dc44a
Support for multiple Atlassian Clouds in the Jira Toolkit (#506)
Adds `Jira.GetAvailableAtlassianClouds` tool, which provides a list of
clouds available (checking which Clouds were actually authorized by the
current auth token).

Refactors the interface of every tool to accept an `atlassian_cloud_id`
argument (when not provided, try to get a unique cloud ID - if multiple
are available, raises a Retryable error with the list of Clouds
available instructing to select one).

Gets rid of all caching. Now storing the global semaphore to the context
object. The global semaphore is important because some tools depend on
others, and each tool instantiates its own Jira HTTP client. Storing the
semaphore in the context object ensures that all HTTP clients will
respect the concurrency limit.

Removes from tool responses the Atlassian URLs linking to objects in the
Jira GUI (users, projects, issues, etc. We do not keep track of the
cloud name anymore, which is required to build the objects' URLs.

Extends/refactors unit tests accordingly.

Evals checking LLM behavior when:

- a cloud ID is explicitly mentioned in the prompt;
- no cloud ID is mentioned;
- a "multiple clouds available" error is raised and the user is prompted
to pick one;
- user request triggers another tool call after having previously picked
a cloud ID (in the same chat context);
2025-07-23 18:09:54 -03:00
Eric Gustin
4598e1e4d4
Updates to Notion toolkit (#476)
### Adds one new tool to the Notion toolkit
* **AppendContentToEndOfPage**: Append markdown content to the end of a
Notion page by its ID or title

### Fixes a bug
* The **CreatePage** would previously fail if the content provided was
broken into more than 100 blocks. I added 'chunking' logic to support >
100 blocks.
2025-07-18 17:35:12 -07:00
Mateo Torres
173cc6994e
bugfix: URL expansion in Twitter (#500)
This solves an edge case where the `"url"` entity does not have an
`"expanded_url"` case when expanding. The behavior for now is simply
don't replace the URL as it seems the display_url is NOT what we want to
keep as it's normally abbreviated

---------

Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-07-18 18:20:06 -03:00
Shub
0b1f513826
Add Simplified Linear Toolkit (#465)
This PR adds a simplified Linear toolkit focused on core functionality:

## What's Included

**Tools:**
- `get_issue` - Get detailed information about Linear issues
- `get_teams` - Get team information and details

**Models:**
- `DateRange` enum with comprehensive date range support (TODAY,
YESTERDAY, THIS_WEEK, LAST_WEEK, THIS_MONTH, LAST_MONTH, THIS_YEAR,
LAST_YEAR, LAST_7_DAYS, LAST_30_DAYS)
- Timezone-aware datetime handling following Google toolkit patterns

## What's Simplified

This toolkit has been streamlined by removing:
- Cycles management tools
- Projects management tools  
- Users management tools
- Workflows management tools
- Corresponding tests and evaluations for removed features

## Quality Assurance

- All linting and formatting checks pass
- Comprehensive test coverage for included functionality
- Follows established patterns from Google toolkit

---------

Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-07-18 14:08:58 -07:00
Lucas Petralli
1843e411f3
Add Zendesk Toolkit (#458)
This PR adds a new toolkit for integrating with Zendesk Help Center and
ticketing system.

  Features

- Search Articles: Search Help Center knowledge base with filters for
text, categories, labels, and dates
  - List Tickets: Retrieve all open support tickets
- Get Comments: Retrieve all comments for a specific ticket to
understand the context
  - Add Comments: Add public or internal comments to existing tickets
- Solve Tickets: Mark tickets as solved with optional internal
resolution comments

  Testing & Quality
  - Comprehensive test suite 
  - Evaluation scripts for real-world testing
  - All tests passing (make test)
  - Code quality checks passing (make check)
  - All evals passing

---------

Co-authored-by: “lgesuellip” <“lgesuellipinto@uade.edu.ar”>
Co-authored-by: lgesuellip <102637283+lgesuellip@users.noreply.github.com>
Co-authored-by: “lgesuellip” <lgesuellipinto@uade.edu.ar>
2025-07-17 13:34:26 -07:00
Renato Byrro
3f6c7a5595
Fix bug in Slack user processing (#488) 2025-07-15 14:52:52 -03:00
Evan Tahler
40cdf2018d
Postgres Database Toolkit (#459)
Adds an example of a good "general case" SQL tool:
* enforces read-only mode
* hints to the LLM to discover the tables and schemas for the tables it
needs before any query
* uses RetryableToolErrors to hint to the LLM about what to do next

Docs: https://github.com/ArcadeAI/docs/pull/345

For testing, `TEST_POSTGRES_DATABASE_CONNECTION_STRING` has been set in
the repo (from Neon). details in 1 password.

<img width="1178" height="1091"
alt="464977013-49aff5e5-e301-4ca0-83b5-3ea742db2283"
src="https://github.com/user-attachments/assets/9344c27b-015d-4b91-907e-84f2e4193e16"
/>
2025-07-11 17:30:40 -07:00
Renato Byrro
1b0547090c
Temporarily remove Slack mpim:write scope (#482) 2025-07-11 18:57:24 -03:00
Eric Gustin
64c7771e36
Officially publish new split toolkits to PyPI (#480)
No more release candidate versions!
2025-07-11 12:34:21 -07:00
Eric Gustin
836c890840
Release candidates for new toolkits (#479)
New toolkit versions are release candidates now.

Also fixed a test for e2b toolkit.

Also, I am explicitly not running test for toolkits for the post merge
workflow because they are run on every PR commit (i.e., they must pass
before we even merge)
2025-07-10 10:34:19 -07:00
Renato Byrro
ed89af4b4d
Slack Toolkit Refactoring (#453)
# Backwards-compatible refactoring of the Slack toolkit

Several performance improvements, streamlined tool set, and easier to
understand tool interfaces.

All "old" tools were kept for backwards compatibility, with the same
interfaces and response structure (but using the new and more performant
tools under the hood).

Full revision of unit-tests and evals.

##  Streamlined tool set

Multiple groups of tools were streamlined into a single one:

* "get conversation metadata" from 5 tools to one;
* "send message" from 2 tools to one;
* "get users in conversation" from 3 tools to one;
* "get messages" from 4 tools to one

## New capabilities

* Messages retrieved are now populated with the users' names, apart from
ID: makes it easier for LLMs to reference who sent a message, were
mentioned, or reacted to a message
* Retrieve users by username, email, and/or ID (before we only supported
ID)
* Retrieve multiple users in a single tool call

## Concurrency controls

All operations issuing multiple requests concurrently now have a
`Semaphore` to limit the concurrency level. The limit can be controlled
through the `SLACK_MAX_CONCURRENT_REQUESTS` env var (defaults to 3).

## Networking performance improvement

Various operations that used to make multiple API calls are now executed
more efficiently:

### Find users by username

* Before: a full scan of `users_list` was required (potentially multiple
pages for large workspaces);
* Now it stops as soon as we have all users needed (yes, it was dumb
before)

### Get multiple users by their IDs

* Before: for each user ID, we made one API call to the `users_info`
endpoint
* Now: we call `list_users` and scan the results to match the user IDs
(an estimate of 99.5% of Slack workspaces have < 200 users; for large
workspaces, we may need to paginate `list_users`)

### Get a conversation by its users

* Before:
  * Call to `list_conversations` (potentially paginating)
* For each conversation, one call to `conversations_members`
(potentially paginating)
  * Then loop and find which conversation matches the users' IDs
* Now:
  * A single call to `conversations_open`
2025-07-10 13:50:28 -03:00
Eric Gustin
07c52100f3
Split and rename multiple toolkits (#438)
# PR Description
## Split toolkits

This PR splits the `Microsoft`, `Google`, and `Search` toolkits into
multiple toolkits each.
 * `Microsoft` --> `OutlookCalendar`, `OutlookMail`.
* `Google` -----> `GoogleCalendar`, `GoogleContacts`, `GoogleDocs`,
`GoogleDrive`, `Gmail`, `GoogleSheets`
* `Search` -----> `GoogleFinance`, `GoogleFlights`, `GoogleHotels`,
`GoogleJobs`, `GoogleMaps`, `GoogleNews`, `GoogleSearch`,
`GoogleShopping`, `Walmart`, `Youtube`

> The original monolithic toolkits (`Microsoft`, `Google`, `Search`) are
not removed in this PR. The plan is to keep those toolkits around while
we
> 1. Stop documenting the toolkits, 
> 2. Stop displaying the toolkits in the dashboard, and 
> 3. Help customers migrate over to the new split toolkits.

## Rename toolkits
This PR renames the following toolkits 
* `Web` ------------> `Firecrawl`
* `CodeSandbox` ---> `E2B`

> The `Web` and `CodeSandbox` toolkits are not removed in this PR. The
plan is to keep them around while we
> 1. Stop documenting the toolkits, 
> 2. Stop displaying the toolkits in the dashboard, and 
> 3. Help customers migrate over to the new renamed toolkits.

## Rename tools
Since toolkit names were changed, this called for some tools to be
renamed as well.
* `GoogleSearch.SearchGoogle` ----------------> `GoogleSearch.Search`
* `GoogleShopping.SearchShoppingProducts` --->
`GoogleShopping.SearchProducts`
* `Walmart.SearchWalmartProducts` ------------> `Walmart.SearchProducts`
* `Walmart.GetWalmartProductDetails` --------->
`Walmart.GetProductDetails`
* `Youtube.SearchYoutubeVideos` -------------->
`Youtube.SearchForVideos`

## Google File Picker
Improvements to the Google File Picker experience were also added in
this PR.

The following tools will ALWAYS provide llm_instructions in their
response to "let the end-user know that they have the option to select
more files via the file picker url if they want to":
* `GoogleDocs.SearchDocuments`
* `GoogleDocs.SearchAndRetrieveDocuments`
* `GoogleDrive.GetFileTreeStructure`

The following tools will only provide the file picker URL if a 404 or
403 from the Google API:
* `GoogleDocs.InsertTextAtEndOfDocument`
* `GoogleDocs.GetDocumentById`
* `GoogleSheets.GetSpreadsheet`
* `GoogleSheets.WriteToCell`

Also, a standalone `GoogleDrive.GenerateGoogleFilePickerUrl` tool
exists.

## Other
* The `SearchDocuments` and `SearchAndRetrieveDocuments` tools used to
be organized within the Drive portion of the Google toolkit, but I moved
these into the new GoogleDocs toolkit because they are specific to Docs.

# Progress

- [x] `OutlookCalendar`
- [x] `OutlookMail`
- [x] `GoogleFinance`
- [x] `GoogleFlights`
- [x] `GoogleHotels`
- [x] `GoogleJobs`
- [x] `GoogleMaps`
- [x] `GoogleNews`
- [x] `GoogleSearch`
- [x] `GoogleShopping`
- [x] `Walmart`
- [x] `Youtube`
- [x] `GoogleCalendar`
- [x] `GoogleContacts`
- [x] `GoogleDocs`
- [x] `GoogleDrive`
- [x] `Gmail`
- [x] `GoogleSheets`
- [x] `Firecrawl`
- [x] `E2B`
- [x] File picker

# Discussion
* Repeated code is a consequence of splitting toolkits that use the same
provider. I am open to any ideas that would allow multiple toolkits to
reference common code. Comment your ideas in this PR.
2025-07-09 16:00:09 -07:00
Eric Gustin
490cb8ae38
Fix existing Slack test & bump TK versions (#471) 2025-07-01 14:13:45 -07:00
Eric Gustin
bfd183f06b
Bump versions (#470) 2025-07-01 13:43:33 -07:00
Eric Gustin
a336f43a83
Fix release workflow for toolkits (#469)
The workflow didn't work correctly for toolkits. see run logs for more
info on how it didn't work correctly:
https://github.com/ArcadeAI/arcade-ai/actions/runs/16008156518/job/45159613768

Bumped the code-sandbox toolkit to prove it works. Proof it worked:
https://github.com/ArcadeAI/arcade-ai/actions/runs/16009427831/job/45163629931?pr=469
2025-07-01 13:29:59 -07:00
Eric Gustin
1d9a4f2275
Bump toolkit versions (#468)
The PyPI packages haven't been bumped since migrating them to use the
TDK. This PR excludes bumping Jira since it was bumped last week.
2025-07-01 12:14:41 -07:00
Eric Gustin
a1dcd7667e
Update toolkit Makefiles (#466) 2025-07-01 11:29:12 -07:00
Mateo Torres
ab34d3ad8e
patching toolkit template generator for outside the main repo (#460)
The current `arcade new` command fails to `make install` and `make
check` if it's not manually patched with pre-commit files. It also fails
due to local dependencies if it's not run inside `arcade-ai/toolkits`

This PR patches the toolkit template to only include the local
dependencies if it detects is `arcade new` being run inside
`arcade-ai/toolkits`, it also makes pre-commit commands optional.
2025-06-30 19:19:15 -03:00
Renato Byrro
352079151e
Jira toolkit: deduplicate cloud data in Atlassian's available-resources response (#456) 2025-06-24 12:39:16 -03:00
Sam Partee
b6b4cd0a4c
🏗️ Restructure: Multi-Package Architecture + uv Migration (#412)
### Overview
Major restructuring from monolithic `arcade-ai` package to modular
library architecture with standardized uv-based dependency management.

![arcade-ai Monorepo
(2)](https://github.com/user-attachments/assets/25f102b0-bb87-4a04-9701-d227d05664b1)

### New Package Structure
- **`arcade-tdk`** - Lightweight toolkit development kit (core
decorators, auth)
- **`arcade-core`** - Core execution engine and catalog functionality  
- **`arcade-serve`** - FastAPI/MCP server components
- **`arcade-ai`** - Meta package that includes CLI functionality.
Optionally include evals via the `evals` extra. Optionally include all
packages via the `all` extra.

### Key Benefits
- **Lighter Dependencies**: Toolkits now depend only on `arcade-tdk` (~2
deps) vs full `arcade-ai` (~30+ deps)
- **Faster Builds**: uv provides 10-100x faster dependency resolution
and installation
- **Better Modularity**: Clear separation of concerns, consumers import
only what they need
- **Standard Tooling**: Eliminates custom poetry scripts, uses standard
Python packaging

### Migration Impact
- All 20 toolkits converted from poetry → uv with `arcade-tdk`
dependencies plus `arcade-ai[evals]` and `arcade-serve` dev
dependencies. When developing locally, devs should install toolkits via
`make install-local`.
- Modern Python 3.10+ type hints throughout
- Standardized build system with hatchling backend
- Enhanced Makefile with robust toolkit management commands
- Removed `arcade dev` CLI command
- Reduce the number of files created by `arcade new` and add an option
to not generate a tests and evals folder.

This foundation enables faster development cycles and cleaner dependency
chains for the growing toolkit ecosystem.

### Todo After this PR is merged
- [ ] Post-merge workflow(s) (release & publish containers, etc)
- [ ] Release order plan. @EricGustin suggests releasing in the
following order:
    1. `arcade-core` version 0.1.0
    2. `arcade-serve` version 0.1.0 and `arcade-tdk` version 0.1.0
    3. `arcade-ai` version 2.0.0
4. Patch release for all toolkits (all changes in toolkits are internal
refactors)
- [ ] [Update docs](https://github.com/ArcadeAI/docs/pull/318)

---------

Co-authored-by: Eric Gustin <eric@arcade.dev>
Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-06-11 16:48:17 -07:00
Renato Byrro
01a9efcf63
Fix quote issue when deploying worker (2) (#427) 2025-06-11 13:49:48 -03:00
Renato Byrro
5c221dd042
Fix quote issue when deploying worker (#426) 2025-06-11 12:53:45 -03:00
Renato Byrro
a538f4bf81
Jira Toolkit (#407)
Unusually big PR, in large part due to Jira's data model complexities.
2025-06-11 12:06:33 -03:00
Eric Gustin
bc8814e24f
Add missing dev dependency to two toolkits (#419)
pytest asyncio was missing in dev deps for the reddit toolkit and notion
toolkit. This was causing PR workflows to fail.
2025-06-09 11:06:07 -07:00
Eric Gustin
6bc6f0c574
Add Confluence toolkit (#406)
12 tools for the new Confluence toolkit.

| 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.|

### Confluence Clients
Confluence has deprecated most of their V1 endpoints, so most of the
tools use V2. However, we still need a V1 client to support search. The
V1 search API has not been deprecated yet, because there is no V2
equivalent. But we need to be aware in the future for when this
deprecation happens.


### Future work
* Content of pages are returned in the Confluence `storage` format. This
is the format that Confluence uses to store pages internally. We should
understand the storage format more deeply, and write utility function to
transform this format into plain text.
* Better protections against extremely large pages. I've tested up to
6,000 word pages.
* Tools for blog posts
* Tool for getting the children of a page. (`get_space_hierarchy` will
suffice for now)
* Allow for numerical titles
2025-05-22 13:18:19 -07:00
Eric Gustin
e764205e6c
Add Microsoft.ListEmailsByProperty tool (#386) 2025-05-16 13:08:29 -08:00
Renato Byrro
b9afa1b5cf
Asana Toolkit (#381) 2025-05-12 14:59:52 -03:00
Eric Gustin
419a0ac717
Add Outlook Calendar tools (#382) 2025-05-09 13:34:40 -08:00
Eric Gustin
ef886bb503
Microsoft Outlook Mail Tools (#377)
| Name | Description |

|------------------------------|--------------------------------------------------------------------------------|
| Microsoft.CreateDraftEmail | Compose a new draft email in Outlook |
| Microsoft.UpdateDraftEmail | Update an existing draft email in Outlook
|
| Microsoft.CreateAndSendEmail | Create and immediately send a new email
in Outlook to the specified recipients |
| Microsoft.SendDraftEmail | Send an existing draft email in Outlook |
| 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 |
2025-04-24 14:27:52 -07:00