Hello 👋 from Porter! Please merge this PR to finish setting up your
application.
---------
Co-authored-by: porter-deployment-app[bot] <87230664+porter-deployment-app[bot]@users.noreply.github.com>
Co-authored-by: sdreyer <sterling@arcade-ai.com>
Hello 👋 from Porter! Please merge this PR to finish setting up your
application.
Co-authored-by: porter-deployment-app[bot] <87230664+porter-deployment-app[bot]@users.noreply.github.com>
This repo has a readme that is basically a shadow version of our docs
that we aren't keeping up-to-date. So, let's remove all that and
encourage folks to head to our docs.
---------
Co-authored-by: Nate Barbettini <nate@arcade.dev>
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
Add hot-reload capability
adds watchfiles dependency and changes uvicorn server logic
but does not have any breaking changes.
---------
Co-authored-by: Eric Gustin <eric@arcade.dev>
Co-authored-by: sdreyer <sterling@arcade-ai.com>
Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
Update our example with the latest version of `arcade-js`. This means we
can delete all the utility functions we created here, since we now have
first-class `Zod` support and they are no longer needed.
> [!WARNING]
> Don't merge until this
[PR](https://github.com/ArcadeAI/arcade-js/pull/127) is merged.
added additional pr guideline for toolkits -- separate pr for each
toolkit change
---------
Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
This PR fixes two bugs:
1. `serve_default_worker` was not registering toolkits to the worker
(non mcp). This caused workers created during `arcade workerup` and
`arcade serve` to have 0 tools.
2. We were logging the number of files in the toolkit as the number of
tools in the toolkit.
MCP stdio Implementation:
The PR adds support for standard input/output (stdio) as a transport
mechanism for the Message Control Protocol. This is a replacement to the
SSE (Server-Sent Events) transport that was worked on in PR #359 but
will not be merged as it's not deprecated.
This will allow developers to use Arcade tools (written by the dev or
Arcade) in Claude, Cursor, windsurf, etc.
The engine Gateway already supports adding HTTPS streamable (replacement
for SSE) MCP servers as tool servers, and will soon support full gateway
capability in the client API as well.
To use any existing Toolkit just
## Examples
### Quickstart setup with existing toolkits
```bash
pip install arcade-ai
pip install <name of toolkit> # ex. arcade-google
arcade serve --mcp
```
### Run with Claude
Just add the following to the Claude config
```json
{
"mcpServers": {
"arcade": {
"command": "bash",
"args": ["-c", "export ARCADE_API_KEY=arc_xxxx && /path/to/python /path/to/arcade serve --mcp"]
}
}
}
```
### Customizing the Tool Server
Developers can customize their served tools and server furthermore by
importing the worker sdk
```python
import arcade_google # pip install arcade_google
import arcade_search # pip install arcade_search
from arcade.core.catalog import ToolCatalog
from arcade.worker.mcp.stdio import StdioServer
# 2. Create and populate the tool catalog
catalog = ToolCatalog()
catalog.add_module(arcade_google) # Registers all tools in the package
catalog.add_module(arcade_search)
# 3. Main entrypoint
async def main():
# Create the worker with the tool catalog
worker = StdioServer(catalog)
# Run the worker
await worker.run()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
```
Then to run with claude, just run this python file instead of the prebuilt server used in ``arcade serve --mcp``
The Asana toolkit is not published yet, so it cannot be added to the
worker's toolkit list. This is causing container build/publish on main
branch to fail.
* `arcade dashboard` opens the Arcade Dashboard in a web browser.
Defaults to `https://api.arcade.dev/dashboard`, but is configurable via
flags.
* `arcade dashboard --local` opens your locally hosted Arcade Dashboard
in a web browser.
* Performs a health check of the engine and will print a warning to the
console if the Engine is not healthy / not running.
----------------------------------------
* Inspiration from https://minikube.sigs.k8s.io/docs/handbook/dashboard/
| 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 |
1. Paginate through all current level blocks before recursing into
children (before this PR we would go back and forth between paginate and
recurse)
2. For top-level blocks only, split blocks into 5 lists, and
concurrently get their content
---------
From my local timing benchmarks, this speeds up the tool call by ~60%
(23 seconds to 9.1 seconds) for larger Notion pages
Without optimization: Avg 22995
Attempt 1: 27503.49497795105
Attempt 2: 20863.977909088135
Attempt 3: 20888.309955596924
Attempt 4: 18574.61714744568
Attempt 5: 27147.75586128235
With optimization: Avg 9148.6
Attempt 1: 9941.372871398926
Attempt 2: 10097.685098648071
Attempt 3: 7855.895042419434
Attempt 4: 9078.719854354858
Attempt 5: 8772.69196510315
Reviewer:
1. DM me to get a client ID/secret for the Hubspot app and login
credentials for a sample Hubspot account
2. For now, you'll need to run the engine on the branch
`nate/token-introspection` for the auth flow to work with Hubspot
3. Add the following to `auth.providers` in your engine yaml:
```yaml
- id: arcade-hubspot
description: 'Hubspot provider'
enabled: true
type: oauth2
provider_id: hubspot
client_id: ${env:HUBSPOT_CLIENT_ID}
client_secret: ${env:HUBSPOT_CLIENT_SECRET}
```
Updating the auth provider's `id` to simply `salesforce`. We don't want
it to be confused with a future well-known `provider_id` of
`arcade-salesforce`.
Also, what the toolkit was referring to as `org_domain` is actually the
organization's SUBdomain. We changed all references to "subdomain" to be
more precise. The documentation has been updated accordingly.
## Google File Picker
The Google Picker lets users select or upload Google Drive files. Users
can grant permission to your apps to access their Drive data, providing
a secure and authorized way to interact with their files.
The `generate_google_file_picker_url` returns a URL to a Google File
Picker for the user.
| Name | Description |
|----------------------------------|-------------------------------------------------------------------------|
| Reddit.CheckSubredditAccess | Checks whether the specified subreddit
exists and also if it is accessible |
| Reddit.GetSubredditRules | Gets the rules of the specified subreddit |
| Reddit.GetMyUsername | Get the Reddit username of the authenticated
user |
| Reddit.GetMyPosts | Get posts that were created by the authenticated
user sorted by newest |
Four new tools that I had to create for my demo app.
| Name | Description | Package | Version |
|-----------------------------------|---------------------------------------------------------------------------|---------|---------|
| Stripe.CreateCustomer | This tool will create a customer in Stripe. |
Stripe | 0.0.1 |
| Stripe.ListCustomers | This tool will fetch a list of Customers from
Stripe. | Stripe | 0.0.1 |
| Stripe.CreateProduct | This tool will create a product in Stripe. |
Stripe | 0.0.1 |
| Stripe.ListProducts | This tool will fetch a list of Products from
Stripe. | Stripe | 0.0.1 |
| Stripe.CreatePrice | This tool will create a price in Stripe. If a
product has not already been | Stripe | 0.0.1 |
| Stripe.ListPrices | This tool will fetch a list of Prices from Stripe.
| Stripe | 0.0.1 |
| Stripe.CreatePaymentLink | This tool will create a payment link in
Stripe. | Stripe | 0.0.1 |
| Stripe.ListInvoices | This tool will list invoices in Stripe. | Stripe
| 0.0.1 |
| Stripe.CreateInvoice | This tool will create an invoice in Stripe. |
Stripe | 0.0.1 |
| Stripe.CreateInvoiceItem | This tool will create an invoice item in
Stripe. | Stripe | 0.0.1 |
| Stripe.FinalizeInvoice | This tool will finalize an invoice in Stripe.
| Stripe | 0.0.1 |
| Stripe.RetrieveBalance | This tool will retrieve the balance from
Stripe. It takes no input. | Stripe | 0.0.1 |
| Stripe.CreateRefund | This tool will refund a payment intent in
Stripe. | Stripe | 0.0.1 |
| Stripe.ListPaymentIntents | This tool will list payment intents in
Stripe. | Stripe | 0.0.1 |
| Stripe.CreateBillingPortalSession | This tool will create a billing
portal session. | Stripe | 0.0.1 |
-------------------------
This PR implements the tools in
[stripe-agent-toolkit](https://github.com/stripe/agent-toolkit)
verbatim. This means that the logic needed to implement these tools is
minimal since stripe has already done the heavy lifting.
The tools added in this toolkit are the same tools that are in the
stripe-agent-toolkit, but formatted as Arcade tools. This means that the
names of the tools, the parameter annotations, and tool docstrings are
taken from the stripe-agent-toolkit. I have omitted evals since the tool
definitions are taken from the stripe-agent-toolkit.
The tools in this PR are generated via a script. I have included this
script in the PR (`_generate.py`) so that if the stripe-agent-toolkit
ever adds more tools, then we can simply run that script to generate the
new tools.