Skip to main content
Glama
bradcstevens

Copilot Studio Agent Direct Line MCP Server

by bradcstevens
directline-client.ts4.65 kB
/** * Direct Line 3.0 API client */ import type { AxiosInstance } from 'axios'; import type { DirectLineToken, Conversation, Activity, ActivitySet, SendActivityOptions, GetActivitiesOptions, } from '../types/directline.js'; import { createHttpClient } from './http-client.js'; import { CircuitBreaker } from '../utils/circuit-breaker.js'; /** * Direct Line Client for interacting with Microsoft Bot Framework Direct Line API */ export class DirectLineClient { private client: AxiosInstance; private secret: string; private circuitBreaker: CircuitBreaker; /** * Create a new Direct Line client * @param secret - Direct Line secret key */ constructor(secret: string) { this.secret = secret; this.client = createHttpClient(); this.circuitBreaker = new CircuitBreaker({ failureThreshold: 5, failureWindow: 30000, recoveryTimeout: 60000, successThreshold: 3, }); } /** * Generate a new Direct Line token from secret * @returns Token response with conversationId and token * @throws Error if token generation fails */ async generateToken(): Promise<DirectLineToken> { return this.circuitBreaker.execute(async () => { try { const response = await this.client.post<DirectLineToken>( '/tokens/generate', {}, { headers: { Authorization: `Bearer ${this.secret}`, }, } ); return response.data; } catch (error) { console.error('[DirectLine] Token generation failed:', error); throw new Error(`Failed to generate Direct Line token: ${error}`); } }); } /** * Start a new conversation * @param token - Optional Direct Line token (generates new one if not provided) * @returns Conversation details * @throws Error if conversation creation fails */ async startConversation(token?: string): Promise<Conversation> { return this.circuitBreaker.execute(async () => { try { const authToken = token || (await this.generateToken()).token; const response = await this.client.post<Conversation>( '/conversations', {}, { headers: { Authorization: `Bearer ${authToken}`, }, } ); return response.data; } catch (error) { console.error('[DirectLine] Conversation creation failed:', error); throw new Error(`Failed to start conversation: ${error}`); } }); } /** * Send an activity (message) to a conversation * @param options - Send activity options * @param token - Direct Line token * @returns Activity ID * @throws Error if sending fails */ async sendActivity(options: SendActivityOptions, token: string): Promise<string> { return this.circuitBreaker.execute(async () => { try { const { conversationId, activity } = options; const response = await this.client.post<{ id: string }>( `/conversations/${conversationId}/activities`, { type: 'message', from: { id: 'user' }, ...activity, }, { headers: { Authorization: `Bearer ${token}`, }, } ); return response.data.id; } catch (error) { console.error('[DirectLine] Send activity failed:', error); throw new Error(`Failed to send activity: ${error}`); } }); } /** * Get activities from a conversation * @param options - Get activities options * @param token - Direct Line token * @returns Activity set with watermark * @throws Error if retrieval fails */ async getActivities(options: GetActivitiesOptions, token: string): Promise<ActivitySet> { return this.circuitBreaker.execute(async () => { try { const { conversationId, watermark } = options; const url = watermark ? `/conversations/${conversationId}/activities?watermark=${watermark}` : `/conversations/${conversationId}/activities`; const response = await this.client.get<ActivitySet>(url, { headers: { Authorization: `Bearer ${token}`, }, }); return response.data; } catch (error) { console.error('[DirectLine] Get activities failed:', error); throw new Error(`Failed to get activities: ${error}`); } }); } /** * Get circuit breaker metrics * @returns Circuit breaker metrics */ getCircuitBreakerMetrics() { return this.circuitBreaker.getMetrics(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bradcstevens/copilot-studio-agent-direct-line-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server