From 5f552582682005f5a62ab776af05408c69d029f4 Mon Sep 17 00:00:00 2001 From: Eric Gustin <34000337+EricGustin@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:26:27 -0700 Subject: [PATCH] General OSS health (#643) --- README.md | 121 ++++++++++++------ .../examples}/ai-sdk/.env.example | 0 .../examples}/ai-sdk/.gitignore | 0 .../examples}/ai-sdk/LICENSE | 0 .../examples}/ai-sdk/README.md | 0 .../examples}/ai-sdk/generateText.js | 0 .../examples}/ai-sdk/index.js | 0 .../examples}/ai-sdk/package.json | 0 .../examples}/ai-sdk/pnpm-lock.yaml | 0 .../crewai/crewai_with_arcade_tool.py | 0 .../examples}/crewai/requirements.txt | 0 .../crewai/simple_crewai_with_arcade_tool.py | 0 .../examples}/langchain-ts/.env.example | 0 .../examples}/langchain-ts/.gitignore | 0 .../examples}/langchain-ts/LICENSE | 0 .../langchain-tool-arcade-auth.ts | 0 .../langchain-ts/langgraph-arcade-minimal.ts | 0 .../langchain-ts/langgraph-with-user-auth.ts | 0 .../examples}/langchain-ts/langgraph.json | 0 .../examples}/langchain-ts/package-lock.json | 0 .../examples}/langchain-ts/package.json | 0 .../examples}/langchain-ts/pnpm-lock.yaml | 0 .../examples}/langchain-ts/tsconfig.json | 0 .../langchain/langchain_tool_arcade_auth.py | 0 .../langchain/langgraph_arcade_minimal.py | 0 .../langchain/langgraph_with_user_auth.py | 0 .../examples}/langchain/requirements.txt | 0 .../examples}/langchain/studio/README.md | 0 .../langchain/studio/configuration.py | 0 .../examples}/langchain/studio/env.example | 0 .../examples}/langchain/studio/graph.py | 0 .../examples}/langchain/studio/langgraph.json | 0 .../langchain/studio/requirements.txt | 0 .../examples}/langgraph-ts/.gitignore | 0 .../examples}/langgraph-ts/README.md | 0 .../examples}/langgraph-ts/langgraph.json | 0 .../examples}/langgraph-ts/package.json | 0 .../langgraph-ts/src/configuration.ts | 0 .../examples}/langgraph-ts/src/graph.ts | 0 .../examples}/langgraph-ts/src/prompts.ts | 0 .../examples}/langgraph-ts/studio.png | Bin .../examples}/mastra/.env.example | 0 .../examples}/mastra/.gitignore | 0 .../examples}/mastra/LICENSE | 0 .../examples}/mastra/README.md | 0 .../examples}/mastra/package.json | 0 .../examples}/mastra/pnpm-lock.yaml | 0 .../mastra/src/mastra/agents/gmail.ts | 0 .../src/mastra/agents/inboxTravelSearch.ts | 0 .../examples}/mastra/src/mastra/index.ts | 0 .../src/mastra/tools/flightSearchTools.ts | 0 .../mastra/src/mastra/tools/gmailTools.ts | 0 .../src/mastra/tools/hotelSearchTools.ts | 0 .../examples}/mastra/tsconfig.json | 0 .../examples}/openai-agents-ts/.env.example | 0 .../examples}/openai-agents-ts/.gitignore | 0 .../examples}/openai-agents-ts/LICENSE | 0 .../examples}/openai-agents-ts/README.md | 0 .../openai-agents-ts/package-lock.json | 0 .../examples}/openai-agents-ts/package.json | 0 .../examples}/openai-agents-ts/src/index.ts | 0 .../openai-agents-ts/src/waitForCompletion.ts | 0 examples/.gitignore | 2 - examples/clients/call_a_tool_directly.py | 40 ------ .../clients/call_a_tool_directly_with_auth.py | 51 -------- examples/clients/call_a_tool_with_llm.py | 45 ------- examples/clients/get_auth_token.py | 58 --------- examples/serving_tools/docker/Dockerfile | 10 -- examples/serving_tools/docker/README.md | 30 ----- examples/serving_tools/docker/toolkits.txt | 1 - examples/serving_tools/modal/README.md | 17 --- .../serving_tools/modal/run-arcade-worker.py | 34 ----- libs/arcade-cli/README.md | 2 +- libs/arcade-cli/arcade_cli/main.py | 2 +- .../minimal/{{ toolkit_name }}/server.py | 6 +- 75 files changed, 90 insertions(+), 329 deletions(-) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/.env.example (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/.gitignore (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/LICENSE (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/README.md (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/generateText.js (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/index.js (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/package.json (100%) rename {examples/agent_frameworks => contrib/examples}/ai-sdk/pnpm-lock.yaml (100%) rename {examples/agent_frameworks => contrib/examples}/crewai/crewai_with_arcade_tool.py (100%) rename {examples/agent_frameworks => contrib/examples}/crewai/requirements.txt (100%) rename {examples/agent_frameworks => contrib/examples}/crewai/simple_crewai_with_arcade_tool.py (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/.env.example (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/.gitignore (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/LICENSE (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/langchain-tool-arcade-auth.ts (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/langgraph-arcade-minimal.ts (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/langgraph-with-user-auth.ts (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/langgraph.json (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/package-lock.json (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/package.json (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/pnpm-lock.yaml (100%) rename {examples/agent_frameworks => contrib/examples}/langchain-ts/tsconfig.json (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/langchain_tool_arcade_auth.py (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/langgraph_arcade_minimal.py (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/langgraph_with_user_auth.py (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/requirements.txt (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/studio/README.md (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/studio/configuration.py (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/studio/env.example (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/studio/graph.py (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/studio/langgraph.json (100%) rename {examples/agent_frameworks => contrib/examples}/langchain/studio/requirements.txt (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/.gitignore (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/README.md (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/langgraph.json (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/package.json (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/src/configuration.ts (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/src/graph.ts (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/src/prompts.ts (100%) rename {examples/agent_frameworks => contrib/examples}/langgraph-ts/studio.png (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/.env.example (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/.gitignore (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/LICENSE (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/README.md (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/package.json (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/pnpm-lock.yaml (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/src/mastra/agents/gmail.ts (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/src/mastra/agents/inboxTravelSearch.ts (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/src/mastra/index.ts (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/src/mastra/tools/flightSearchTools.ts (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/src/mastra/tools/gmailTools.ts (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/src/mastra/tools/hotelSearchTools.ts (100%) rename {examples/agent_frameworks => contrib/examples}/mastra/tsconfig.json (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/.env.example (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/.gitignore (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/LICENSE (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/README.md (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/package-lock.json (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/package.json (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/src/index.ts (100%) rename {examples/agent_frameworks => contrib/examples}/openai-agents-ts/src/waitForCompletion.ts (100%) delete mode 100644 examples/.gitignore delete mode 100644 examples/clients/call_a_tool_directly.py delete mode 100644 examples/clients/call_a_tool_directly_with_auth.py delete mode 100644 examples/clients/call_a_tool_with_llm.py delete mode 100644 examples/clients/get_auth_token.py delete mode 100644 examples/serving_tools/docker/Dockerfile delete mode 100644 examples/serving_tools/docker/README.md delete mode 100644 examples/serving_tools/docker/toolkits.txt delete mode 100644 examples/serving_tools/modal/README.md delete mode 100644 examples/serving_tools/modal/run-arcade-worker.py diff --git a/README.md b/README.md index 44026c79..815cacea 100644 --- a/README.md +++ b/README.md @@ -32,16 +32,16 @@
- Documentation •
- Tools •
- Quickstart •
+ Prebuilt Tools •
Contact Us
# Arcade MCP Server Framework
-**To learn more about Arcade.dev, check out our [documentation](https://docs.arcade.dev/home).**
+* **To see example servers built with Arcade MCP Server Framework (this repo), check out our [examples](examples/)**
-**To learn more about the Arcade MCP Server Framework, check out our [Arcade MCP documentation](https://python.mcp.arcade.dev/)**
+* **To learn more about the Arcade MCP Server Framework (this repo), check out our [Arcade MCP documentation](https://docs.arcade.dev/en/home/build-tools/create-a-mcp-server)**
+
+* **To learn more about other offerings from Arcade.dev, check out our [documentation](https://docs.arcade.dev/home).**
_Pst. hey, you, give us a star if you like it!_
@@ -49,13 +49,13 @@ _Pst. hey, you, give us a star if you like it!_
-### Quick Start: Create a New Server
+## Quick Start: Create a New Server
-The fastest way to get started is with the `arcade new` command, which creates a complete MCP server project:
+The fastest way to get started is with the `arcade new` CLI command, which creates a complete MCP server project:
```bash
# Install the CLI
-uv pip install arcade-mcp
+uv tool install arcade-mcp
# Create a new server project
arcade new my_server
@@ -64,7 +64,7 @@ arcade new my_server
cd my_server
```
-This generates a complete project with:
+This generates a project with:
- **server.py** - Main server file with MCPApp and example tools
@@ -72,24 +72,84 @@ This generates a complete project with:
- **.env.example** - Example `.env` file containing a secret required by one of the generated tools in `server.py`
-The generated `server.py` includes proper command-line argument handling:
+The generated `server.py` includes proper command-line argument handling and three example tools:
```python
#!/usr/bin/env python3
+"""simple_server MCP server"""
+
import sys
from typing import Annotated
-from arcade_mcp_server import MCPApp
-app = MCPApp(name="my_server", version="1.0.0")
+import httpx
+from arcade_mcp_server import Context, MCPApp
+from arcade_mcp_server.auth import Reddit
+
+app = MCPApp(name="simple_server", version="1.0.0", log_level="DEBUG")
+
@app.tool
-def greet(name: Annotated[str, "Name to greet"]) -> str:
- """Greet someone by name."""
+def greet(name: Annotated[str, "The name of the person to greet"]) -> str:
+ """Greet a person by name."""
return f"Hello, {name}!"
+
+# To use this tool locally, you need to either set the secret in the .env file or as an environment variable
+@app.tool(requires_secrets=["MY_SECRET_KEY"])
+def whisper_secret(context: Context) -> Annotated[str, "The last 4 characters of the secret"]:
+ """Reveal the last 4 characters of a secret"""
+ # Secrets are injected into the context at runtime.
+ # LLMs and MCP clients cannot see or access your secrets
+ # You can define secrets in a .env file.
+ try:
+ secret = context.get_secret("MY_SECRET_KEY")
+ except Exception as e:
+ return str(e)
+
+ return "The last 4 characters of the secret are: " + secret[-4:]
+
+# To use this tool locally, you need to install the Arcade CLI (uv tool install arcade-mcp)
+# and then run 'arcade login' to authenticate.
+@app.tool(requires_auth=Reddit(scopes=["read"]))
+async def get_posts_in_subreddit(
+ context: Context, subreddit: Annotated[str, "The name of the subreddit"]
+) -> dict:
+ """Get posts from a specific subreddit"""
+ # Normalize the subreddit name
+ subreddit = subreddit.lower().replace("r/", "").replace(" ", "")
+
+ # Prepare the httpx request
+ # OAuth token is injected into the context at runtime.
+ # LLMs and MCP clients cannot see or access your OAuth tokens.
+ oauth_token = context.get_auth_token_or_empty()
+ headers = {
+ "Authorization": f"Bearer {oauth_token}",
+ "User-Agent": "{{ toolkit_name }}-mcp-server",
+ }
+ params = {"limit": 5}
+ url = f"https://oauth.reddit.com/r/{subreddit}/hot"
+
+ # Make the request
+ async with httpx.AsyncClient() as client:
+ response = await client.get(url, headers=headers, params=params)
+ response.raise_for_status()
+
+ # Return the response
+ return response.json()
+
+# Run with specific transport
if __name__ == "__main__":
- transport = sys.argv[1] if len(sys.argv) > 1 else "http"
+ # Get transport from command line argument, default to "stdio"
+ # - "stdio" (default): Standard I/O for Claude Desktop, CLI tools, etc.
+ # Supports tools that require_auth or require_secrets out-of-the-box
+ # - "http": HTTPS streaming for Cursor, VS Code, etc.
+ # Does not support tools that require_auth or require_secrets unless the server is deployed
+ # using 'arcade deploy' or added in the Arcade Developer Dashboard with 'Arcade' server type
+ transport = sys.argv[1] if len(sys.argv) > 1 else "stdio"
+
+ # Run the server
app.run(transport=transport, host="127.0.0.1", port=8000)
+
```
This approach gives you:
@@ -106,11 +166,11 @@ This approach gives you:
Run your server directly with Python:
```bash
-# Run with HTTP transport (default)
+# Run with stdio transport (default)
uv run server.py
-# Run with stdio transport (for Claude Desktop)
-uv run server.py stdio
+# Run with http transport via command line argument
+uv run server.py http
# Or use python directly
python server.py http
@@ -124,26 +184,15 @@ Your server will start and listen for connections. With HTTP transport, you can
Once your server is running, connect it to your favorite AI assistant:
```bash
-# Configure Claude Desktop (configures for stdio)
-arcade configure claude --from-local
-
-# Configure Cursor (configures for http streamable)
-arcade configure cursor --from-local
-
-# Configure VS Code (configures for http streamable)
-arcade configure vscode --from-local
+arcade configure claude # Configure Claude Desktop to connect to your stdio server in your current directory
+arcade configure cursor --transport http --port 8080 # Configure Cursor to connect to your local HTTP server on port 8080
+arcade configure vscode --entrypoint my_server.py # Configure VSCode to connect to your stdio server that will run when my_server.py is executed directly
```
-## Client Libraries
-
-- **[ArcadeAI/arcade-py](https://github.com/ArcadeAI/arcade-py):**
- The Python client for interacting with Arcade.
-
-- **[ArcadeAI/arcade-js](https://github.com/ArcadeAI/arcade-js):**
- The JavaScript client for interacting with Arcade.
-
-- **[ArcadeAI/arcade-go](https://github.com/ArcadeAI/arcade-go):**
- The Go client for interacting with Arcade.
+## Installing this Repo from Source
+```bash
+git clone https://github.com/ArcadeAI/arcade-mcp.git && cd arcade-mcp && make install
+```
## Support and Community
diff --git a/examples/agent_frameworks/ai-sdk/.env.example b/contrib/examples/ai-sdk/.env.example
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/.env.example
rename to contrib/examples/ai-sdk/.env.example
diff --git a/examples/agent_frameworks/ai-sdk/.gitignore b/contrib/examples/ai-sdk/.gitignore
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/.gitignore
rename to contrib/examples/ai-sdk/.gitignore
diff --git a/examples/agent_frameworks/ai-sdk/LICENSE b/contrib/examples/ai-sdk/LICENSE
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/LICENSE
rename to contrib/examples/ai-sdk/LICENSE
diff --git a/examples/agent_frameworks/ai-sdk/README.md b/contrib/examples/ai-sdk/README.md
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/README.md
rename to contrib/examples/ai-sdk/README.md
diff --git a/examples/agent_frameworks/ai-sdk/generateText.js b/contrib/examples/ai-sdk/generateText.js
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/generateText.js
rename to contrib/examples/ai-sdk/generateText.js
diff --git a/examples/agent_frameworks/ai-sdk/index.js b/contrib/examples/ai-sdk/index.js
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/index.js
rename to contrib/examples/ai-sdk/index.js
diff --git a/examples/agent_frameworks/ai-sdk/package.json b/contrib/examples/ai-sdk/package.json
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/package.json
rename to contrib/examples/ai-sdk/package.json
diff --git a/examples/agent_frameworks/ai-sdk/pnpm-lock.yaml b/contrib/examples/ai-sdk/pnpm-lock.yaml
similarity index 100%
rename from examples/agent_frameworks/ai-sdk/pnpm-lock.yaml
rename to contrib/examples/ai-sdk/pnpm-lock.yaml
diff --git a/examples/agent_frameworks/crewai/crewai_with_arcade_tool.py b/contrib/examples/crewai/crewai_with_arcade_tool.py
similarity index 100%
rename from examples/agent_frameworks/crewai/crewai_with_arcade_tool.py
rename to contrib/examples/crewai/crewai_with_arcade_tool.py
diff --git a/examples/agent_frameworks/crewai/requirements.txt b/contrib/examples/crewai/requirements.txt
similarity index 100%
rename from examples/agent_frameworks/crewai/requirements.txt
rename to contrib/examples/crewai/requirements.txt
diff --git a/examples/agent_frameworks/crewai/simple_crewai_with_arcade_tool.py b/contrib/examples/crewai/simple_crewai_with_arcade_tool.py
similarity index 100%
rename from examples/agent_frameworks/crewai/simple_crewai_with_arcade_tool.py
rename to contrib/examples/crewai/simple_crewai_with_arcade_tool.py
diff --git a/examples/agent_frameworks/langchain-ts/.env.example b/contrib/examples/langchain-ts/.env.example
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/.env.example
rename to contrib/examples/langchain-ts/.env.example
diff --git a/examples/agent_frameworks/langchain-ts/.gitignore b/contrib/examples/langchain-ts/.gitignore
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/.gitignore
rename to contrib/examples/langchain-ts/.gitignore
diff --git a/examples/agent_frameworks/langchain-ts/LICENSE b/contrib/examples/langchain-ts/LICENSE
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/LICENSE
rename to contrib/examples/langchain-ts/LICENSE
diff --git a/examples/agent_frameworks/langchain-ts/langchain-tool-arcade-auth.ts b/contrib/examples/langchain-ts/langchain-tool-arcade-auth.ts
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/langchain-tool-arcade-auth.ts
rename to contrib/examples/langchain-ts/langchain-tool-arcade-auth.ts
diff --git a/examples/agent_frameworks/langchain-ts/langgraph-arcade-minimal.ts b/contrib/examples/langchain-ts/langgraph-arcade-minimal.ts
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/langgraph-arcade-minimal.ts
rename to contrib/examples/langchain-ts/langgraph-arcade-minimal.ts
diff --git a/examples/agent_frameworks/langchain-ts/langgraph-with-user-auth.ts b/contrib/examples/langchain-ts/langgraph-with-user-auth.ts
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/langgraph-with-user-auth.ts
rename to contrib/examples/langchain-ts/langgraph-with-user-auth.ts
diff --git a/examples/agent_frameworks/langchain-ts/langgraph.json b/contrib/examples/langchain-ts/langgraph.json
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/langgraph.json
rename to contrib/examples/langchain-ts/langgraph.json
diff --git a/examples/agent_frameworks/langchain-ts/package-lock.json b/contrib/examples/langchain-ts/package-lock.json
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/package-lock.json
rename to contrib/examples/langchain-ts/package-lock.json
diff --git a/examples/agent_frameworks/langchain-ts/package.json b/contrib/examples/langchain-ts/package.json
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/package.json
rename to contrib/examples/langchain-ts/package.json
diff --git a/examples/agent_frameworks/langchain-ts/pnpm-lock.yaml b/contrib/examples/langchain-ts/pnpm-lock.yaml
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/pnpm-lock.yaml
rename to contrib/examples/langchain-ts/pnpm-lock.yaml
diff --git a/examples/agent_frameworks/langchain-ts/tsconfig.json b/contrib/examples/langchain-ts/tsconfig.json
similarity index 100%
rename from examples/agent_frameworks/langchain-ts/tsconfig.json
rename to contrib/examples/langchain-ts/tsconfig.json
diff --git a/examples/agent_frameworks/langchain/langchain_tool_arcade_auth.py b/contrib/examples/langchain/langchain_tool_arcade_auth.py
similarity index 100%
rename from examples/agent_frameworks/langchain/langchain_tool_arcade_auth.py
rename to contrib/examples/langchain/langchain_tool_arcade_auth.py
diff --git a/examples/agent_frameworks/langchain/langgraph_arcade_minimal.py b/contrib/examples/langchain/langgraph_arcade_minimal.py
similarity index 100%
rename from examples/agent_frameworks/langchain/langgraph_arcade_minimal.py
rename to contrib/examples/langchain/langgraph_arcade_minimal.py
diff --git a/examples/agent_frameworks/langchain/langgraph_with_user_auth.py b/contrib/examples/langchain/langgraph_with_user_auth.py
similarity index 100%
rename from examples/agent_frameworks/langchain/langgraph_with_user_auth.py
rename to contrib/examples/langchain/langgraph_with_user_auth.py
diff --git a/examples/agent_frameworks/langchain/requirements.txt b/contrib/examples/langchain/requirements.txt
similarity index 100%
rename from examples/agent_frameworks/langchain/requirements.txt
rename to contrib/examples/langchain/requirements.txt
diff --git a/examples/agent_frameworks/langchain/studio/README.md b/contrib/examples/langchain/studio/README.md
similarity index 100%
rename from examples/agent_frameworks/langchain/studio/README.md
rename to contrib/examples/langchain/studio/README.md
diff --git a/examples/agent_frameworks/langchain/studio/configuration.py b/contrib/examples/langchain/studio/configuration.py
similarity index 100%
rename from examples/agent_frameworks/langchain/studio/configuration.py
rename to contrib/examples/langchain/studio/configuration.py
diff --git a/examples/agent_frameworks/langchain/studio/env.example b/contrib/examples/langchain/studio/env.example
similarity index 100%
rename from examples/agent_frameworks/langchain/studio/env.example
rename to contrib/examples/langchain/studio/env.example
diff --git a/examples/agent_frameworks/langchain/studio/graph.py b/contrib/examples/langchain/studio/graph.py
similarity index 100%
rename from examples/agent_frameworks/langchain/studio/graph.py
rename to contrib/examples/langchain/studio/graph.py
diff --git a/examples/agent_frameworks/langchain/studio/langgraph.json b/contrib/examples/langchain/studio/langgraph.json
similarity index 100%
rename from examples/agent_frameworks/langchain/studio/langgraph.json
rename to contrib/examples/langchain/studio/langgraph.json
diff --git a/examples/agent_frameworks/langchain/studio/requirements.txt b/contrib/examples/langchain/studio/requirements.txt
similarity index 100%
rename from examples/agent_frameworks/langchain/studio/requirements.txt
rename to contrib/examples/langchain/studio/requirements.txt
diff --git a/examples/agent_frameworks/langgraph-ts/.gitignore b/contrib/examples/langgraph-ts/.gitignore
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/.gitignore
rename to contrib/examples/langgraph-ts/.gitignore
diff --git a/examples/agent_frameworks/langgraph-ts/README.md b/contrib/examples/langgraph-ts/README.md
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/README.md
rename to contrib/examples/langgraph-ts/README.md
diff --git a/examples/agent_frameworks/langgraph-ts/langgraph.json b/contrib/examples/langgraph-ts/langgraph.json
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/langgraph.json
rename to contrib/examples/langgraph-ts/langgraph.json
diff --git a/examples/agent_frameworks/langgraph-ts/package.json b/contrib/examples/langgraph-ts/package.json
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/package.json
rename to contrib/examples/langgraph-ts/package.json
diff --git a/examples/agent_frameworks/langgraph-ts/src/configuration.ts b/contrib/examples/langgraph-ts/src/configuration.ts
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/src/configuration.ts
rename to contrib/examples/langgraph-ts/src/configuration.ts
diff --git a/examples/agent_frameworks/langgraph-ts/src/graph.ts b/contrib/examples/langgraph-ts/src/graph.ts
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/src/graph.ts
rename to contrib/examples/langgraph-ts/src/graph.ts
diff --git a/examples/agent_frameworks/langgraph-ts/src/prompts.ts b/contrib/examples/langgraph-ts/src/prompts.ts
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/src/prompts.ts
rename to contrib/examples/langgraph-ts/src/prompts.ts
diff --git a/examples/agent_frameworks/langgraph-ts/studio.png b/contrib/examples/langgraph-ts/studio.png
similarity index 100%
rename from examples/agent_frameworks/langgraph-ts/studio.png
rename to contrib/examples/langgraph-ts/studio.png
diff --git a/examples/agent_frameworks/mastra/.env.example b/contrib/examples/mastra/.env.example
similarity index 100%
rename from examples/agent_frameworks/mastra/.env.example
rename to contrib/examples/mastra/.env.example
diff --git a/examples/agent_frameworks/mastra/.gitignore b/contrib/examples/mastra/.gitignore
similarity index 100%
rename from examples/agent_frameworks/mastra/.gitignore
rename to contrib/examples/mastra/.gitignore
diff --git a/examples/agent_frameworks/mastra/LICENSE b/contrib/examples/mastra/LICENSE
similarity index 100%
rename from examples/agent_frameworks/mastra/LICENSE
rename to contrib/examples/mastra/LICENSE
diff --git a/examples/agent_frameworks/mastra/README.md b/contrib/examples/mastra/README.md
similarity index 100%
rename from examples/agent_frameworks/mastra/README.md
rename to contrib/examples/mastra/README.md
diff --git a/examples/agent_frameworks/mastra/package.json b/contrib/examples/mastra/package.json
similarity index 100%
rename from examples/agent_frameworks/mastra/package.json
rename to contrib/examples/mastra/package.json
diff --git a/examples/agent_frameworks/mastra/pnpm-lock.yaml b/contrib/examples/mastra/pnpm-lock.yaml
similarity index 100%
rename from examples/agent_frameworks/mastra/pnpm-lock.yaml
rename to contrib/examples/mastra/pnpm-lock.yaml
diff --git a/examples/agent_frameworks/mastra/src/mastra/agents/gmail.ts b/contrib/examples/mastra/src/mastra/agents/gmail.ts
similarity index 100%
rename from examples/agent_frameworks/mastra/src/mastra/agents/gmail.ts
rename to contrib/examples/mastra/src/mastra/agents/gmail.ts
diff --git a/examples/agent_frameworks/mastra/src/mastra/agents/inboxTravelSearch.ts b/contrib/examples/mastra/src/mastra/agents/inboxTravelSearch.ts
similarity index 100%
rename from examples/agent_frameworks/mastra/src/mastra/agents/inboxTravelSearch.ts
rename to contrib/examples/mastra/src/mastra/agents/inboxTravelSearch.ts
diff --git a/examples/agent_frameworks/mastra/src/mastra/index.ts b/contrib/examples/mastra/src/mastra/index.ts
similarity index 100%
rename from examples/agent_frameworks/mastra/src/mastra/index.ts
rename to contrib/examples/mastra/src/mastra/index.ts
diff --git a/examples/agent_frameworks/mastra/src/mastra/tools/flightSearchTools.ts b/contrib/examples/mastra/src/mastra/tools/flightSearchTools.ts
similarity index 100%
rename from examples/agent_frameworks/mastra/src/mastra/tools/flightSearchTools.ts
rename to contrib/examples/mastra/src/mastra/tools/flightSearchTools.ts
diff --git a/examples/agent_frameworks/mastra/src/mastra/tools/gmailTools.ts b/contrib/examples/mastra/src/mastra/tools/gmailTools.ts
similarity index 100%
rename from examples/agent_frameworks/mastra/src/mastra/tools/gmailTools.ts
rename to contrib/examples/mastra/src/mastra/tools/gmailTools.ts
diff --git a/examples/agent_frameworks/mastra/src/mastra/tools/hotelSearchTools.ts b/contrib/examples/mastra/src/mastra/tools/hotelSearchTools.ts
similarity index 100%
rename from examples/agent_frameworks/mastra/src/mastra/tools/hotelSearchTools.ts
rename to contrib/examples/mastra/src/mastra/tools/hotelSearchTools.ts
diff --git a/examples/agent_frameworks/mastra/tsconfig.json b/contrib/examples/mastra/tsconfig.json
similarity index 100%
rename from examples/agent_frameworks/mastra/tsconfig.json
rename to contrib/examples/mastra/tsconfig.json
diff --git a/examples/agent_frameworks/openai-agents-ts/.env.example b/contrib/examples/openai-agents-ts/.env.example
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/.env.example
rename to contrib/examples/openai-agents-ts/.env.example
diff --git a/examples/agent_frameworks/openai-agents-ts/.gitignore b/contrib/examples/openai-agents-ts/.gitignore
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/.gitignore
rename to contrib/examples/openai-agents-ts/.gitignore
diff --git a/examples/agent_frameworks/openai-agents-ts/LICENSE b/contrib/examples/openai-agents-ts/LICENSE
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/LICENSE
rename to contrib/examples/openai-agents-ts/LICENSE
diff --git a/examples/agent_frameworks/openai-agents-ts/README.md b/contrib/examples/openai-agents-ts/README.md
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/README.md
rename to contrib/examples/openai-agents-ts/README.md
diff --git a/examples/agent_frameworks/openai-agents-ts/package-lock.json b/contrib/examples/openai-agents-ts/package-lock.json
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/package-lock.json
rename to contrib/examples/openai-agents-ts/package-lock.json
diff --git a/examples/agent_frameworks/openai-agents-ts/package.json b/contrib/examples/openai-agents-ts/package.json
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/package.json
rename to contrib/examples/openai-agents-ts/package.json
diff --git a/examples/agent_frameworks/openai-agents-ts/src/index.ts b/contrib/examples/openai-agents-ts/src/index.ts
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/src/index.ts
rename to contrib/examples/openai-agents-ts/src/index.ts
diff --git a/examples/agent_frameworks/openai-agents-ts/src/waitForCompletion.ts b/contrib/examples/openai-agents-ts/src/waitForCompletion.ts
similarity index 100%
rename from examples/agent_frameworks/openai-agents-ts/src/waitForCompletion.ts
rename to contrib/examples/openai-agents-ts/src/waitForCompletion.ts
diff --git a/examples/.gitignore b/examples/.gitignore
deleted file mode 100644
index 2edb4a25..00000000
--- a/examples/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Un-ignore poetry.lock because the projects in this directory represent runnable sample apps
-!poetry.lock
diff --git a/examples/clients/call_a_tool_directly.py b/examples/clients/call_a_tool_directly.py
deleted file mode 100644
index c913783e..00000000
--- a/examples/clients/call_a_tool_directly.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""
-This example demonstrates how to directly call a tool that does not require authorization.
-"""
-
-from arcadepy import Arcade # pip install arcade-py
-
-
-def call_non_auth_tool(client: Arcade, user_id: str) -> None:
- """Directly call a prebuilt tool that does not require authorization.
-
- In this example, we are
- 1. Preparing the inputs to the Math.Add tool
- 2. Executing the tool
- 3. Printing the output of the tool's execution, i.e., the result of adding 9001 and 42
-
- This is a simple example of calling a non-auth tool. Next, try writing your own non-auth tool for your own use case.
- """
- # Prepare the inputs to the tool as a dictionary where keys are the names of the parameters expected by the tool and the values are the actual values to pass to the tool
- tool_input = {"a": 9001, "b": 42}
-
- # Execute the tool
- response = client.tools.execute(
- tool_name="Math.Add",
- input=tool_input,
- user_id=user_id,
- )
-
- # Print the output of the tool execution
- print(response.output.value)
-
-
-if __name__ == "__main__":
- cloud_host = "https://api.arcade.dev"
-
- client = Arcade(
- base_url=cloud_host, # Alternatively, use http://localhost:9099 if you are running Arcade Engine locally, or any base_url if you're hosting elsewhere
- )
-
- user_id = "you@example.com"
- call_non_auth_tool(client, user_id)
diff --git a/examples/clients/call_a_tool_directly_with_auth.py b/examples/clients/call_a_tool_directly_with_auth.py
deleted file mode 100644
index 333b5874..00000000
--- a/examples/clients/call_a_tool_directly_with_auth.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""
-This example demonstrates how to directly call a tool that requires authorization.
-"""
-
-from arcadepy import Arcade # pip install arcade-py
-
-
-def call_auth_tool(client: Arcade, user_id: str) -> None:
- """Directly call a prebuilt tool that requires authorization.
-
- In this example, we are
- 1. Authorizing Arcade to read emails from the user's Gmail account with the user's permission to do so
- 2. Reading 5 emails from the user's Gmail account
- 3. Printing the emails
-
- Try altering this example to call a tool that requires a different authorization.
- """
- # Start the authorization process
- auth_response = client.tools.authorize(
- tool_name="Gmail.ListEmails",
- user_id=user_id,
- )
-
- # If not already authorized, then wait for the user to authorize the permissions required by the tool
- if auth_response.status != "completed":
- print(f"Click this link to authorize: {auth_response.url}")
-
- # Wait for the user to complete the auth flow, if necessary
- client.auth.wait_for_completion(auth_response)
-
- # Prepare the inputs to the tool as a dictionary where keys are the names of the parameters expected by the tool and the values are the actual values to pass to the tool
- tool_input = {"n_emails": 5}
-
- # Execute the tool
- response = client.tools.execute(
- tool_name="Gmail.ListEmails",
- input=tool_input,
- user_id=user_id,
- )
-
- # Print the output of the tool execution.
- print(response)
-
-
-if __name__ == "__main__":
- client = Arcade(
- base_url="https://api.arcade.dev", # Alternatively, use http://localhost:9099 if you are running Arcade Engine locally, or any base_url if you're hosting elsewhere
- )
-
- user_id = "you@example.com"
- call_auth_tool(client, user_id)
diff --git a/examples/clients/call_a_tool_with_llm.py b/examples/clients/call_a_tool_with_llm.py
deleted file mode 100644
index 1d8e18e6..00000000
--- a/examples/clients/call_a_tool_with_llm.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""
-This example shows how to call a tool that requires authorization with an LLM using the OpenAI Python client.
-"""
-
-import os
-
-from openai import OpenAI
-
-
-def call_tool_with_openai(client: OpenAI) -> dict:
- response = client.chat.completions.create(
- messages=[
- {"role": "user", "content": "Star the ArcadeAI/arcade-mcp repository."},
- ],
- model="gpt-4o-mini", # TODO: Try "claude-3-5-sonnet-20240620" or other models from our supported model providers. Checkout out our docs for a full list https://docs.arcade.dev
- user="you@example.com",
- tools=["Github.SetStarred"],
- tool_choice="generate", # TODO: Try "execute" and note any differences
- )
-
- return response
-
-
-if __name__ == "__main__":
- arcade_api_key = os.environ.get(
- "ARCADE_API_KEY"
- ) # If you forget your Arcade API key, it is stored at ~/.arcade/credentials.yaml on `arcade login`
- cloud_host = "https://api.arcade.dev" + "/v1"
-
- openai_client = OpenAI(
- api_key=arcade_api_key,
- base_url=cloud_host, # Alternatively, use http://localhost:9099/v1 if you are running Arcade Engine locally
- )
-
- chat_result = call_tool_with_openai(openai_client)
- # If the tool call requires authorization, then wait for the user to authorize and then call the tool again
- if (
- chat_result.choices[0].tool_authorizations
- and chat_result.choices[0].tool_authorizations[0].get("status") == "pending"
- ):
- print(chat_result.choices[0].message.content)
- input("After you have authorized, press Enter to continue...")
- chat_result = call_tool_with_openai(openai_client)
-
- print(chat_result.choices[0].message.content)
diff --git a/examples/clients/get_auth_token.py b/examples/clients/get_auth_token.py
deleted file mode 100644
index 9840c5f8..00000000
--- a/examples/clients/get_auth_token.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""
-This example demonstrates how to get an authorization token for a user and then use it to make a request to the Google API on behalf of the user.
-"""
-
-from arcadepy import Arcade
-from google.oauth2.credentials import Credentials # pip install google-auth
-from googleapiclient.discovery import build # pip install google-api-python-client
-
-
-def get_auth_token(client: Arcade, user_id: str) -> str:
- """Get an authorization token for a user.
-
- In this example, we are
- 1. Starting the authorization process for the Gmail Readonly scope
- 2. Waiting for the user to authorize the scope
- 3. Getting the authorization token
- 4. Using the authorization token to make a request to the Google API on behalf of the user
- """
- # Start the authorization process
- auth_response = client.auth.start(
- user_id, "google", scopes=["https://www.googleapis.com/auth/gmail.readonly"]
- )
-
- if auth_response.status != "completed":
- print(f"Click this link to authorize: {auth_response.url}")
- auth_response = client.auth.wait_for_completion(auth_response)
-
- return auth_response.context.token
-
-
-def use_auth_token(token: str) -> None:
- """Use an authorization token to make a request to the Google API on behalf of a user.
-
- In this example, we are
- 1. Using the authorization token that we got from the authorization process to make a request to the Google API
- client.auth.wait_for_completion(auth_response)
- """
- # Use the token from the authorization response
- creds = Credentials(token)
- service = build("gmail", "v1", credentials=creds)
-
- # Now you can use the Google API
- results = service.users().labels().list(userId="me").execute()
- labels = results.get("labels", [])
- print("Labels:", labels)
-
-
-if __name__ == "__main__":
- cloud_host = "https://api.arcade.dev"
-
- client = Arcade(
- base_url=cloud_host, # Alternatively, use http://localhost:9099 if you are running Arcade locally, or any base_url if you're hosting elsewhere
- )
-
- user_id = "you@example.com"
-
- token = get_auth_token(client, user_id)
- use_auth_token(token)
diff --git a/examples/serving_tools/docker/Dockerfile b/examples/serving_tools/docker/Dockerfile
deleted file mode 100644
index 3267cd9d..00000000
--- a/examples/serving_tools/docker/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-ARG VERSION=latest
-
-# Base worker image
-FROM ghcr.io/arcadeai/worker-base:${VERSION}
-
-# Copy requirements and constraints
-COPY toolkits.txt ./
-
-# Install toolkits from file
-RUN pip install -r toolkits.txt
diff --git a/examples/serving_tools/docker/README.md b/examples/serving_tools/docker/README.md
deleted file mode 100644
index 1a67fddd..00000000
--- a/examples/serving_tools/docker/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-## Custom Worker Image
-
-This example shows how to build a custom worker image with toolkits.
-
-### Requirements
-
-- Docker
-
-### Build
-
-```
-docker build -t custom-worker:0.1.0 .
-```
-
-### Run
-
-```
-docker run -p 8002:8002 custom-worker:0.1.0
-```
-
-### Change the Toolkits
-
-To change the toolkits, edit the `toolkits.txt` file.
-
-```
-arcade-gmail==0.1.0
-arcade-firecrawl==0.1.0
-arcade-zoom==0.1.2
-...
-```
diff --git a/examples/serving_tools/docker/toolkits.txt b/examples/serving_tools/docker/toolkits.txt
deleted file mode 100644
index c2fc264c..00000000
--- a/examples/serving_tools/docker/toolkits.txt
+++ /dev/null
@@ -1 +0,0 @@
-arcade-gmail
diff --git a/examples/serving_tools/modal/README.md b/examples/serving_tools/modal/README.md
deleted file mode 100644
index 69907ff4..00000000
--- a/examples/serving_tools/modal/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Deploy a Custom Arcade Worker on Modal
-
-### Requirements
-
-- Python 3.10+
-- Modal CLI
-
-### Deploy
-
-```bash
-cd examples/serving-tools
-modal deploy run-arcade-worker.py
-```
-
-### Changing the Toolkits
-
-To change the toolkits, edit the `toolkits` list in the `run-arcade-worker.py` file.
diff --git a/examples/serving_tools/modal/run-arcade-worker.py b/examples/serving_tools/modal/run-arcade-worker.py
deleted file mode 100644
index d7bd0f4f..00000000
--- a/examples/serving_tools/modal/run-arcade-worker.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import os
-
-from modal import App, Image, asgi_app
-
-# Define the FastAPI app
-app = App("arcade-worker")
-
-toolkits = ["arcade_gmail", "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 arcade_serve.fastapi.worker import FastAPIWorker
- from arcade_tdk import Toolkit
- from fastapi import FastAPI
-
- 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 installed_toolkits:
- if toolkit.package_name in toolkits:
- worker.register_toolkit(toolkit)
-
- return web_app
diff --git a/libs/arcade-cli/README.md b/libs/arcade-cli/README.md
index 24e6270d..a9ae83b5 100644
--- a/libs/arcade-cli/README.md
+++ b/libs/arcade-cli/README.md
@@ -14,7 +14,7 @@ Arcade CLI provides a comprehensive command-line interface for the Arcade platfo
## Installation
```bash
-pip install arcade-mcp
+uv tool install arcade-mcp
```
## Usage
diff --git a/libs/arcade-cli/arcade_cli/main.py b/libs/arcade-cli/arcade_cli/main.py
index 7bafa33e..fedd9361 100644
--- a/libs/arcade-cli/arcade_cli/main.py
+++ b/libs/arcade-cli/arcade_cli/main.py
@@ -531,7 +531,7 @@ def configure(
Examples:
arcade configure claude
arcade configure cursor --transport http --port 8080
- arcade configure vscode --host arcade --entrypoint ../../../mcp/server.py --config .vscode/mcp.json
+ arcade configure vscode --host arcade --entrypoint my_server.py --config .vscode/mcp.json
arcade configure claude --host local --name my_server_name
"""
from arcade_cli.configure import configure_client
diff --git a/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/server.py b/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/server.py
index a438db09..0417dfaa 100644
--- a/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/server.py
+++ b/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/server.py
@@ -17,7 +17,7 @@ def greet(name: Annotated[str, "The name of the person to greet"]) -> str:
return f"Hello, {name}!"
-# To use this tool, you need to either set the secret in the .env file or as an environment variable
+# To use this tool locally, you need to either set the secret in the .env file or as an environment variable
@app.tool(requires_secrets=["MY_SECRET_KEY"])
def whisper_secret(context: Context) -> Annotated[str, "The last 4 characters of the secret"]:
"""Reveal the last 4 characters of a secret"""
@@ -31,8 +31,8 @@ def whisper_secret(context: Context) -> Annotated[str, "The last 4 characters of
return "The last 4 characters of the secret are: " + secret[-4:]
-# To use this tool, you need to either set your ARCADE_API_KEY as an environment variable or
-# use the Arcade CLI (uv pip install arcade-mcp) and run 'arcade login' to authenticate.
+# To use this tool locally, you need to install the Arcade CLI (uv tool install arcade-mcp)
+# and then run 'arcade login' to authenticate.
@app.tool(requires_auth=Reddit(scopes=["read"]))
async def get_posts_in_subreddit(
context: Context, subreddit: Annotated[str, "The name of the subreddit"]