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
JavaScript
;
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