pgpt-service.ts•4.53 kB
import axios, { AxiosInstance } from 'axios';
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { ChatArgs, SourceArgs, ListSourcesArgs, GetSourceArgs } from '../types/api.js';
export class PGPTService {
  private api: AxiosInstance;
  private token: string | null = null;
  constructor() {
    // Initialize axios instance with base configuration
    this.api = axios.create({
      baseURL: process.env.PGPT_API_URL || 'http://localhost:3000',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
    });
  }
  private async ensureAuthenticated(): Promise<void> {
    if (!this.token) {
      const email = process.env.PGPT_EMAIL;
      const password = process.env.PGPT_PASSWORD;
      if (!email || !password) {
        throw new McpError(
          ErrorCode.InvalidRequest,
          'Missing authentication credentials'
        );
      }
      try {
        const response = await this.api.post('/api/v1/login', {
          email,
          password,
        });
        this.token = response.data.data.token;
        this.api.defaults.headers.common['Authorization'] = `Bearer ${this.token}`;
      } catch (error) {
        throw new McpError(
          ErrorCode.InvalidRequest,
          'Authentication failed'
        );
      }
    }
  }
  async chat(args: ChatArgs) {
    await this.ensureAuthenticated();
    try {
      const response = await this.api.post('/api/v1/chats', {
        language: args.language || 'en',
        question: args.question,
        usePublic: args.usePublic || false,
        groups: args.groups || [],
      });
      return {
        content: [
          {
            type: 'text',
            text: response.data.data.answer,
          },
        ],
      };
    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new McpError(
          ErrorCode.InternalError,
          `Chat failed: ${error.response?.data?.message || error.message}`
        );
      }
      throw error;
    }
  }
  async createSource(args: SourceArgs) {
    await this.ensureAuthenticated();
    try {
      const response = await this.api.post('/api/v1/sources', {
        name: args.name,
        content: args.content,
        groups: args.groups || [],
      });
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data.data, null, 2),
          },
        ],
      };
    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new McpError(
          ErrorCode.InternalError,
          `Source creation failed: ${error.response?.data?.message || error.message}`
        );
      }
      throw error;
    }
  }
  async listGroups() {
    await this.ensureAuthenticated();
    try {
      const response = await this.api.get('/api/v1/groups');
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data.data, null, 2),
          },
        ],
      };
    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new McpError(
          ErrorCode.InternalError,
          `Group listing failed: ${error.response?.data?.message || error.message}`
        );
      }
      throw error;
    }
  }
  async listSources(args: ListSourcesArgs) {
    await this.ensureAuthenticated();
    try {
      const response = await this.api.post('/api/v1/sources/groups', {
        groupName: args.groupName,
      });
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data.data, null, 2),
          },
        ],
      };
    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new McpError(
          ErrorCode.InternalError,
          `Source listing failed: ${error.response?.data?.message || error.message}`
        );
      }
      throw error;
    }
  }
  async getSource(args: GetSourceArgs) {
    await this.ensureAuthenticated();
    try {
      const response = await this.api.get(`/api/v1/sources/${args.sourceId}`);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data.data, null, 2),
          },
        ],
      };
    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new McpError(
          ErrorCode.InternalError,
          `Source retrieval failed: ${error.response?.data?.message || error.message}`
        );
      }
      throw error;
    }
  }
}