Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 164 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,74 @@ yarn add @stackone/ai

# Using pnpm
pnpm add @stackone/ai

# Using bun
bun add @stackone/ai
```

### Optional: AI SDK Integration
## Usage

If you plan to use the AI SDK integration (Vercel AI SDK), install it separately:
```typescript
import { StackOneToolSet } from "@stackone/ai";

```bash
# Using npm
npm install ai
const toolset = new StackOneToolSet({
baseUrl: "https://api.stackone.com",
accountId: "your-account-id",
});

# Using yarn
yarn add ai
const tools = await toolset.fetchTools();
const employeeTool = tools.getTool("bamboohr_list_employees");
const employees = await employeeTool.execute();
```

# Using pnpm
pnpm add ai
### Authentication

Set the `STACKONE_API_KEY` environment variable:

```bash
export STACKONE_API_KEY=<your-api-key>
```

## Development Environment
or load from a .env file using your preferred environment variable library.

### Using Nix Flake
### Account IDs

This project includes a Nix flake for reproducible development environments. If you have Nix installed with flakes enabled, you can use it to set up your development environment:
StackOne uses account IDs to identify different integrations. You can specify the account ID at different levels:

```bash
# Enter development shell
nix develop
```typescript
import { StackOneToolSet } from "@stackone/ai";

# Or use direnv for automatic activation
echo "use flake" > .envrc
direnv allow
```
// Single account - simplest approach
const toolset = new StackOneToolSet({ accountId: "your-bamboohr-account" });
const tools = await toolset.fetchTools();

The flake provides all necessary development dependencies including Node.js, pnpm, and other build tools.
// Multiple accounts - returns tools from both integrations
const multiAccountToolset = new StackOneToolSet();
const allTools = await multiAccountToolset.fetchTools({
accountIds: ["bamboohr-account-123", "workday-account-456"],
});

// Filter to specific integration when using multiple accounts
const bamboohrOnly = await multiAccountToolset.fetchTools({
accountIds: ["bamboohr-account-123", "workday-account-456"],
actions: ["bamboohr_*"], // Only BambooHR tools
});

// Set directly on a tool instance
tools.setAccountId("direct-account-id");
const currentAccountId = tools.getAccountId(); // Get the current account ID
```

## Integrations

The StackOneToolSet makes it super easy to use StackOne APIs as tools in your AI applications.

### With OpenAI library
<details>
<summary><strong>With OpenAI Chat Completions API</strong></summary>

```bash
npm install @stackone/ai openai # or: yarn/pnpm/bun add
```

```typescript
import { OpenAI } from "openai";
Expand Down Expand Up @@ -90,7 +119,84 @@ await openai.chat.completions.create({

[View full example](examples/openai-integration.ts)

### AI SDK by Vercel
</details>

<details>
<summary><strong>With OpenAI Responses API</strong></summary>

```bash
npm install @stackone/ai openai # or: yarn/pnpm/bun add
```

```typescript
import OpenAI from "openai";
import { StackOneToolSet } from "@stackone/ai";

const toolset = new StackOneToolSet({
baseUrl: "https://api.stackone.com",
accountId: "your-account-id",
});

const tools = await toolset.fetchTools();

const openai = new OpenAI();

await openai.responses.create({
model: "gpt-5.1",
instructions: "You are a helpful HR assistant.",
input: "What is the phone number for employee c28xIQ?",
tools: tools.toOpenAIResponses(),
});
```

[View full example](examples/openai-responses-integration.ts)

</details>

<details>
<summary><strong>With Anthropic Claude</strong></summary>

```bash
npm install @stackone/ai @anthropic-ai/sdk # or: yarn/pnpm/bun add
```

```typescript
import Anthropic from "@anthropic-ai/sdk";
import { StackOneToolSet } from "@stackone/ai";

const toolset = new StackOneToolSet({
baseUrl: "https://api.stackone.com",
accountId: "your-account-id",
});

const tools = await toolset.fetchTools();

const anthropic = new Anthropic();

await anthropic.messages.create({
model: "claude-haiku-4-5-20241022",
max_tokens: 1024,
system: "You are a helpful HR assistant.",
messages: [
{
role: "user",
content: "What is the phone number for employee c28xIQ?",
},
],
tools: tools.toAnthropic(),
});
```

[View full example](examples/anthropic-integration.ts)

</details>

<details>
<summary><strong>With AI SDK by Vercel</strong></summary>

```bash
npm install @stackone/ai ai @ai-sdk/openai # or: yarn/pnpm/bun add
```

```typescript
import { openai } from "@ai-sdk/openai";
Expand All @@ -113,7 +219,14 @@ await generateText({

[View full example](examples/ai-sdk-integration.ts)

### TanStack AI
</details>

<details>
<summary><strong>With TanStack AI</strong></summary>

```bash
npm install @stackone/ai @tanstack/ai @tanstack/ai-openai zod # or: yarn/pnpm/bun add
```

```typescript
import { chat } from "@tanstack/ai";
Expand Down Expand Up @@ -144,7 +257,7 @@ const getEmployeeTool = {
const adapter = openai();
const stream = chat({
adapter,
model: "gpt-4o",
model: "gpt-5.1",
messages: [{ role: "user", content: "Get employee with id: abc123" }],
tools: [getEmployeeTool],
});
Expand All @@ -156,7 +269,14 @@ for await (const chunk of stream) {

[View full example](examples/tanstack-ai-integration.ts)

### Claude Agent SDK
</details>

<details>
<summary><strong>With Claude Agent SDK</strong></summary>

```bash
npm install @stackone/ai @anthropic-ai/claude-agent-sdk zod # or: yarn/pnpm/bun add
```

```typescript
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
Expand Down Expand Up @@ -207,58 +327,7 @@ for await (const message of result) {

[View full example](examples/claude-agent-sdk-integration.ts)

## Usage

```typescript
import { StackOneToolSet } from "@stackone/ai";

const toolset = new StackOneToolSet({
baseUrl: "https://api.stackone.com",
accountId: "your-account-id",
});

const tools = await toolset.fetchTools();
const employeeTool = tools.getTool("bamboohr_list_employees");
const employees = await employeeTool.execute();
```

### Authentication

Set the `STACKONE_API_KEY` environment variable:

```bash
export STACKONE_API_KEY=<your-api-key>
```

or load from a .env file using your preferred environment variable library.

### Account IDs

StackOne uses account IDs to identify different integrations. You can specify the account ID at different levels:

```typescript
import { StackOneToolSet } from "@stackone/ai";

// Single account - simplest approach
const toolset = new StackOneToolSet({ accountId: "your-bamboohr-account" });
const tools = await toolset.fetchTools();

// Multiple accounts - returns tools from both integrations
const multiAccountToolset = new StackOneToolSet();
const allTools = await multiAccountToolset.fetchTools({
accountIds: ["bamboohr-account-123", "workday-account-456"],
});

// Filter to specific integration when using multiple accounts
const bamboohrOnly = await multiAccountToolset.fetchTools({
accountIds: ["bamboohr-account-123", "workday-account-456"],
actions: ["bamboohr_*"], // Only BambooHR tools
});

// Set directly on a tool instance
tools.setAccountId("direct-account-id");
const currentAccountId = tools.getAccountId(); // Get the current account ID
```
</details>

## Features

Expand Down Expand Up @@ -306,7 +375,7 @@ This is especially useful when you want to:

Meta tools enable dynamic tool discovery and execution, allowing AI agents to search for relevant tools based on natural language queries without hardcoding tool names.

> ⚠️ **Beta Feature**: Meta tools are currently in beta and the API may change in future versions.
> **Beta Feature**: Meta tools are currently in beta and the API may change in future versions.

#### How Meta Tools Work

Expand Down Expand Up @@ -382,8 +451,6 @@ import { StackOneToolSet } from "@stackone/ai";
const toolset = new StackOneToolSet({ baseUrl: "https://api.example-dev.com" });
```

[View full example](examples/custom-base-url.ts)

### Testing with dryRun

You can use the `dryRun` option to return the api arguments from a tool call without making the actual api call:
Expand Down Expand Up @@ -528,3 +595,20 @@ When AI agents use this tool, they will:
5. **Report results**: Show which accounts received the feedback successfully

The tool description includes clear instructions for AI agents to always ask for explicit user consent before submitting feedback.

## Development Environment

### Using Nix Flake

This project includes a Nix flake for reproducible development environments. If you have Nix installed with flakes enabled, you can use it to set up your development environment:

```bash
# Enter development shell
nix develop

# Or use direnv for automatic activation
echo "use flake" > .envrc
direnv allow
```

The flake provides all necessary development dependencies including Node.js, pnpm, and other build tools.
2 changes: 1 addition & 1 deletion examples/tanstack-ai-integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const tanstackAiIntegration = async (): Promise<void> => {
const adapter = openai();
const stream = chat({
adapter,
model: 'gpt-4o',
model: 'gpt-5.1',
messages: [
{
role: 'user',
Expand Down
Loading