@mondaydotcomorg/atp-providers
Production-ready provider implementations for ATP (cache, auth, OAuth, audit).
Overview
This package provides concrete implementations of ATP provider interfaces including cache backends, authentication providers, OAuth integrations, and audit sinks.
Installation
npm install @mondaydotcomorg/atp-providers
Architecture
graph TB
Providers[Providers Package] --> Cache[Cache Providers]
Providers --> Auth[Auth Providers]
Providers --> OAuth[OAuth Providers]
Providers --> Audit[Audit Sinks]
Cache --> Memory[MemoryCache]
Cache --> Redis[RedisCache]
Cache --> File[FileCache]
Auth --> Env[EnvAuthProvider]
OAuth --> Google[GoogleOAuthProvider]
OAuth --> GitHub[GitHubOAuthProvider]
Audit --> JSONL[JSONLAuditSink]
Audit --> OTel[OpenTelemetryAuditSink]
Cache Providers
MemoryCache
In-memory cache for development and testing.
import { MemoryCache } from '@mondaydotcomorg/atp-providers';
const cache = new MemoryCache({
defaultTTL: 3600,
maxSize: 1000,
});
await cache.set('key', value, 3600);
const cached = await cache.get('key');
await cache.delete('key');
RedisCache
Redis-backed cache for production and distributed systems.
import { RedisCache } from '@mondaydotcomorg/atp-providers';
import Redis from 'ioredis';
const redis = new Redis({
host: 'localhost',
port: 6379,
password: process.env.REDIS_PASSWORD,
});
const cache = new RedisCache({
redis,
keyPrefix: 'atp:',
defaultTTL: 3600,
});
await cache.set('key', value, 3600);
const cached = await cache.get('key');
Benefits:
- Cross-pod state sharing
- Persistent storage
- High performance
- Production-ready
FileCache
File-based cache for simple persistence.
import { FileCache } from '@mondaydotcomorg/atp-providers';
const cache = new FileCache({
directory: './cache',
defaultTTL: 3600,
});
await cache.set('key', value);
const cached = await cache.get('key');
Auth Providers
EnvAuthProvider
Environment-based authentication for simple use cases.
import { EnvAuthProvider } from '@mondaydotcomorg/atp-providers';
const authProvider = new EnvAuthProvider({
envPrefix: 'AUTH_',
});
await authProvider.setCredentials('github', {
accessToken: 'ghp_...',
refreshToken: null,
expiresAt: null,
});
const credentials = await authProvider.getCredentials('github');
console.log(credentials.accessToken);
OAuth Providers
GoogleOAuthProvider
Google OAuth 2.0 integration.
import { GoogleOAuthProvider } from '@mondaydotcomorg/atp-providers';
const oauth = new GoogleOAuthProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
redirectUri: 'http://localhost:3333/oauth/callback',
scopes: [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/calendar',
],
});
const authUrl = await oauth.generateAuthUrl({
state: 'random-state',
});
const tokens = await oauth.handleCallback('authorization-code', {
state: 'random-state',
});
const newTokens = await oauth.refreshToken('refresh-token');
const hasScope = await oauth.checkScopes(tokens.accessToken, [
'https://www.googleapis.com/auth/calendar',
]);
GitHubOAuthProvider
GitHub OAuth integration.
import { GitHubOAuthProvider } from '@mondaydotcomorg/atp-providers';
const oauth = new GitHubOAuthProvider({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
redirectUri: 'http://localhost:3333/oauth/callback',
scopes: ['repo', 'user'],
});
const authUrl = await oauth.generateAuthUrl({ state: 'state' });
const tokens = await oauth.handleCallback('code', { state: 'state' });
Custom OAuth Provider
import type { OAuthProvider } from '@mondaydotcomorg/atp-protocol';
class SlackOAuthProvider implements OAuthProvider {
name = 'slack';
async generateAuthUrl(config) {
return `https://slack.com/oauth/v2/authorize?client_id=${config.clientId}&...`;
}
async handleCallback(code, config) {
const response = await fetch('https://slack.com/api/oauth.v2.access', {
method: 'POST',
body: JSON.stringify({ code, client_id: config.clientId, ... }),
});
const data = await response.json();
return {
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresAt: Date.now() + data.expires_in * 1000,
};
}
async refreshToken(refreshToken, config) {
}
async checkScopes(accessToken, requiredScopes) {
return true;
}
}
Audit Sinks
JSONLAuditSink
Write audit logs as JSON Lines files.
import { JSONLAuditSink } from '@mondaydotcomorg/atp-providers';
const auditSink = new JSONLAuditSink({
path: './audit-logs',
rotateDaily: true,
compress: true,
});
Features:
- Daily rotation
- Compression
- Structured JSON
- Easy parsing
OpenTelemetryAuditSink
Export audit events to OpenTelemetry collector.
import { OpenTelemetryAuditSink } from '@mondaydotcomorg/atp-providers';
const auditSink = new OpenTelemetryAuditSink({
endpoint: 'http://localhost:4318/v1/traces',
serviceName: 'atp-server',
serviceVersion: '1.0.0',
});
Integration with observability platforms:
- Jaeger
- Zipkin
- Prometheus
- Datadog
- New Relic
OpenTelemetry Metrics
import { OTelCounter, OTelHistogram, METRIC_CONFIGS } from '@mondaydotcomorg/atp-providers';
import { OTelAttribute } from '@mondaydotcomorg/atp-providers';
const attributes = {
[OTelAttribute.EXECUTION_ID]: 'exec-123',
[OTelAttribute.CLIENT_ID]: 'client-456',
[OTelAttribute.TOOL_NAME]: 'github.repos.get',
};
Usage in Server
import { createServer } from '@mondaydotcomorg/atp-server';
import {
RedisCache,
EnvAuthProvider,
GoogleOAuthProvider,
JSONLAuditSink,
OpenTelemetryAuditSink,
} from '@mondaydotcomorg/atp-providers';
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
const server = createServer({
audit: {
enabled: true,
sinks: [
new JSONLAuditSink({ path: './audit-logs', rotateDaily: true }),
new OpenTelemetryAuditSink({
endpoint: 'http://localhost:4318/v1/traces',
serviceName: 'atp-server',
}),
],
},
otel: {
enabled: true,
serviceName: 'atp-server',
},
});
server.setCacheProvider(new RedisCache({ redis }));
server.setAuthProvider(new EnvAuthProvider());
const googleCalendar = {
name: 'calendar',
type: 'oauth',
oauthProvider: new GoogleOAuthProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
redirectUri: 'http://localhost:3333/oauth/callback',
scopes: ['https://www.googleapis.com/auth/calendar'],
}),
functions: [
{
name: 'listEvents',
description: 'List calendar events',
inputSchema: { type: 'object', properties: {} },
handler: async (input, credentials) => {
const response = await fetch(
'https://www.googleapis.com/calendar/v3/calendars/primary/events',
{
headers: {
Authorization: `Bearer ${credentials.accessToken}`,
},
}
);
return await response.json();
},
},
],
};
server.addAPIGroup(googleCalendar);
await server.start(3333);
Cache Provider Interface
interface CacheProvider {
name: string;
get<T>(key: string): Promise<T | null>;
set(key: string, value: unknown, ttl?: number): Promise<void>;
delete(key: string): Promise<void>;
has(key: string): Promise<boolean>;
clear?(): Promise<void>;
}
Auth Provider Interface
interface AuthProvider {
name: string;
getCredentials(key: string): Promise<UserCredentialData | null>;
setCredentials(key: string, credentials: UserCredentialData): Promise<void>;
deleteCredentials(key: string): Promise<void>;
}
interface UserCredentialData {
accessToken: string;
refreshToken: string | null;
expiresAt: number | null;
scopes?: string[];
}
OAuth Provider Interface
interface OAuthProvider {
name: string;
generateAuthUrl(config: OAuthConfig): Promise<string>;
handleCallback(code: string, config: OAuthConfig): Promise<OAuthTokens>;
refreshToken(refreshToken: string, config: OAuthConfig): Promise<OAuthTokens>;
checkScopes(accessToken: string, requiredScopes: string[]): Promise<boolean>;
}
Audit Sink Interface
interface AuditSink {
write(event: AuditEvent): Promise<void>;
flush?(): Promise<void>;
}
interface AuditEvent {
timestamp: number;
type: 'execution' | 'tool_call' | 'llm_call' | 'approval' | 'error';
executionId?: string;
clientId?: string;
data: Record<string, unknown>;
}
TypeScript Support
Full TypeScript definitions included.
License
MIT