diff --git a/README.md b/README.md
index 9f2b26d..d64b9a2 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,14 @@ yarn gen:keys
 
 > See all the available [examples](/examples/).
 
+### Integrations
+
+Examples integrating XMTP with external libraries from the ecosystem
+
+- [grok](/integrations/grok/): Integrate XMTP to the Grok API
+
+> See all the available [examples](/integrations/).
+
 ## Web inbox
 
 Interact with the XMTP network using [xmtp.chat](https://xmtp.chat), the official web inbox for developers.
diff --git a/examples/gpt/index.ts b/examples/gpt/index.ts
index c02fc3f..44c400e 100644
--- a/examples/gpt/index.ts
+++ b/examples/gpt/index.ts
@@ -47,7 +47,7 @@ async function main() {
   await client.conversations.sync();
 
   console.log(
-    `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`,
+    `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`,
   );
 
   console.log("Waiting for messages...");
diff --git a/integrations/grok/.env.example b/integrations/grok/.env.example
new file mode 100644
index 0000000..9eeda7f
--- /dev/null
+++ b/integrations/grok/.env.example
@@ -0,0 +1,5 @@
+WALLET_KEY= # the private key of the wallet
+ENCRYPTION_KEY= # a second random 32 bytes encryption key for local db encryption
+
+# grok api key
+GROK_API_KEY= # the API key for the Grok API
diff --git a/integrations/grok/README.md b/integrations/grok/README.md
new file mode 100644
index 0000000..87c8797
--- /dev/null
+++ b/integrations/grok/README.md
@@ -0,0 +1,158 @@
+# Grok agent example
+
+This example uses the [Grok](https://x.ai/api) API for responses and [XMTP](https://xmtp.org) for secure messaging. You can test your agent on [xmtp.chat](https://xmtp.chat) or any other XMTP-compatible client.
+
+## Environment variables
+
+Add the following keys to a `.env` file:
+
+```bash
+WALLET_KEY= # the private key of the wallet
+ENCRYPTION_KEY= # a second random 32 bytes encryption key for local db encryption
+GROK_API_KEY= # the API key for the Grok API
+```
+
+You can generate random keys with the following command:
+
+```bash
+yarn gen:keys
+```
+
+> [!WARNING]
+> Running the `gen:keys` script will overwrite the existing `.env` file.
+
+## Usage
+
+```tsx
+import { Client, type XmtpEnv } from "@xmtp/node-sdk";
+import { createSigner, getEncryptionKeyFromHex } from "@/helpers";
+
+/* Get the wallet key associated to the public key of
+ * the agent and the encryption key for the local db
+ * that stores your agent's messages */
+const { WALLET_KEY, ENCRYPTION_KEY, GROK_API_KEY } = process.env;
+
+/* Check if the environment variables are set */
+if (!WALLET_KEY) {
+  throw new Error("WALLET_KEY must be set");
+}
+
+/* Check if the encryption key is set */
+if (!ENCRYPTION_KEY) {
+  throw new Error("ENCRYPTION_KEY must be set");
+}
+
+/* Check if the Grok API key is set */
+if (!GROK_API_KEY) {
+  throw new Error("GROK_API_KEY must be set");
+}
+
+/* Create the signer using viem and parse the encryption key for the local db */
+const signer = createSigner(WALLET_KEY);
+const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY);
+
+/* Set the environment to dev or production */
+const env: XmtpEnv = "dev";
+
+/**
+ * Main function to run the agent
+ */
+async function main() {
+  console.log(`Creating client on the '${env}' network...`);
+  /* Initialize the xmtp client */
+  const client = await Client.create(signer, encryptionKey, {
+    env,
+  });
+
+  console.log("Syncing conversations...");
+  /* Sync the conversations from the network to update the local db */
+  await client.conversations.sync();
+
+  console.log(
+    `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`,
+  );
+  console.log("Waiting for messages...");
+  /* Stream all messages from the network */
+  const stream = client.conversations.streamAllMessages();
+
+  for await (const message of await stream) {
+    /* Ignore messages from the same agent or non-text messages */
+    if (
+      message?.senderInboxId.toLowerCase() === client.inboxId.toLowerCase() ||
+      message?.contentType?.typeId !== "text"
+    ) {
+      continue;
+    }
+
+    console.log(
+      `Received message: ${message.content as string} by ${message.senderInboxId}`,
+    );
+
+    /* Get the conversation from the local db */
+    const conversation = client.conversations.getConversationById(
+      message.conversationId,
+    );
+
+    /* If the conversation is not found, skip the message */
+    if (!conversation) {
+      console.log("Unable to find conversation, skipping");
+      continue;
+    }
+
+    try {
+      /* Get the AI response from Grok */
+      const response = await fetch("https://api.x.ai/v1/chat/completions", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+          Authorization: `Bearer ${GROK_API_KEY}`, // Use the same API key variable
+        },
+        body: JSON.stringify({
+          messages: [
+            { role: "system", content: "You are a test assistant." },
+            { role: "user", content: message.content as string },
+          ],
+          model: "grok-2-latest",
+          stream: false,
+          temperature: 0,
+        }),
+      }).then(
+        (res) =>
+          res.json() as Promise<{
+            choices: { message: { content: string } }[];
+          }>,
+      );
+      const aiResponse = response.choices[0]?.message?.content || "";
+      console.log(`Sending AI response: ${aiResponse}`);
+      /* Send the AI response to the conversation */
+      await conversation.send(aiResponse);
+    } catch (error) {
+      console.error("Error getting AI response:", error);
+      await conversation.send(
+        "Sorry, I encountered an error processing your message.",
+      );
+    }
+
+    console.log("Waiting for messages...");
+  }
+}
+
+main().catch(console.error);
+```
+
+## Run the agent
+
+```bash
+# git clone repo
+git clone https://github.com/ephemeraHQ/xmtp-agent-examples.git
+# go to the folder
+cd xmtp-agent-examples
+cd integrations
+cd grok
+# install packages
+yarn
+# generate random keys (optional)
+yarn gen:keys
+# run the example
+yarn dev
+```
diff --git a/integrations/grok/index.ts b/integrations/grok/index.ts
new file mode 100644
index 0000000..cbac903
--- /dev/null
+++ b/integrations/grok/index.ts
@@ -0,0 +1,114 @@
+import { Client, type XmtpEnv } from "@xmtp/node-sdk";
+import { createSigner, getEncryptionKeyFromHex } from "@/helpers";
+
+/* Get the wallet key associated to the public key of
+ * the agent and the encryption key for the local db
+ * that stores your agent's messages */
+const { WALLET_KEY, ENCRYPTION_KEY, GROK_API_KEY } = process.env;
+
+/* Check if the environment variables are set */
+if (!WALLET_KEY) {
+  throw new Error("WALLET_KEY must be set");
+}
+
+/* Check if the encryption key is set */
+if (!ENCRYPTION_KEY) {
+  throw new Error("ENCRYPTION_KEY must be set");
+}
+
+/* Check if the Grok API key is set */
+if (!GROK_API_KEY) {
+  throw new Error("GROK_API_KEY must be set");
+}
+
+/* Create the signer using viem and parse the encryption key for the local db */
+const signer = createSigner(WALLET_KEY);
+const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY);
+
+/* Set the environment to dev or production */
+const env: XmtpEnv = "dev";
+
+/**
+ * Main function to run the agent
+ */
+async function main() {
+  console.log(`Creating client on the '${env}' network...`);
+  /* Initialize the xmtp client */
+  const client = await Client.create(signer, encryptionKey, {
+    env,
+  });
+
+  console.log("Syncing conversations...");
+  /* Sync the conversations from the network to update the local db */
+  await client.conversations.sync();
+
+  console.log(
+    `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`,
+  );
+  console.log("Waiting for messages...");
+  /* Stream all messages from the network */
+  const stream = client.conversations.streamAllMessages();
+
+  for await (const message of await stream) {
+    /* Ignore messages from the same agent or non-text messages */
+    if (
+      message?.senderInboxId.toLowerCase() === client.inboxId.toLowerCase() ||
+      message?.contentType?.typeId !== "text"
+    ) {
+      continue;
+    }
+
+    console.log(
+      `Received message: ${message.content as string} by ${message.senderInboxId}`,
+    );
+
+    /* Get the conversation from the local db */
+    const conversation = client.conversations.getConversationById(
+      message.conversationId,
+    );
+
+    /* If the conversation is not found, skip the message */
+    if (!conversation) {
+      console.log("Unable to find conversation, skipping");
+      continue;
+    }
+
+    try {
+      /* Get the AI response from Grok */
+      const response = await fetch("https://api.x.ai/v1/chat/completions", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+          Authorization: `Bearer ${GROK_API_KEY}`, // Use the same API key variable
+        },
+        body: JSON.stringify({
+          messages: [
+            { role: "system", content: "You are a test assistant." },
+            { role: "user", content: message.content as string },
+          ],
+          model: "grok-2-latest",
+          stream: false,
+          temperature: 0,
+        }),
+      }).then(
+        (res) =>
+          res.json() as Promise<{
+            choices: { message: { content: string } }[];
+          }>,
+      );
+      const aiResponse = response.choices[0]?.message?.content || "";
+      console.log(`Sending AI response: ${aiResponse}`);
+      /* Send the AI response to the conversation */
+      await conversation.send(aiResponse);
+    } catch (error) {
+      console.error("Error getting AI response:", error);
+      await conversation.send(
+        "Sorry, I encountered an error processing your message.",
+      );
+    }
+
+    console.log("Waiting for messages...");
+  }
+}
+
+main().catch(console.error);
diff --git a/integrations/grok/package.json b/integrations/grok/package.json
new file mode 100644
index 0000000..f1de7e0
--- /dev/null
+++ b/integrations/grok/package.json
@@ -0,0 +1,20 @@
+{
+  "name": "@integrations/gpt",
+  "version": "0.0.0",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "tsx --env-file=.env index.ts",
+    "gen:keys": "tsx ../../scripts/generateKeys.ts"
+  },
+  "dependencies": {
+    "@xmtp/node-sdk": "0.0.42",
+    "tsx": "^4.19.2",
+    "uint8arrays": "^5.1.0",
+    "viem": "^2.22.17"
+  },
+  "packageManager": "yarn@4.6.0",
+  "engines": {
+    "node": ">=20"
+  }
+}
diff --git a/package.json b/package.json
index 2ee4d6d..c963392 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,10 @@
   "version": "0.0.0",
   "private": true,
   "type": "module",
+  "workspaces": [
+    "examples/*",
+    "integrations/*"
+  ],
   "scripts": {
     "clean": "rimraf node_modules && yarn clean:dbs",
     "clean:dbs": "rimraf *.db3* ||:",
@@ -16,8 +20,7 @@
     "typecheck": "tsc"
   },
   "dependencies": {
-    "@xmtp/content-type-text": "^2.0.0",
-    "@xmtp/node-sdk": "0.0.40",
+    "@xmtp/node-sdk": "0.0.42",
     "alchemy-sdk": "^3.0.0",
     "openai": "latest",
     "tsx": "^4.19.2",
diff --git a/scripts/generateKeys.ts b/scripts/generateKeys.ts
index 6396c02..d49280a 100644
--- a/scripts/generateKeys.ts
+++ b/scripts/generateKeys.ts
@@ -1,23 +1,20 @@
 import { writeFile } from "node:fs/promises";
-import { dirname, join } from "node:path";
-import { fileURLToPath } from "node:url";
+import { join } from "node:path";
 import { generatePrivateKey } from "viem/accounts";
 import { generateEncryptionKeyHex } from "@/helpers";
 
-const __dirname = dirname(fileURLToPath(import.meta.url));
-
 console.log("Generating keys...");
 
 const walletKey = generatePrivateKey();
 const encryptionKeyHex = generateEncryptionKeyHex();
 
-const envFilePath = join(__dirname, "../.env");
+const filePath = join(process.cwd(), ".env");
 
 await writeFile(
-  envFilePath,
+  filePath,
   `WALLET_KEY=${walletKey}
 ENCRYPTION_KEY=${encryptionKeyHex}
 `,
 );
 
-console.log(`Keys written to ${envFilePath}`);
+console.log(`Keys written to ${filePath}`);
diff --git a/yarn.lock b/yarn.lock
index f1a0992..6f159de 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -808,6 +808,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@integrations/gpt@workspace:integrations/grok":
+  version: 0.0.0-use.local
+  resolution: "@integrations/gpt@workspace:integrations/grok"
+  dependencies:
+    "@xmtp/node-sdk": "npm:0.0.42"
+    tsx: "npm:^4.19.2"
+    uint8arrays: "npm:^5.1.0"
+    viem: "npm:^2.22.17"
+  languageName: unknown
+  linkType: soft
+
 "@isaacs/cliui@npm:^8.0.2":
   version: 8.0.2
   resolution: "@isaacs/cliui@npm:8.0.2"
@@ -1263,23 +1274,23 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@xmtp/node-bindings@npm:^0.0.34":
-  version: 0.0.34
-  resolution: "@xmtp/node-bindings@npm:0.0.34"
-  checksum: 10/4f5314d40dc1f07e303e52a4be1d4517f1199089b4ac1677fabb11f64a6b4f57a989b25849b31036d6d228e9de494a8326d2b53386067146ee47e28691bba999
+"@xmtp/node-bindings@npm:^0.0.37":
+  version: 0.0.37
+  resolution: "@xmtp/node-bindings@npm:0.0.37"
+  checksum: 10/06d12ee27f306a2ad767b75eedf3ceb0457cab3f574a545f44e487cbb39d07a3866c81277954a4937dc1f048a75c10b34b5ffa5de4fc43eaf9b1310a1c4dce8a
   languageName: node
   linkType: hard
 
-"@xmtp/node-sdk@npm:0.0.40":
-  version: 0.0.40
-  resolution: "@xmtp/node-sdk@npm:0.0.40"
+"@xmtp/node-sdk@npm:0.0.42":
+  version: 0.0.42
+  resolution: "@xmtp/node-sdk@npm:0.0.42"
   dependencies:
     "@xmtp/content-type-group-updated": "npm:^2.0.0"
     "@xmtp/content-type-primitives": "npm:^2.0.0"
     "@xmtp/content-type-text": "npm:^2.0.0"
-    "@xmtp/node-bindings": "npm:^0.0.34"
+    "@xmtp/node-bindings": "npm:^0.0.37"
     "@xmtp/proto": "npm:^3.72.3"
-  checksum: 10/eeed6072513dbf1c5ed7f0cfb9d5876c086d648b3fe93d757f0fefa87d03312a8aa5b3f3256b27339b37bbddf75c604eade1480a643909e04dc3865903915b2f
+  checksum: 10/6163ede6d9cd7bc36b3a237d9a63a8be0041a11a1eefc6f56fefbf7cb8b8cc02c817c4696996a29a4f296d7545fd3172d8ebf8f85e1aeb23dcff917719dfcd10
   languageName: node
   linkType: hard
 
@@ -3820,8 +3831,7 @@ __metadata:
     "@ianvs/prettier-plugin-sort-imports": "npm:^4.4.1"
     "@types/eslint__js": "npm:^8.42.3"
     "@types/node": "npm:^22.13.0"
-    "@xmtp/content-type-text": "npm:^2.0.0"
-    "@xmtp/node-sdk": "npm:0.0.40"
+    "@xmtp/node-sdk": "npm:0.0.42"
     alchemy-sdk: "npm:^3.0.0"
     eslint: "npm:^9.19.0"
     eslint-config-prettier: "npm:^10.0.1"