UNPKG

pet-adoption-mcp

Version:

A Model Context Protocol (MCP) server that helps users find adoptable pets through the Petfinder API

97 lines 3.69 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PetfinderClient = void 0; const axios_1 = __importDefault(require("axios")); const types_1 = require("./types"); class PetfinderClient { static instance = null; http; config; animalTypes = []; constructor(config) { this.config = config; this.http = axios_1.default.create({ baseURL: "https://api.petfinder.com", }); } static getInstance(apiKey, secretKey) { if (PetfinderClient.instance) { return PetfinderClient.instance; } if (!apiKey || !secretKey) { throw new Error("API key and secret key are required"); } PetfinderClient.instance = new PetfinderClient({ apiKey, secretKey }); return PetfinderClient.instance; } async authenticate() { if (this.config.bearerToken && this.config.bearerTokenExpiresAt && this.config.bearerTokenExpiresAt > new Date()) { return; } try { const response = await this.http.post("/v2/oauth2/token", { grant_type: "client_credentials", client_id: this.config.apiKey, client_secret: this.config.secretKey, }); this.config.bearerToken = response.data.access_token; this.config.bearerTokenExpiresAt = new Date(Date.now() + response.data.expires_in * 1000); this.http.interceptors.request.use((config) => { config.headers.Authorization = `Bearer ${this.config.bearerToken}`; return config; }); } catch (error) { console.error("Failed to authenticate with Petfinder API:", error); throw new Error("Failed to authenticate with Petfinder API"); } } async searchAnimals(params) { try { await this.authenticate(); if (params.location) { const location = typeof params.location === "string" ? params.location : Object.values(params.location).join(", "); params.location = location; } const response = await this.http.get("/v2/animals", { params: { distance: 10, status: types_1.Status.Adoptable, ...params, size: params.size?.join(","), limit: 10, }, }); return response.data.animals; } catch (error) { console.error("Failed to search animals:", error); throw new Error("Failed to search animals"); } } async getAnimalTypes() { if (this.animalTypes.length > 0) { return this.animalTypes; } try { await this.authenticate(); const response = await this.http.get("/v2/types"); for (const resp of response.data.types) { const breedsResponse = await this.http.get(resp._links.breeds.href); const breeds = breedsResponse.data.breeds.map((breed) => breed.name); resp.breeds = breeds; } this.animalTypes = response.data.types; return this.animalTypes; } catch (error) { console.error("Failed to get animal types:", error); throw new Error("Failed to get animal types"); } } } exports.PetfinderClient = PetfinderClient; //# sourceMappingURL=index.js.map