Skip to content

Commit 128fd89

Browse files
nikosdouvlisanagstefLekoArts
authoredFeb 12, 2025
feat(agent-toolkit): Introduce @clerk/agent-toolkit package (#5130)
Co-authored-by: Stefanos Anagnostou <anagstef@users.noreply.github.com> Co-authored-by: Lennart <lekoarts@gmail.com>
1 parent dd2cbfe commit 128fd89

26 files changed

+1066
-4
lines changed
 

‎.changeset/many-pumpkins-double.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@clerk/agent-toolkit': patch
3+
---
4+
5+
Introduce `@clerk/agent-toolkit` package. The Clerk Agent Toolkit enables popular agent frameworks, including Vercel's AI SDK and LangChain, to integrate with Clerk using tools (also known as function calling).
6+
7+
This package exposes a subset of Clerk's functionality to agent frameworks, allowing you to build powerful agentic systems capable of managing users, user data, organizations, and more.
8+
9+
**Please note:** All relevant information and instructions on how to set it up can be found in the package's README. It's an early developer preview and can't be considered stable yet.
10+

‎.changeset/metal-gorillas-fetch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/backend': patch
3+
---
4+
5+
Adds an internal `raw()` getter method to the `User` resource that returns the raw JSON payload of the request that instantiated the resource.

‎.github/labeler.yml

+3
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,6 @@ actions:
6565

6666
integration:
6767
- integration/**
68+
69+
agent-toolkit:
70+
- packages/agent-toolkit/**

‎packages/agent-toolkit/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Clerk, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎packages/agent-toolkit/README.md

+230
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<p align="center">
2+
<a href="https://clerk.com?utm_source=github&utm_medium=clerk_agent_toolkit" target="_blank" rel="noopener noreferrer">
3+
<picture>
4+
<source media="(prefers-color-scheme: dark)" srcset="https://images.clerk.com/static/logo-dark-mode-400x400.png">
5+
<img src="https://images.clerk.com/static/logo-light-mode-400x400.png" height="64">
6+
</picture>
7+
</a>
8+
<br />
9+
<h1 align="center">@clerk/agent-toolkit</h1>
10+
</p>
11+
12+
<div align="center">
13+
14+
[![Chat on Discord](https://img.shields.io/discord/856971667393609759.svg?logo=discord)](https://clerk.com/discord)
15+
[![Clerk documentation](https://img.shields.io/badge/documentation-clerk-green.svg)](https://clerk.com/docs?utm_source=github&utm_medium=clerk_agent_toolkit)
16+
[![Follow on Twitter](https://img.shields.io/twitter/follow/ClerkDev?style=social)](https://twitter.com/intent/follow?screen_name=ClerkDev)
17+
18+
[Changelog](https://github.com/clerk/javascript/blob/main/packages/agent-toolkit/CHANGELOG.md)
19+
·
20+
[Report a Bug](https://github.com/clerk/javascript/issues/new?assignees=&labels=needs-triage&projects=&template=BUG_REPORT.yml)
21+
·
22+
[Request a Feature](https://feedback.clerk.com/roadmap)
23+
·
24+
[Get Help](https://clerk.com/contact/support?utm_source=github&utm_medium=clerk_agent_toolkit)
25+
26+
</div>
27+
28+
> [!IMPORTANT]
29+
>
30+
> Agent behavior is typically non-deterministic. Ensure you thoroughly test your integration and evaluate your application's performance. Additionally, consider scoping this toolkit's tools to specific users to limit resource access.
31+
>
32+
> If your app's code path is predetermined, it's always preferable to call APIs directly instead of using agents and tool calling.
33+
>
34+
> This SDK is recommended for testing purposes only unless you are confident in the agent's behavior and have implemented necessary security measures such as guardrails and best practices.
35+
36+
## Table of Contents
37+
38+
1. [Getting Started](#getting-started)
39+
2. [Public APIs](#public-apis)
40+
3. [Use with Vercel's AI SDK](#use-with-vercels-ai-sdk)
41+
4. [Use with Langchain](#use-with-langchain)
42+
5. [Advanced Usage](#advanced-usage)
43+
6. [Support](#support)
44+
45+
## Getting Started
46+
47+
Use this SDK to integrate [Clerk](https://clerk.com/?utm_source=github&utm_medium=clerk_agent_toolkit) into your agentic workflows. The Clerk Agent Toolkit enables popular agent frameworks, including Vercel's AI SDK and LangChain, to integrate with Clerk using tools (also known as function calling).
48+
49+
This package exposes a subset of Clerk's functionality to agent frameworks, allowing you to build powerful agentic systems capable of managing users, user data, organizations, and more.
50+
51+
## Public APIs
52+
53+
The Clerk Agent Toolkit package provides two main import paths:
54+
55+
- `@clerk/agent-toolkit/ai-sdk`: Helpers for integrating with Vercel's AI SDK.
56+
- `@clerk/agent-toolkit/langchain`: Helpers for integrating with Langchain.
57+
58+
The toolkit offers the same tools and core APIs across frameworks, but their public interfaces may vary slightly to align with each framework's design:
59+
60+
- `createClerkToolkit(options)`: Instantiates a new Clerk toolkit.
61+
- `toolkit.injectSessionClaims(systemPrompt)`: Injects session claims (`userId`, `sessionId`, `orgId`, etc.) into the system prompt, making them accessible to the AI model.
62+
- `toolkit.users()`: Provides tools for managing users.
63+
- `toolkit.organizations()`: Provides tools for managing organizations.
64+
- `toolkit.allTools()`: Returns all available tools.
65+
- `toolkit.toolMap()`: **(Langchain only)** Returns an object mapping available tools, useful for calling tools by name.
66+
67+
For more details on each tool, refer to the framework-specific directories or the [Clerk Backend API documentation](https://clerk.com/docs/reference/backend-api).
68+
69+
### Prerequisites
70+
71+
- `ai-sdk`: `"^3.4.7 || ^4.0.0"`, or `langchain`: `"^0.3.6"`
72+
- An existing Clerk application. [Create your account for free](https://dashboard.clerk.com/sign-up?utm_source=github&utm_medium=clerk_agent_toolkit).
73+
- An API key for an AI model compatible with Langchain
74+
75+
### Example Repository
76+
77+
- [Clerk AI SDK Example](https://github.com/clerk/agent-toolkit-example)
78+
79+
## Using Vercel's AI SDK
80+
81+
1. Install the Clerk Agent Toolkit package:
82+
83+
```shell
84+
npm install @clerk/agent-toolkit
85+
```
86+
87+
2. Set the Clerk secret key as an environment variable in your project. Ensure you also configure any required LLM model keys.
88+
89+
```
90+
CLERK_SECRET_KEY=sk_
91+
```
92+
93+
3. Import the helper from the `/ai-sdk` path, instantiate a new Clerk `toolkit`, and use it in your agent function:
94+
95+
```typescript
96+
// Import the helper from the ai-sdk path
97+
import { createClerkToolkit } from '@clerk/agent-toolkit/ai-sdk';
98+
import { openai } from '@ai-sdk/openai';
99+
import { streamText } from 'ai';
100+
import { auth } from '@clerk/nextjs/server';
101+
import { systemPrompt } from '@/lib/ai/prompts';
102+
103+
export const maxDuration = 30;
104+
105+
export async function POST(req: Request) {
106+
const { messages } = await req.json();
107+
// Optional - get the userId from the request
108+
const { userId } = await auth.protect();
109+
110+
// Instantiate a new Clerk toolkit
111+
// Optional - scope the toolkit to a specific user
112+
const toolkit = await createClerkToolkit({ context: { userId } });
113+
114+
const result = streamText({
115+
model: openai('gpt-4o'),
116+
messages,
117+
// Optional - inject session claims into the system prompt
118+
system: toolkit.injectSessionClaims(systemPrompt),
119+
tools: {
120+
// Provide the tools you want to use
121+
...toolkit.users(),
122+
...toolkit.organizations(),
123+
},
124+
});
125+
126+
return result.toDataStreamResponse();
127+
}
128+
```
129+
130+
## Using Langchain
131+
132+
1. Install the Clerk Agent Toolkit package:
133+
134+
```shell
135+
npm install @clerk/agent-toolkit
136+
```
137+
138+
2. Set the Clerk secret key as an environment variable:
139+
140+
```shell
141+
CLERK_SECRET_KEY=sk_
142+
```
143+
144+
3. Import the helper from the `/langchain` path, instantiate a new Clerk `toolkit`, and use it in your agent function:
145+
146+
```typescript
147+
// Import the helper from the langchain path
148+
import { createClerkToolkit } from '@clerk/agent-toolkit/langchain';
149+
import { ChatOpenAI } from '@langchain/openai';
150+
import { auth } from '@clerk/nextjs/server';
151+
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
152+
import { LangChainAdapter } from 'ai';
153+
import { systemPrompt } from '@/lib/ai/prompts';
154+
155+
export const maxDuration = 30;
156+
157+
export async function POST(req: Request) {
158+
const { prompt } = await req.json();
159+
const { userId } = await auth.protect();
160+
161+
// Instantiate a new Clerk toolkit
162+
// Optional - scope the toolkit to a specific user
163+
const toolkit = await createClerkToolkit({ context: { userId } });
164+
165+
const model = new ChatOpenAI({ model: 'gpt-4o', temperature: 0 });
166+
167+
// Bind the tools you want to use to the model
168+
const modelWithTools = model.bindTools(toolkit.users());
169+
170+
const messages = [new SystemMessage(toolkit.injectSessionClaims(systemPrompt)), new HumanMessage(prompt)];
171+
const aiMessage = await modelWithTools.invoke(messages);
172+
messages.push(aiMessage);
173+
174+
for (const toolCall of aiMessage.tool_calls || []) {
175+
// Call the selected tool
176+
const selectedTool = toolkit.toolMap()[toolCall.name];
177+
const toolMessage = await selectedTool.invoke(toolCall);
178+
messages.push(toolMessage);
179+
}
180+
181+
// To simplify the setup, this example uses the ai-sdk langchain adapter
182+
// to stream the results back to the /langchain page.
183+
// For more details, see: https://sdk.vercel.ai/providers/adapters/langchain
184+
const stream = await modelWithTools.stream(messages);
185+
return LangChainAdapter.toDataStreamResponse(stream);
186+
}
187+
```
188+
189+
## Advanced Usage
190+
191+
### Using a Custom `clerkClient`
192+
193+
If you need to set the Clerk secret key dynamically or use different Clerk instances, pass a custom `clerkClient`. Install `@clerk/backend` into your project and call the `createClerkClient` function:
194+
195+
```typescript
196+
import { createClerkToolkit } from '@clerk/agent-toolkit/ai-sdk';
197+
import { createClerkClient } from '@clerk/backend';
198+
199+
export async function POST(req: Request) {
200+
// Create a new Clerk client
201+
const clerkClient = createClerkClient({ secretKey: 'sk_' });
202+
203+
// Instantiate a new Clerk toolkit with the custom client
204+
const toolkit = await createClerkToolkit({ clerkClient });
205+
206+
// Use the toolkit as usual
207+
const result = streamText({
208+
model: openai('gpt-4o'),
209+
messages,
210+
tools: toolkit.users(),
211+
});
212+
}
213+
```
214+
215+
## Support
216+
217+
You can get in touch with us in any of the following ways:
218+
219+
- Join our official community [Discord server](https://clerk.com/discord)
220+
- On [our support page](https://clerk.com/contact/support?utm_source=github&utm_medium=clerk_agent_toolkit)
221+
222+
## Contributing
223+
224+
We're open to all community contributions! If you'd like to contribute in any way, please read [our contribution guidelines](https://github.com/clerk/javascript/blob/main/docs/CONTRIBUTING.md) and [code of conduct](https://github.com/clerk/javascript/blob/main/docs/CODE_OF_CONDUCT.md).
225+
226+
## License
227+
228+
This project is licensed under the **MIT license**.
229+
230+
See [LICENSE](https://github.com/clerk/javascript/blob/main/packages/agent-toolkit/LICENSE) for more information.

‎packages/agent-toolkit/package.json

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"name": "@clerk/agent-toolkit",
3+
"version": "0.0.1",
4+
"private": true,
5+
"description": "Clerk Toolkit for AI Agents",
6+
"homepage": "https://clerk.com/",
7+
"bugs": {
8+
"url": "https://github.com/clerk/javascript/issues"
9+
},
10+
"repository": {
11+
"type": "git",
12+
"url": "git+https://github.com/clerk/javascript.git",
13+
"directory": "packages/agent-toolkit"
14+
},
15+
"license": "MIT",
16+
"author": "Clerk",
17+
"sideEffects": false,
18+
"type": "module",
19+
"exports": {
20+
"./langchain": {
21+
"types": "./dist/langchain/index.d.ts",
22+
"import": "./dist/langchain/index.js"
23+
},
24+
"./ai-sdk": {
25+
"types": "./dist/ai-sdk/index.d.ts",
26+
"import": "./dist/ai-sdk/index.js"
27+
}
28+
},
29+
"files": [
30+
"dist"
31+
],
32+
"scripts": {
33+
"build": "tsup --env.NODE_ENV production",
34+
"clean": "rimraf ./dist",
35+
"dev": "tsup --watch",
36+
"lint": "eslint src",
37+
"lint:attw": "attw --pack . --ignore-rules cjs-resolves-to-esm no-resolution",
38+
"lint:publint": "publint"
39+
},
40+
"dependencies": {
41+
"@clerk/backend": "workspace:^",
42+
"@clerk/shared": "workspace:^",
43+
"@clerk/types": "workspace:^",
44+
"zod": "^3.24.1"
45+
},
46+
"devDependencies": {
47+
"esbuild-plugin-file-path-extensions": "^2.1.4"
48+
},
49+
"peerDependencies": {
50+
"@langchain/core": "^0.3.6",
51+
"ai": "^3.4.7 || ^4.0.0"
52+
},
53+
"peerDependenciesMeta": {
54+
"@langchain/core": {
55+
"optional": true
56+
},
57+
"ai": {
58+
"optional": true
59+
}
60+
},
61+
"engines": {
62+
"node": ">=20"
63+
},
64+
"publishConfig": {
65+
"access": "public"
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { Tool } from 'ai';
2+
import { tool } from 'ai';
3+
4+
import type { SdkAdapter } from '../lib/types';
5+
6+
/**
7+
* Converts a `ClerkTool` to an AI SDK `Tool`.
8+
*/
9+
export const adapter: SdkAdapter<Tool> = (clerkClient, context, clerkTool) => {
10+
return tool({
11+
description: clerkTool.description,
12+
parameters: clerkTool.parameters,
13+
execute: clerkTool.bindRunnable(clerkClient, context),
14+
});
15+
};

0 commit comments

Comments
 (0)