Skip to main content
Glama
sirsambhav221

MCP Docker Hub Server

DockerHub.js8.36 kB
const axios = require('axios') const cache = require('../utils/cache') const DockerCredentialsService = require('./DockerCredentialsService') const credentialsService = new DockerCredentialsService(); const getAccessToken = async (username,pat) => { try { if (!username) { throw new Error('Username is required to get Docker Hub access token'); } // Get credentials from database const userExists = await credentialsService.ifUserExists(username,pat); if (!userExists) { throw new Error(`No Docker credentials found for user: ${username}. Please save credentials first.`); } else{ const credentials = await credentialsService.getCredentials(username); } const response = await axios.post('https://hub.docker.com/v2/auth/token', { identifier: username, secret: credentials.pat }, { headers: { 'Content-Type': 'application/json' } }) return response.data.access_token } catch (error) { console.error('Error getting Docker Hub access token:', error.message) throw error } } const getRegistryToken = async (scope, username, pat) => { const url = `https://auth.docker.io/token?service=registry.docker.io&scope=${scope}`; const cacheKey = `registryToken:${scope}:${username}:${pat}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for registry token'); return cached; } const headers = {}; if (username && pat) { const credentials = Buffer.from(`${username}:${pat}`).toString('base64'); headers['Authorization'] = `Basic ${credentials}`; } try { const response = await axios.get(url, { headers }); cache.set(cacheKey, response.data.access_token, 240000); return response.data.access_token; } catch (error) { console.error('Error getting registry token:', error.message); throw error; } } const validateCredentials = async (username, pat) => { const userExists = await credentialsService.ifUserExists(username.trim(), pat.trim()); if (!userExists) { throw new Error(`No Docker credentials found for user: ${username}. Please save credentials first.`); } return true; } const getImages = async (query, limit = 5, page = 1, pat=null) => { const cacheKey = `images:${query}:${limit}:${page}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for images search'); return cached; } try { const response = await axios.get('https://hub.docker.com/v2/search/repositories/', { params: { query: query, page: page, page_size: limit }, headers: { 'Content-Type': 'application/json', 'Authorization': pat ? `Bearer ${pat}` : null } }) if (!response.data || !response.data.results) { throw new Error('Invalid response structure from Docker Hub API'); } cache.set(cacheKey, response.data.results, 600000); return response.data.results } catch (error) { console.error('Error searching Docker Hub images:', error.message) if (error.response) { console.error('Response status:', error.response.status); } throw error } } const getImageDetails = async (imageName, isOffical=false, pat=null) => { const cacheKey = `details:${isOffical ? 'library/' : ''}${imageName}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for image details'); return cached; } try { const response = await axios.get(`https://hub.docker.com/v2/repositories/${isOffical ? 'library/' : ''}${imageName}`, { headers: { 'Authorization': pat ? `Bearer ${pat}` : null } }) const data = { ...response.data }; delete data.full_description; delete data.media_types; delete data.hub_user; cache.set(cacheKey, data, 3600000); return data; } catch (error) { console.error('Error getting Docker Hub image details:', error.message) throw error } } const getImageTags = async (imageName, isOffical=false, page=1, limit=2, pat=null) => { const cacheKey = `tags:${isOffical ? 'library/' : ''}${imageName}:${page}:${limit}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for image tags'); return cached; } try { const response = await axios.get(`https://hub.docker.com/v2/repositories/${isOffical ? 'library/' : ''}${imageName}/tags`, { params: { page: page, page_size: limit }, headers: { 'Authorization': pat ? `Bearer ${pat}` : null } }) cache.set(cacheKey, response.data.results, 1800000); return response.data.results; } catch (error) { console.error('Error getting Docker Hub image tags:', error.message) throw error } } const getImageManifest = async (imageName, isOffical=false, tag, username, pat) => { const cacheKey = `manifest:${isOffical ? 'library/' : ''}${imageName}:${tag}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for image manifest'); return cached; } try { const token = await getRegistryToken(`repository:${isOffical ? 'library/' : ''}${imageName}:pull`, username, pat); const response2 = await axios.get(`https://registry-1.docker.io/v2/${isOffical ? 'library/' : ''}${imageName}/manifests/${tag}`, { headers: { 'Authorization': `Bearer ${token}` } }); const result = response2.data?.manifests || response2.data?.layers; // Cache for 1 hour (manifests rarely change) cache.set(cacheKey, result, 3600000); return result; } catch (error) { console.error('Error getting Docker Hub image manifest:', error.message); if (error.response) { console.error('Response status:', error.response.status); } throw error; } } const getImageTagDetails = async (imageName, isOffical=false, tag, pat=null) => { const cacheKey = `tagDetails:${isOffical ? 'library/' : ''}${imageName}:${tag}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for image tag details'); return cached; } try { const response = await axios.get(`https://hub.docker.com/v2/repositories/${isOffical ? 'library/' : ''}${imageName}/tags/${tag}`, { headers: { 'Authorization': pat ? `Bearer ${pat}` : null } }) console.log(response.data) // Cache for 30 minutes cache.set(cacheKey, response.data, 1800000); return response.data; } catch (error) { console.error('Error getting Docker Hub image tag details:', error.message) throw error } } const getAllRepositories = async (username, pat=null) => { const cacheKey = `repos:${username}`; const cached = cache.get(cacheKey); if (cached) { console.log('Cache hit for repositories'); return cached; } try { const response = await axios.get(`https://hub.docker.com/v2/repositories/${username}`, { headers: { 'Content-Type': 'application/json', 'Authorization': pat ? `Bearer ${pat}` : null } }) cache.set(cacheKey, response.data.results, 7200000); return response.data.results; } catch (error) { console.error('Error getting repositories:', error.message) throw error } } module.exports = { getAccessToken, getImages, getImageDetails, getImageManifest, getImageTags, getImageTagDetails, getAllRepositories, getRegistryToken, validateCredentials }

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/sirsambhav221/MCPDCOKER'

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