Skip to main content
Glama
apps.ts33 kB
import { BaseService, ServiceInfo } from './base-service.js'; export class AppsService extends BaseService { getServiceInfo(): ServiceInfo { return { name: 'apps', description: 'Manage BTCPayServer apps - create, get, update, delete Point-of-Sale and Crowdfund applications with comprehensive features', category: 'applications', methods: [ { name: 'listAll', description: 'List all apps for all stores', parameters: {}, examples: [ { name: 'List all apps', description: 'Get all apps across all stores', parameters: {} } ] }, { name: 'listStore', description: 'List all apps for a specific store', parameters: { storeId: { type: 'string', description: 'Store ID', required: true } }, examples: [ { name: 'List store apps', description: 'Get all apps for a store', parameters: { storeId: 'store123' } } ] }, { name: 'get', description: 'Get basic app data', parameters: { appId: { type: 'string', description: 'App ID', required: true } }, examples: [ { name: 'Get app info', description: 'Get basic app information', parameters: { appId: 'app_123' } } ] }, { name: 'delete', description: 'Delete an app', parameters: { appId: { type: 'string', description: 'App ID to delete', required: true } }, examples: [ { name: 'Delete app', description: 'Remove an app completely', parameters: { appId: 'app_123' } } ] }, { name: 'uploadImage', description: 'Upload an image for an app', parameters: { appId: { type: 'string', description: 'App ID', required: true }, fileData: { type: 'object', description: 'FormData object containing the image file', required: true } }, examples: [ { name: 'Upload app image', description: 'Upload an image for app branding', parameters: { appId: 'app_123', fileData: 'FormData with image file' } } ] }, { name: 'deleteImage', description: 'Delete an app image', parameters: { appId: { type: 'string', description: 'App ID', required: true }, fileId: { type: 'string', description: 'File ID to delete', required: true } }, examples: [ { name: 'Delete app image', description: 'Remove an app image', parameters: { appId: 'app_123', fileId: 'file_456' } } ] }, { name: 'getSalesStatistics', description: 'Get app sales statistics', parameters: { appId: { type: 'string', description: 'App ID', required: true }, numberOfDays: { type: 'number', description: 'Number of days to include in statistics', required: false, default: 7 } }, examples: [ { name: 'Get sales stats', description: 'Get sales statistics for the last 30 days', parameters: { appId: 'app_123', numberOfDays: 30 } } ] }, { name: 'getTopItems', description: 'Get top-selling items for an app', parameters: { appId: { type: 'string', description: 'App ID', required: true }, count: { type: 'number', description: 'Number of items to return', required: false, default: 5 }, offset: { type: 'number', description: 'Offset for pagination', required: false, default: 0 } }, examples: [ { name: 'Get top items', description: 'Get top 10 selling items', parameters: { appId: 'app_123', count: 10 } } ] }, { name: 'createPos', description: 'Create a new Point-of-Sale app', parameters: { storeId: { type: 'string', description: 'Store ID', required: true }, appName: { type: 'string', description: 'Name given to the app when it was created', required: true }, id: { type: 'string', description: 'Id of the app', required: false }, title: { type: 'string', description: 'Display title of the app', required: false }, description: { type: 'string', description: 'App description', required: false }, defaultView: { type: 'string', description: 'App view type (Static, Cart, Light, Print)', required: false }, showItems: { type: 'boolean', description: 'Display item selection for keypad', required: false }, showCustomAmount: { type: 'boolean', description: 'Whether the option to enter a custom amount is shown', required: false }, showDiscount: { type: 'boolean', description: 'Whether the option to enter a discount is shown', required: false }, showSearch: { type: 'boolean', description: 'Display the search bar', required: false }, showCategories: { type: 'boolean', description: 'Display the list of categories', required: false }, enableTips: { type: 'boolean', description: 'Whether the option to enter a tip is shown', required: false }, currency: { type: 'string', description: 'Currency used for the app', required: false }, fixedAmountPayButtonText: { type: 'string', description: 'Payment button text template for items with a set price', required: false }, customAmountPayButtonText: { type: 'string', description: 'Payment button text which appears for items which allow user to input a custom amount', required: false }, tipText: { type: 'string', description: 'Prompt which appears next to the tip amount field if tipping is enabled', required: false }, customTipPercentages: { type: 'array', description: 'Array of predefined tip percentage amounts', required: false }, notificationUrl: { type: 'string', description: 'Callback notification url to POST to once when invoice is paid', required: false }, redirectUrl: { type: 'string', description: 'URL user is redirected to once invoice is paid', required: false }, redirectAutomatically: { type: 'boolean', description: 'Whether user is redirected to specified redirect URL automatically after the invoice is paid', required: false, default: false }, htmlLang: { type: 'string', description: 'Used for SEO, the HTML Lang of the page', required: false }, htmlMetaTags: { type: 'string', description: 'Used for SEO, the Meta tags of the page', required: false }, formId: { type: 'string', description: 'Form ID to request customer data', required: false }, template: { type: 'string', description: 'JSON of item available in the app', required: true, default: 'string' }, archived: { type: 'boolean', description: 'If true, the app does not appear in the apps list by default', required: false } }, examples: [ { name: 'Create basic POS', description: 'Create a simple Point-of-Sale app', parameters: { storeId: 'store123', appName: 'Coffee Shop POS', id: 'coffee-shop-pos', title: 'Coffee Shop', description: 'Order coffee and pastries', defaultView: 'Cart', enableTips: true, currency: 'BTC', template: 'string', redirectAutomatically: false } }, { name: 'Create advanced POS', description: 'Create a fully configured POS app', parameters: { storeId: 'store123', appName: 'Restaurant POS', id: 'restaurant-pos', title: 'Fine Dining Restaurant', description: 'Premium dining experience', defaultView: 'Cart', showItems: true, showCustomAmount: true, showDiscount: true, enableTips: true, currency: 'BTC', customTipPercentages: [15, 18, 20, 25], fixedAmountPayButtonText: 'Pay {0}', customAmountPayButtonText: 'Pay Amount', tipText: 'Service was great?', notificationUrl: 'https://myrestaurant.com/webhook', redirectUrl: 'https://myrestaurant.com/thankyou', template: 'string', redirectAutomatically: false } } ] }, { name: 'getPos', description: 'Get Point-of-Sale app details', parameters: { appId: { type: 'string', description: 'App ID', required: true } }, examples: [ { name: 'Get POS app', description: 'Retrieve POS app configuration', parameters: { appId: '3ki4jsAkN4u9rv1PUzj1odX4Nx7s' } } ] }, { name: 'updatePos', description: 'Update Point-of-Sale app', parameters: { appId: { type: 'string', description: 'POS App ID', required: true }, appName: { type: 'string', description: 'Name given to the app when it was created', required: false }, title: { type: 'string', description: 'Display title of the app', required: false }, description: { type: 'string', description: 'App description', required: false }, defaultView: { type: 'string', description: 'App view type (Static, Cart, Light, Print)', required: false }, enableTips: { type: 'boolean', description: 'Whether the option to enter a tip is shown', required: false }, currency: { type: 'string', description: 'Currency used for the app', required: false }, customTipPercentages: { type: 'array', description: 'Array of predefined tip percentage amounts', required: false }, archived: { type: 'boolean', description: 'If true, the app does not appear in the apps list by default', required: false } }, examples: [ { name: 'Update POS settings', description: 'Update POS app configuration', parameters: { appId: 'pos_app_456', title: 'Updated Coffee Shop', enableTips: true, customTipPercentages: [18, 20, 22] } } ] }, { name: 'createCrowdfund', description: 'Create a new Crowdfund app', parameters: { storeId: { type: 'string', description: 'Store ID', required: true }, appName: { type: 'string', description: 'Name given to the app when it was created', required: true }, id: { type: 'string', description: 'Id of the app', required: false }, title: { type: 'string', description: 'Display title of the app', required: false }, description: { type: 'string', description: 'App description', required: false }, enabled: { type: 'boolean', description: 'Whether the app is enabled to be viewed by everyone', required: false }, enforceTargetAmount: { type: 'boolean', description: 'Whether contributions over the set target amount are allowed', required: false }, startDate: { type: 'number', description: 'UNIX timestamp for crowdfund start time', required: false }, endDate: { type: 'number', description: 'UNIX timestamp for crowdfund end time', required: false }, targetCurrency: { type: 'string', description: 'Target currency for the crowdfund', required: false }, targetAmount: { type: 'string', description: 'Target amount for the crowdfund', required: false }, mainImageUrl: { type: 'string', description: 'URL for image used as a cover image for the app', required: false }, notificationUrl: { type: 'string', description: 'Callback notification url to POST to once when invoice is paid', required: false }, tagline: { type: 'string', description: 'Tagline for the app displayed to user', required: false }, disqusEnabled: { type: 'boolean', description: 'Whether Disqus is enabled for the app', required: false }, disqusShortname: { type: 'string', description: 'Disqus shortname to used for the app', required: false }, soundsEnabled: { type: 'boolean', description: 'Whether sounds on new contributions are enabled', required: false }, animationsEnabled: { type: 'boolean', description: 'Whether background animations on new contributions are enabled', required: false }, resetEveryAmount: { type: 'string', description: 'Contribution goal reset frequency amount', required: false }, resetEvery: { type: 'string', description: 'Contribution goal reset frequency', required: false }, displayPerksValue: { type: 'boolean', description: 'Whether perk values are displayed', required: false }, sortPerksByPopularity: { type: 'boolean', description: 'Whether perks are sorted by popularity', required: false }, sounds: { type: 'array', description: 'Array of custom sounds which can be used on new contributions', required: false }, animationColors: { type: 'array', description: 'Array of custom HEX colors which can be used for background animations', required: false }, htmlLang: { type: 'string', description: 'Used for SEO, the HTML Lang of the page', required: false }, htmlMetaTags: { type: 'string', description: 'Used for SEO, the Meta tags of the page', required: false }, formId: { type: 'string', description: 'Form ID to request customer data', required: false }, perksTemplate: { type: 'string', description: 'JSON of perks available in the app', required: true, default: 'string' }, archived: { type: 'boolean', description: 'If true, the app does not appear in the apps list by default', required: false } }, examples: [ { name: 'Create project crowdfund', description: 'Create a crowdfunding campaign', parameters: { storeId: 'store123', appName: 'Open Source Project', id: 'open-source-project', title: 'Fund Our Development', description: 'Help us build amazing open source software', targetCurrency: 'BTC', targetAmount: '420.69', enabled: true, tagline: 'Support innovation', perksTemplate: 'string' } }, { name: 'Create charity crowdfund', description: 'Create a charity fundraising campaign', parameters: { storeId: 'store123', appName: 'Charity Drive', id: 'charity-drive', title: 'Help Those in Need', description: 'Supporting local families during difficult times', targetCurrency: 'BTC', targetAmount: '25.0', enabled: true, enforceTargetAmount: false, animationsEnabled: true, soundsEnabled: true, disqusEnabled: true, perksTemplate: 'string' } } ] }, { name: 'getCrowdfund', description: 'Get Crowdfund app details', parameters: { appId: { type: 'string', description: 'App ID', required: true } }, examples: [ { name: 'Get crowdfund app', description: 'Retrieve crowdfund app details', parameters: { appId: '3ki4jsAkN4u9rv1PUzj1odX4Nx7s' } } ] }, { name: 'updateCrowdfund', description: 'Update Crowdfund app', parameters: { appId: { type: 'string', description: 'Crowdfund App ID', required: true }, appName: { type: 'string', description: 'Name given to the app when it was created', required: false }, title: { type: 'string', description: 'Display title of the app', required: false }, description: { type: 'string', description: 'App description', required: false }, enabled: { type: 'boolean', description: 'Whether the app is enabled to be viewed by everyone', required: false }, targetAmount: { type: 'string', description: 'Target amount for the crowdfund', required: false }, targetCurrency: { type: 'string', description: 'Target currency for the crowdfund', required: false }, tagline: { type: 'string', description: 'Tagline for the app displayed to user', required: false }, archived: { type: 'boolean', description: 'If true, the app does not appear in the apps list by default', required: false } }, examples: [ { name: 'Update crowdfund target', description: 'Update crowdfund target amount', parameters: { appId: 'crowd_app_789', targetAmount: '75000', enabled: true, tagline: 'We are almost there!' } } ] } ] }; } protected async handleMethod(methodName: string, parameters: Record<string, any>): Promise<any> { switch (methodName) { case 'listAll': return await this.client.listAllApps(); case 'listStore': return await this.client.listStoreApps(parameters.storeId); case 'get': return await this.client.getApp(parameters.appId); case 'delete': return await this.client.deleteApp(parameters.appId); case 'uploadImage': return await this.client.uploadAppImage(parameters.appId, parameters.fileData); case 'deleteImage': return await this.client.deleteAppImage(parameters.appId, parameters.fileId); case 'getSalesStatistics': return await this.client.getAppSalesStatistics( parameters.appId, parameters.numberOfDays || 7 ); case 'getTopItems': return await this.client.getAppTopItems( parameters.appId, parameters.count || 5, parameters.offset || 0 ); case 'createPos': // Extract all POS-specific parameters and create the data object const posAppData: any = {}; // Required fields if (parameters.appName) posAppData.appName = parameters.appName; // Template is required - provide default string if not specified posAppData.template = parameters.template || 'string'; // Add missing fields that BTCPayServer expects if (parameters.id) posAppData.id = parameters.id; // Set default redirectAutomatically if not provided posAppData.redirectAutomatically = parameters.redirectAutomatically !== undefined ? parameters.redirectAutomatically : false; // Optional fields if (parameters.title !== undefined) posAppData.title = parameters.title; if (parameters.description !== undefined) posAppData.description = parameters.description; if (parameters.defaultView !== undefined) posAppData.defaultView = parameters.defaultView; if (parameters.showItems !== undefined) posAppData.showItems = parameters.showItems; if (parameters.showCustomAmount !== undefined) posAppData.showCustomAmount = parameters.showCustomAmount; if (parameters.showDiscount !== undefined) posAppData.showDiscount = parameters.showDiscount; if (parameters.showSearch !== undefined) posAppData.showSearch = parameters.showSearch; if (parameters.showCategories !== undefined) posAppData.showCategories = parameters.showCategories; if (parameters.enableTips !== undefined) posAppData.enableTips = parameters.enableTips; if (parameters.currency !== undefined) posAppData.currency = parameters.currency; if (parameters.fixedAmountPayButtonText !== undefined) posAppData.fixedAmountPayButtonText = parameters.fixedAmountPayButtonText; if (parameters.customAmountPayButtonText !== undefined) posAppData.customAmountPayButtonText = parameters.customAmountPayButtonText; if (parameters.tipText !== undefined) posAppData.tipText = parameters.tipText; if (parameters.customTipPercentages !== undefined) posAppData.customTipPercentages = parameters.customTipPercentages; if (parameters.notificationUrl !== undefined) posAppData.notificationUrl = parameters.notificationUrl; if (parameters.redirectUrl !== undefined) posAppData.redirectUrl = parameters.redirectUrl; if (parameters.htmlLang !== undefined) posAppData.htmlLang = parameters.htmlLang; if (parameters.htmlMetaTags !== undefined) posAppData.htmlMetaTags = parameters.htmlMetaTags; if (parameters.formId !== undefined) posAppData.formId = parameters.formId; if (parameters.template !== undefined) posAppData.template = parameters.template; if (parameters.archived !== undefined) posAppData.archived = parameters.archived; return await this.client.createPosApp(parameters.storeId, posAppData); case 'getPos': return await this.client.getPosApp(parameters.appId); case 'updatePos': // Extract all update parameters and create the data object const updatePosData: any = {}; if (parameters.appName !== undefined) updatePosData.appName = parameters.appName; if (parameters.title !== undefined) updatePosData.title = parameters.title; if (parameters.description !== undefined) updatePosData.description = parameters.description; if (parameters.defaultView !== undefined) updatePosData.defaultView = parameters.defaultView; if (parameters.enableTips !== undefined) updatePosData.enableTips = parameters.enableTips; if (parameters.currency !== undefined) updatePosData.currency = parameters.currency; if (parameters.customTipPercentages !== undefined) updatePosData.customTipPercentages = parameters.customTipPercentages; if (parameters.archived !== undefined) updatePosData.archived = parameters.archived; return await this.client.updatePosApp(parameters.appId, updatePosData); case 'createCrowdfund': // Extract all Crowdfund-specific parameters and create the data object const crowdfundAppData: any = {}; // Required fields if (parameters.appName) crowdfundAppData.appName = parameters.appName; // PerksTemplate is required - provide default string if not specified crowdfundAppData.perksTemplate = parameters.perksTemplate || 'string'; // Add missing fields that BTCPayServer expects if (parameters.id) crowdfundAppData.id = parameters.id; // Optional fields if (parameters.title !== undefined) crowdfundAppData.title = parameters.title; if (parameters.description !== undefined) crowdfundAppData.description = parameters.description; if (parameters.enabled !== undefined) crowdfundAppData.enabled = parameters.enabled; if (parameters.enforceTargetAmount !== undefined) crowdfundAppData.enforceTargetAmount = parameters.enforceTargetAmount; if (parameters.startDate !== undefined) crowdfundAppData.startDate = parameters.startDate; if (parameters.endDate !== undefined) crowdfundAppData.endDate = parameters.endDate; if (parameters.targetCurrency !== undefined) crowdfundAppData.targetCurrency = parameters.targetCurrency; if (parameters.targetAmount !== undefined) crowdfundAppData.targetAmount = parameters.targetAmount; if (parameters.mainImageUrl !== undefined) crowdfundAppData.mainImageUrl = parameters.mainImageUrl; if (parameters.notificationUrl !== undefined) crowdfundAppData.notificationUrl = parameters.notificationUrl; if (parameters.tagline !== undefined) crowdfundAppData.tagline = parameters.tagline; if (parameters.disqusEnabled !== undefined) crowdfundAppData.disqusEnabled = parameters.disqusEnabled; if (parameters.disqusShortname !== undefined) crowdfundAppData.disqusShortname = parameters.disqusShortname; if (parameters.soundsEnabled !== undefined) crowdfundAppData.soundsEnabled = parameters.soundsEnabled; if (parameters.animationsEnabled !== undefined) crowdfundAppData.animationsEnabled = parameters.animationsEnabled; if (parameters.resetEveryAmount !== undefined) crowdfundAppData.resetEveryAmount = parameters.resetEveryAmount; if (parameters.resetEvery !== undefined) crowdfundAppData.resetEvery = parameters.resetEvery; if (parameters.displayPerksValue !== undefined) crowdfundAppData.displayPerksValue = parameters.displayPerksValue; if (parameters.sortPerksByPopularity !== undefined) crowdfundAppData.sortPerksByPopularity = parameters.sortPerksByPopularity; if (parameters.sounds !== undefined) crowdfundAppData.sounds = parameters.sounds; if (parameters.animationColors !== undefined) crowdfundAppData.animationColors = parameters.animationColors; if (parameters.htmlLang !== undefined) crowdfundAppData.htmlLang = parameters.htmlLang; if (parameters.htmlMetaTags !== undefined) crowdfundAppData.htmlMetaTags = parameters.htmlMetaTags; if (parameters.formId !== undefined) crowdfundAppData.formId = parameters.formId; if (parameters.perksTemplate !== undefined) crowdfundAppData.perksTemplate = parameters.perksTemplate; if (parameters.archived !== undefined) crowdfundAppData.archived = parameters.archived; return await this.client.createCrowdfundApp(parameters.storeId, crowdfundAppData); case 'getCrowdfund': return await this.client.getCrowdfundApp(parameters.appId); case 'updateCrowdfund': // Extract all update parameters and create the data object const updateCrowdfundData: any = {}; if (parameters.appName !== undefined) updateCrowdfundData.appName = parameters.appName; if (parameters.title !== undefined) updateCrowdfundData.title = parameters.title; if (parameters.description !== undefined) updateCrowdfundData.description = parameters.description; if (parameters.enabled !== undefined) updateCrowdfundData.enabled = parameters.enabled; if (parameters.targetAmount !== undefined) updateCrowdfundData.targetAmount = parameters.targetAmount; if (parameters.targetCurrency !== undefined) updateCrowdfundData.targetCurrency = parameters.targetCurrency; if (parameters.tagline !== undefined) updateCrowdfundData.tagline = parameters.tagline; if (parameters.archived !== undefined) updateCrowdfundData.archived = parameters.archived; return await this.client.updateCrowdfundApp(parameters.appId, updateCrowdfundData); default: throw new Error(`Method ${methodName} not implemented`); } } }

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/Abhijay007/btcpayserver-mcp'

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