diff --git a/pages/toolkits/productivity/google/contacts.mdx b/pages/toolkits/productivity/google/contacts.mdx
new file mode 100644
index 000000000..8243b34f3
--- /dev/null
+++ b/pages/toolkits/productivity/google/contacts.mdx
@@ -0,0 +1,180 @@
+# Calendar
+
+import ToolInfo from "@/components/ToolInfo";
+import Badges from "@/components/Badges";
+import TabbedCodeBlock from "@/components/TabbedCodeBlock";
+import TableOfContents from "@/components/TableOfContents";
+
+
+
+
+
+The Arcade Contacts toolkit provides a pre-built set of tools for interacting with Google Contacts. These tools make it easy to build agents and AI apps that can:
+
+- Create new contacts
+- Search for contacts by name or email
+
+## Install
+
+```bash
+pip install arcade_google
+```
+
+
+ pip installing the toolkit is only needed if you are [self-hosting](/home/install/overview) Arcade. You do not need to install the toolkit if you're using Arcade Cloud.
+
+
+## Available Tools
+
+
+
+
+ If you need to perform an action that's not listed here, you can [get in touch
+ with us](mailto:contact@arcade.dev) to request a new tool, or [create your
+ own tools](/home/build-tools/create-a-toolkit) with the [Google auth
+ provider](/home/auth-providers/google#using-google-auth-in-custom-tools).
+
+
+## SearchContactsByEmail
+
+Search the user's contacts in Google Contacts by email address.
+
+
+
+**Parameters**
+
+- **`email`** _(string, required)_: The email address to search for.
+- **`limit`** _(integer, optional)_: The maximum number of contacts to return (30 is the max allowed by the Google API).
+
+---
+
+## SearchContactsByName
+
+Search the user's contacts in Google Contacts by name.
+
+
+
+**Parameters**
+
+- **`name`** _(string, required)_: The full name to search for.
+- **`limit`** _(integer, optional)_: The maximum number of contacts to return (30 is the max allowed by the Google API).
+
+---
+
+## CreateContact
+
+Create a new contact record in Google Contacts.
+
+
+
+**Parameters**
+
+- **`given_name`** _(string, required)_: The given name of the contact.
+- **`family_name`** _(string, optional)_: The optional family name of the contact.
+- **`email`** _(string, optional)_: The optional email address of the contact.
+
+
+---
+
+## Auth
+
+The Arcade Contacts toolkit uses the [Google auth provider](/home/auth-providers/google) to connect to users' Google accounts.
+
+With the hosted Arcade Engine, there's nothing to configure. Your users will see `Arcade (demo)` as the name of the application that's requesting permission.
+
+
+ The hosted Arcade Engine is intended for demo and testing purposes only, not
+ for production use. To use Arcade and Google Contacts in production, you
+ must use a self-hosted instance of the Arcade Engine.
+
+
+With a self-hosted installation of Arcade, you need to [configure the Google auth provider](/home/auth-providers/google#configuring-google-auth) with your own Google app credentials.
diff --git a/public/examples/integrations/toolkits/google/calendar/create_event_example_call_tool.js b/public/examples/integrations/toolkits/google/calendar/create_event_example_call_tool.js
index de744e293..493f23422 100644
--- a/public/examples/integrations/toolkits/google/calendar/create_event_example_call_tool.js
+++ b/public/examples/integrations/toolkits/google/calendar/create_event_example_call_tool.js
@@ -33,4 +33,4 @@ const response = await client.tools.execute({
user_id: USER_ID,
});
-console.log(response);
\ No newline at end of file
+console.log(response);
diff --git a/public/examples/integrations/toolkits/google/calendar/create_event_example_llm_oai.js b/public/examples/integrations/toolkits/google/calendar/create_event_example_llm_oai.js
index 962560f6a..ef84bc07d 100644
--- a/public/examples/integrations/toolkits/google/calendar/create_event_example_llm_oai.js
+++ b/public/examples/integrations/toolkits/google/calendar/create_event_example_llm_oai.js
@@ -19,4 +19,4 @@ const response = await client.chat.completions.create({
tool_choice: 'generate'
});
-console.log(response.choices[0].message.content);
\ No newline at end of file
+console.log(response.choices[0].message.content);
diff --git a/public/examples/integrations/toolkits/google/calendar/delete_event_example_call_tool.js b/public/examples/integrations/toolkits/google/calendar/delete_event_example_call_tool.js
index b3fc094f0..ddc027682 100644
--- a/public/examples/integrations/toolkits/google/calendar/delete_event_example_call_tool.js
+++ b/public/examples/integrations/toolkits/google/calendar/delete_event_example_call_tool.js
@@ -29,4 +29,4 @@ const response = await client.tools.execute({
user_id: USER_ID,
});
-console.log(response);
\ No newline at end of file
+console.log(response);
diff --git a/public/examples/integrations/toolkits/google/contacts/create_contact_example_call_tool.js b/public/examples/integrations/toolkits/google/contacts/create_contact_example_call_tool.js
new file mode 100644
index 000000000..842245d7f
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/create_contact_example_call_tool.js
@@ -0,0 +1,33 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "you@example.com";
+const TOOL_NAME = "Google.CreateContact";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({
+ tool_name: TOOL_NAME,
+ user_id: USER_ID,
+});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ given_name: "John",
+ family_name: "Doe",
+ email: "john.doe@example.com",
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(response);
diff --git a/public/examples/integrations/toolkits/google/contacts/create_contact_example_call_tool.py b/public/examples/integrations/toolkits/google/contacts/create_contact_example_call_tool.py
new file mode 100644
index 000000000..26ac9f7d3
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/create_contact_example_call_tool.py
@@ -0,0 +1,30 @@
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "you@example.com"
+TOOL_NAME = "Google.CreateContact"
+
+auth_response = client.tools.authorize(
+ tool_name=TOOL_NAME,
+ user_id=USER_ID,
+)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "given_name": "John",
+ "family_name": "Doe",
+ "email": "john.doe@example.com",
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(response)
diff --git a/public/examples/integrations/toolkits/google/contacts/create_contact_example_llm_oai.js b/public/examples/integrations/toolkits/google/contacts/create_contact_example_llm_oai.js
new file mode 100644
index 000000000..bd863e2db
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/create_contact_example_llm_oai.js
@@ -0,0 +1,22 @@
+import OpenAI from 'openai';
+
+const USER_ID = "you@example.com";
+const PROMPT = "Create a new contact record for John Doe with the email john.doe@example.com.";
+const TOOL_NAME = "Google.CreateContact";
+
+const client = new OpenAI({
+ baseURL: 'https://api.arcade.dev',
+ apiKey: process.env.ARCADE_API_KEY
+});
+
+const response = await client.chat.completions.create({
+ messages: [
+ { role: 'user', content: PROMPT }
+ ],
+ model: 'gpt-4o-mini',
+ user: USER_ID,
+ tools: [TOOL_NAME],
+ tool_choice: 'generate'
+});
+
+console.log(response.choices[0].message.content);
diff --git a/public/examples/integrations/toolkits/google/contacts/create_contact_example_llm_oai.py b/public/examples/integrations/toolkits/google/contacts/create_contact_example_llm_oai.py
new file mode 100644
index 000000000..774510086
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/create_contact_example_llm_oai.py
@@ -0,0 +1,21 @@
+import os
+from openai import OpenAI
+
+USER_ID = "you@example.com"
+PROMPT = "Create a new contact record for John Doe with the email john.doe@example.com."
+TOOL_NAME = "Google.CreateContact"
+
+client = OpenAI(
+ base_url="https://api.arcade.dev", api_key=os.environ.get("ARCADE_API_KEY")
+)
+
+response = client.chat.completions.create(
+ messages=[
+ {"role": "user", "content": PROMPT},
+ ],
+ model="gpt-4o-mini",
+ user=USER_ID,
+ tools=[TOOL_NAME],
+ tool_choice="generate",
+)
+print(response.choices[0].message.content)
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_call_tool.js b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_call_tool.js
new file mode 100644
index 000000000..9288123ab
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "you@example.com";
+const TOOL_NAME = "Google.SearchContactsByEmail";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({
+ tool_name: TOOL_NAME,
+ user_id: USER_ID,
+});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ email: "john.doe@example.com",
+ limit: 30,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(response);
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_call_tool.py b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_call_tool.py
new file mode 100644
index 000000000..0ca47a20f
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_call_tool.py
@@ -0,0 +1,29 @@
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "you@example.com"
+TOOL_NAME = "Google.SearchContactsByEmail"
+
+auth_response = client.tools.authorize(
+ tool_name=TOOL_NAME,
+ user_id=USER_ID,
+)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "email": "john.doe@example.com",
+ "limit": 30,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(response)
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_llm_oai.js b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_llm_oai.js
new file mode 100644
index 000000000..8b071a635
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_llm_oai.js
@@ -0,0 +1,22 @@
+import OpenAI from 'openai';
+
+const USER_ID = "you@example.com";
+const PROMPT = "Do i have any contacts with the email john.doe@example.com? If so get info on them.";
+const TOOL_NAME = "Google.SearchContactsByEmail";
+
+const client = new OpenAI({
+ baseURL: 'https://api.arcade.dev',
+ apiKey: process.env.ARCADE_API_KEY
+});
+
+const response = await client.chat.completions.create({
+ messages: [
+ { role: 'user', content: PROMPT }
+ ],
+ model: 'gpt-4o-mini',
+ user: USER_ID,
+ tools: [TOOL_NAME],
+ tool_choice: 'generate'
+});
+
+console.log(response.choices[0].message.content);
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_llm_oai.py b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_llm_oai.py
new file mode 100644
index 000000000..0b60f7d1a
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_email_example_llm_oai.py
@@ -0,0 +1,21 @@
+import os
+from openai import OpenAI
+
+USER_ID = "you@example.com"
+PROMPT = "Do I have any contacts with the email john.doe@example.com? If so get info on them."
+TOOL_NAME = "Google.SearchContactsByEmail"
+
+client = OpenAI(
+ base_url="https://api.arcade.dev", api_key=os.environ.get("ARCADE_API_KEY")
+)
+
+response = client.chat.completions.create(
+ messages=[
+ {"role": "user", "content": PROMPT},
+ ],
+ model="gpt-4o-mini",
+ user=USER_ID,
+ tools=[TOOL_NAME],
+ tool_choice="generate",
+)
+print(response.choices[0].message.content)
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_call_tool.js b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_call_tool.js
new file mode 100644
index 000000000..458c3b570
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "you@example.com";
+const TOOL_NAME = "Google.SearchContactsByName";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({
+ tool_name: TOOL_NAME,
+ user_id: USER_ID,
+});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ name: "John Doe",
+ limit: 30,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(response);
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_call_tool.py b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_call_tool.py
new file mode 100644
index 000000000..d36ed45dd
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_call_tool.py
@@ -0,0 +1,29 @@
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "you@example.com"
+TOOL_NAME = "Google.SearchContactsByName"
+
+auth_response = client.tools.authorize(
+ tool_name=TOOL_NAME,
+ user_id=USER_ID,
+)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "name": "John Doe",
+ "limit": 30,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(response)
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_llm_oai.js b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_llm_oai.js
new file mode 100644
index 000000000..d567ca607
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_llm_oai.js
@@ -0,0 +1,22 @@
+import OpenAI from 'openai';
+
+const USER_ID = "you@example.com";
+const PROMPT = "Search my contacts for John Doe.";
+const TOOL_NAME = "Google.SearchContactsByName";
+
+const client = new OpenAI({
+ baseURL: 'https://api.arcade.dev',
+ apiKey: process.env.ARCADE_API_KEY
+});
+
+const response = await client.chat.completions.create({
+ messages: [
+ { role: 'user', content: PROMPT }
+ ],
+ model: 'gpt-4o-mini',
+ user: USER_ID,
+ tools: [TOOL_NAME],
+ tool_choice: 'generate'
+});
+
+console.log(response.choices[0].message.content);
diff --git a/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_llm_oai.py b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_llm_oai.py
new file mode 100644
index 000000000..2d3ea2366
--- /dev/null
+++ b/public/examples/integrations/toolkits/google/contacts/search_contacts_by_name_example_llm_oai.py
@@ -0,0 +1,21 @@
+import os
+from openai import OpenAI
+
+USER_ID = "you@example.com"
+PROMPT = "Search my contacts for John Doe."
+TOOL_NAME = "Google.SearchContactsByName"
+
+client = OpenAI(
+ base_url="https://api.arcade.dev", api_key=os.environ.get("ARCADE_API_KEY")
+)
+
+response = client.chat.completions.create(
+ messages=[
+ {"role": "user", "content": PROMPT},
+ ],
+ model="gpt-4o-mini",
+ user=USER_ID,
+ tools=[TOOL_NAME],
+ tool_choice="generate",
+)
+print(response.choices[0].message.content)
diff --git a/public/images/icons/google_contacts.png b/public/images/icons/google_contacts.png
new file mode 100644
index 000000000..10dceaa8c
Binary files /dev/null and b/public/images/icons/google_contacts.png differ
diff --git a/src/components/custom/Toolkits/toolkits-config.ts b/src/components/custom/Toolkits/toolkits-config.ts
index 361694cb3..f6c6f5451 100644
--- a/src/components/custom/Toolkits/toolkits-config.ts
+++ b/src/components/custom/Toolkits/toolkits-config.ts
@@ -67,6 +67,14 @@ export const tools: Tool[] = [
category: "productivity",
type: "arcade",
},
+ {
+ name: "Google Contacts",
+ image: "google_contacts",
+ summary: "Create and search contacts in Google Contacts with your agents.",
+ link: "/toolkits/productivity/google/contacts",
+ category: "productivity",
+ type: "arcade",
+ },
{
name: "Google Drive",
image: "google_drive",