@rashidazarang/aptly-mcp
Version:
Model Context Protocol server for Aptly package repository management - enables AI assistants to manage Debian repositories
162 lines • 5.95 kB
JavaScript
import axios from 'axios';
export class AptlyClient {
client;
constructor(config) {
this.client = axios.create({
baseURL: config.baseURL,
timeout: config.timeout || 30000,
headers: {
'Content-Type': 'application/json',
},
});
if (config.authToken) {
this.client.defaults.headers.common['Authorization'] = `Bearer ${config.authToken}`;
}
// Error handling interceptor
this.client.interceptors.response.use((response) => response, (error) => {
if (error.response?.data?.error) {
throw new Error(`Aptly API Error: ${error.response.data.error}`);
}
if (error.code === 'ECONNREFUSED') {
throw new Error('Cannot connect to Aptly server. Is it running?');
}
throw new Error(`Request failed: ${error.message}`);
});
}
// Health check
async ping() {
try {
await this.client.get('/api/version');
return true;
}
catch {
return false;
}
}
// Repository operations
async listRepositories() {
const response = await this.client.get('/api/repos');
return response.data || [];
}
async getRepository(name) {
const response = await this.client.get(`/api/repos/${encodeURIComponent(name)}`);
return response.data;
}
async createRepository(name, comment, defaultDistribution, defaultComponent) {
const data = { Name: name };
if (comment)
data.Comment = comment;
if (defaultDistribution)
data.DefaultDistribution = defaultDistribution;
if (defaultComponent)
data.DefaultComponent = defaultComponent;
const response = await this.client.post('/api/repos', data);
return response.data;
}
async deleteRepository(name, force = false) {
const params = force ? { force: '1' } : {};
await this.client.delete(`/api/repos/${encodeURIComponent(name)}`, { params });
}
// Package operations
async listPackages(repoName, query) {
const params = {};
if (query)
params.q = query;
const response = await this.client.get(`/api/repos/${encodeURIComponent(repoName)}/packages`, { params });
return response.data || [];
}
async addPackages(repoName, directory, files) {
const data = { SourceKind: 'upload' };
if (files && files.length > 0) {
data.UploadedFiles = files;
}
else {
// Add all files from directory
const fileList = await this.listUploadedFiles(directory);
if (fileList[directory]) {
data.UploadedFiles = fileList[directory].map(f => f.filename);
}
}
await this.client.post(`/api/repos/${encodeURIComponent(repoName)}/packages`, data);
}
// Mirror operations
async listMirrors() {
const response = await this.client.get('/api/mirrors');
return response.data || [];
}
async createMirror(name, archiveURL, distribution, components, architectures) {
const data = {
Name: name,
ArchiveURL: archiveURL,
Distribution: distribution,
};
if (components)
data.Components = components;
if (architectures)
data.Architectures = architectures;
const response = await this.client.post('/api/mirrors', data);
return response.data;
}
async getMirror(name) {
const response = await this.client.get(`/api/mirrors/${encodeURIComponent(name)}`);
return response.data;
}
async updateMirror(name) {
await this.client.put(`/api/mirrors/${encodeURIComponent(name)}`, {});
}
// Snapshot operations
async listSnapshots() {
const response = await this.client.get('/api/snapshots');
return response.data || [];
}
async createSnapshot(name, repoName, description) {
const data = {
Name: name,
Description: description || `Snapshot of repository ${repoName}`,
};
const response = await this.client.post(`/api/repos/${encodeURIComponent(repoName)}/snapshots`, data);
return response.data;
}
// Publish operations
async listPublishedRepositories() {
const response = await this.client.get('/api/publish');
return response.data || [];
}
async publishRepository(repoName, distribution, prefix) {
const data = {
SourceKind: 'local',
Sources: [{ Component: 'main', Name: repoName }],
Distribution: distribution,
};
if (prefix) {
data.Prefix = prefix;
}
const response = await this.client.post('/api/publish', data);
return response.data;
}
async publishSnapshot(snapshotName, distribution, prefix) {
const data = {
SourceKind: 'snapshot',
Sources: [{ Component: 'main', Name: snapshotName }],
Distribution: distribution,
};
if (prefix) {
data.Prefix = prefix;
}
const response = await this.client.post('/api/publish', data);
return response.data;
}
// File upload operations
async listUploadedFiles(directory) {
const path = directory ? `/api/files/${encodeURIComponent(directory)}` : '/api/files';
const response = await this.client.get(path);
return response.data || {};
}
async deleteUploadedFiles(directory, filename) {
const path = filename
? `/api/files/${encodeURIComponent(directory)}/${encodeURIComponent(filename)}`
: `/api/files/${encodeURIComponent(directory)}`;
await this.client.delete(path);
}
}
//# sourceMappingURL=aptly-client.js.map