@mondaydotcomorg/atp-client
Client library for connecting to Agent Tool Protocol servers and executing code.
Overview
The ATP client enables agents to connect to ATP servers, execute TypeScript code with runtime APIs, handle pauses for LLM/approval/embedding callbacks, and manage client-side tool execution.
Installation
npm install @mondaydotcomorg/atp-client
Architecture
graph TB
Client[AgentToolProtocolClient] --> Session[ClientSession]
Client --> API[APIOperations]
Client --> Exec[ExecutionOperations]
Client --> Services[ServiceProviders]
Services --> LLM[LLM Handler]
Services --> Approval[Approval Handler]
Services --> Embedding[Embedding Handler]
Services --> Tools[Client Tools]
Exec --> Pause[Pause/Resume]
Session --> Hooks[Pre-Request Hooks]
Quick Start
Basic Client
import { AgentToolProtocolClient } from '@mondaydotcomorg/atp-client';
const client = new AgentToolProtocolClient({
baseUrl: 'http://localhost:3333',
headers: {
Authorization: 'Bearer your-api-key',
},
});
await client.init();
const result = await client.execute({
code: `
const items = ['apple', 'banana', 'cherry'];
return items.length;
`,
});
console.log(result.result);
With LLM Support
import { ChatOpenAI } from '@langchain/openai';
const llm = new ChatOpenAI({ modelName: 'gpt-4' });
const client = new AgentToolProtocolClient({
baseUrl: 'http://localhost:3333',
headers: { Authorization: 'Bearer key' },
});
client.provideLLM({
call: async (prompt, options) => {
const response = await llm.invoke(prompt);
return response.content;
},
});
await client.init();
const result = await client.execute({
code: `
const joke = await atp.llm.call({
prompt: 'Tell me a programming joke',
});
return joke;
`,
});
With Embeddings
import { OpenAIEmbeddings } from '@langchain/openai';
const embeddings = new OpenAIEmbeddings();
client.provideEmbedding({
embed: async (text) => {
const vector = await embeddings.embedQuery(text);
return 'embedding-id-123';
},
search: async (query, options) => {
const queryVector = await embeddings.embedQuery(query);
return results;
},
});
const result = await client.execute({
code: `
const id = await atp.embedding.embed('Important document');
const similar = await atp.embedding.search('document', { topK: 5 });
return similar;
`,
});
With Approval Handler
client.provideApproval({
request: async (message, context) => {
const approved = await askUser(message);
return {
approved,
response: { reason: 'User decision' },
timestamp: Date.now(),
};
},
});
const result = await client.execute({
code: `
const approval = await atp.approval.request(
'Delete all files?',
{ critical: true }
);
if (!approval.approved) {
return { cancelled: true };
}
return { deleted: true };
`,
});
Client-Side Tools
Register custom tools that execute on the client:
import { createClientTool } from '@mondaydotcomorg/atp-client';
const fetchTool = createClientTool({
name: 'fetch',
description: 'Make HTTP requests from client',
inputSchema: {
type: 'object',
properties: {
url: { type: 'string' },
method: { type: 'string', enum: ['GET', 'POST'] },
},
required: ['url'],
},
handler: async (input) => {
const response = await fetch(input.url, {
method: input.method || 'GET',
});
return await response.json();
},
});
const client = new AgentToolProtocolClient({
baseUrl: 'http://localhost:3333',
headers: { Authorization: 'Bearer key' },
serviceProviders: {
tools: [fetchTool],
},
});
await client.init();
const result = await client.execute({
code: `
const data = await atp.tool.fetch({
url: 'https://api.example.com/data',
method: 'GET',
});
return data;
`,
});
Pre-Request Hooks
Intercept and modify requests (e.g., token refresh):
const client = new AgentToolProtocolClient({
baseUrl: 'http://localhost:3333',
hooks: {
preRequest: async (context) => {
if (tokenExpired()) {
const newToken = await refreshToken();
return {
headers: {
...context.currentHeaders,
Authorization: `Bearer ${newToken}`,
},
};
}
return {};
},
},
});
Core Features
Execute Code
const result = await client.execute({
code: 'return 1 + 1',
timeout: 30000,
pausable: true,
});
interface ExecutionResult {
status: 'success' | 'error' | 'paused' | 'timeout';
result?: unknown;
error?: string;
pauseReason?: string;
executionId?: string;
}
Search APIs
const results = await client.search({
query: 'user authentication',
limit: 10,
});
const searchResults = await client.searchQuery('how to create a user');
Explore APIs
const schema = await client.explore();
interface ExploreResult {
apis: Array<{
name: string;
description: string;
functions: Array<{
name: string;
description: string;
parameters: unknown;
}>;
}>;
}
Type Definitions
const types = await client.getTypeDefinitions();
API Reference
AgentToolProtocolClient
class AgentToolProtocolClient {
constructor(options: AgentToolProtocolClientOptions);
init(clientInfo?: Record<string, unknown>): Promise<{
clientId: string;
token: string;
expiresAt: number;
tokenRotateAt: number;
}>;
execute(config: ExecutionConfig): Promise<ExecutionResult>;
resume(executionId: string, resumeData: ResumeData): Promise<ExecutionResult>;
provideLLM(handler: ClientLLMHandler): void;
provideApproval(handler: ClientApprovalHandler): void;
provideEmbedding(handler: ClientEmbeddingHandler): void;
search(options: SearchOptions): Promise<SearchResult[]>;
searchQuery(query: string, options?: SearchOptions): Promise<SearchResult[]>;
explore(): Promise<ExploreResult>;
getTypeDefinitions(): Promise<string>;
getClientId(): string;
}
Options
interface AgentToolProtocolClientOptions {
baseUrl: string;
headers?: Record<string, string>;
serviceProviders?: {
llm?: ClientLLMHandler;
approval?: ClientApprovalHandler;
embedding?: ClientEmbeddingHandler;
tools?: ClientTool[];
};
hooks?: {
preRequest?: (context: HookContext) => Promise<HookResult>;
};
}
Flow Diagram
sequenceDiagram
participant Agent
participant Client
participant Server
participant LLM
Agent->>Client: execute(code)
Client->>Server: POST /execute
Server->>Server: Run code
alt Code calls atp.llm.call()
Server->>Client: Pause (LLM callback)
Client->>Agent: Request LLM
Agent->>LLM: API call
LLM-->>Agent: Response
Agent->>Client: Resume with result
Client->>Server: POST /resume
Server->>Server: Continue execution
end
Server-->>Client: Execution result
Client-->>Agent: Return result
Error Handling
import { ExecutionStatus } from '@mondaydotcomorg/atp-client';
try {
const result = await client.execute({ code: '...' });
if (result.status === ExecutionStatus.ERROR) {
console.error('Execution failed:', result.error);
} else if (result.status === ExecutionStatus.TIMEOUT) {
console.error('Execution timed out');
} else if (result.status === ExecutionStatus.PAUSED) {
console.log('Execution paused:', result.pauseReason);
}
} catch (error) {
console.error('Client error:', error);
}
TypeScript Support
Full TypeScript definitions with strict typing for all APIs.
License
MIT