Skip to main content
Glama

YOURLS-MCP

by kesslerio
index.js8.15 kB
/** * Tool registration module */ import { z } from 'zod'; import createShortenUrlTool from './shortenUrl.js'; import createExpandUrlTool from './expandUrl.js'; import createUrlStatsTool from './urlStats.js'; import createDbStatsTool from './dbStats.js'; import createShortUrlAnalyticsTool from './shortUrlAnalytics.js'; import createContractUrlTool from './contractUrl.js'; import createUpdateUrlTool from './updateUrl.js'; import createChangeKeywordTool from './changeKeyword.js'; import createGetUrlKeywordTool from './getUrlKeyword.js'; import createDeleteUrlTool from './deleteUrl.js'; import createListUrlsTool from './listUrls.js'; import createGenerateQrCodeTool from './generateQrCode.js'; import createShortenWithAnalyticsTool from './shortenWithAnalytics.js'; import createCustomUrlTool from './createCustomUrl.js'; /** * Register all tools with the MCP server * * @param {object} server - MCP server instance * @param {object} yourlsClient - YOURLS API client */ export function registerTools(server, yourlsClient) { // Core YOURLS API tools const shortenUrlTool = createShortenUrlTool(yourlsClient); const expandUrlTool = createExpandUrlTool(yourlsClient); const urlStatsTool = createUrlStatsTool(yourlsClient); const dbStatsTool = createDbStatsTool(yourlsClient); // Plugin-based API tools const shortUrlAnalyticsTool = createShortUrlAnalyticsTool(yourlsClient); const contractUrlTool = createContractUrlTool(yourlsClient); const updateUrlTool = createUpdateUrlTool(yourlsClient); const changeKeywordTool = createChangeKeywordTool(yourlsClient); const getUrlKeywordTool = createGetUrlKeywordTool(yourlsClient); const deleteUrlTool = createDeleteUrlTool(yourlsClient); const listUrlsTool = createListUrlsTool(yourlsClient); const generateQrCodeTool = createGenerateQrCodeTool(yourlsClient); const customUrlTool = createCustomUrlTool(yourlsClient); // Helper function to convert schema to zod properties const schemaToZodProperties = (schema) => { if (!schema || !schema.properties) { return {}; } const zodProps = {}; // Convert each property to a zod schema Object.keys(schema.properties).forEach(key => { const prop = schema.properties[key]; const isRequired = schema.required && schema.required.includes(key); let zodProp = z.string(); // Add description if available if (prop.description) { zodProp = zodProp.describe(prop.description); } // Make optional if not required if (!isRequired) { zodProp = zodProp.optional(); } zodProps[key] = zodProp; }); return zodProps; }; // Register core tools using server.tool() method server.tool( shortenUrlTool.name, shortenUrlTool.description, { url: shortenUrlTool.inputSchema.properties.url.description ? z.string().describe(shortenUrlTool.inputSchema.properties.url.description) : z.string(), keyword: shortenUrlTool.inputSchema.properties.keyword.description ? z.string().optional().describe(shortenUrlTool.inputSchema.properties.keyword.description) : z.string().optional(), title: shortenUrlTool.inputSchema.properties.title.description ? z.string().optional().describe(shortenUrlTool.inputSchema.properties.title.description) : z.string().optional() }, shortenUrlTool.execute ); server.tool( expandUrlTool.name, expandUrlTool.description, { shorturl: expandUrlTool.inputSchema.properties.shorturl.description ? z.string().describe(expandUrlTool.inputSchema.properties.shorturl.description) : z.string() }, expandUrlTool.execute ); server.tool( urlStatsTool.name, urlStatsTool.description, { shorturl: urlStatsTool.inputSchema.properties.shorturl.description ? z.string().describe(urlStatsTool.inputSchema.properties.shorturl.description) : z.string() }, urlStatsTool.execute ); server.tool( dbStatsTool.name, dbStatsTool.description, {}, dbStatsTool.execute ); // Register plugin-based tools server.tool( shortUrlAnalyticsTool.name, shortUrlAnalyticsTool.description, { shorturl: z.string().describe('The short URL to get analytics for'), period: z.string().optional().describe('The time period for analytics (e.g., "day", "week", "month")') }, shortUrlAnalyticsTool.execute ); server.tool( contractUrlTool.name, contractUrlTool.description, { url: z.string().describe('The URL to check if it exists in the database') }, contractUrlTool.execute ); server.tool( updateUrlTool.name, updateUrlTool.description, { shorturl: z.string().describe('The short URL or keyword to update'), url: z.string().describe('The new destination URL'), title: z.string().optional().describe('Optional new title for the URL') }, updateUrlTool.execute ); server.tool( changeKeywordTool.name, changeKeywordTool.description, { oldshorturl: z.string().describe('The existing short URL or keyword'), newshorturl: z.string().describe('The new keyword to use'), title: z.string().optional().describe('Optional new title') }, changeKeywordTool.execute ); server.tool( getUrlKeywordTool.name, getUrlKeywordTool.description, { url: z.string().describe('The URL to find keywords for'), exactly_one: z.boolean().optional().describe('Whether to return only one result (default: false)') }, getUrlKeywordTool.execute ); server.tool( deleteUrlTool.name, deleteUrlTool.description, { shorturl: z.string().describe('The short URL or keyword to delete') }, deleteUrlTool.execute ); server.tool( listUrlsTool.name, listUrlsTool.description, { sortby: z.string().optional().describe('Field to sort by (e.g., "clicks", "timestamp")'), sortorder: z.string().optional().describe('Sort order ("asc" or "desc")'), perpage: z.number().optional().describe('Number of results per page'), page: z.number().optional().describe('Page number'), search: z.string().optional().describe('Search term to filter results') }, listUrlsTool.execute ); server.tool( generateQrCodeTool.name, generateQrCodeTool.description, { shorturl: z.string().describe('The short URL to generate a QR code for'), size: z.number().optional().describe('Size of the QR code in pixels'), format: z.string().optional().describe('Image format (png, svg, etc.)'), margin: z.number().optional().describe('Margin size') }, generateQrCodeTool.execute ); server.tool( customUrlTool.name, customUrlTool.description, { url: z.string().describe('The URL to shorten'), keyword: z.string().describe('The custom keyword for the short URL'), title: z.string().optional().describe('Optional title for the URL'), force_url_modification: z.boolean().optional().describe('Whether to force URL modification to allow duplicates') }, customUrlTool.execute ); // Register Google Analytics integration tool const shortenWithAnalyticsTool = createShortenWithAnalyticsTool(yourlsClient); server.tool( shortenWithAnalyticsTool.name, shortenWithAnalyticsTool.description, { url: z.string().describe('The URL to shorten'), keyword: z.string().optional().describe('Optional custom keyword for the short URL'), title: z.string().optional().describe('Optional title for the URL'), utm_source: z.string().describe('UTM source parameter'), utm_medium: z.string().describe('UTM medium parameter'), utm_campaign: z.string().optional().describe('UTM campaign parameter'), utm_term: z.string().optional().describe('UTM term parameter'), utm_content: z.string().optional().describe('UTM content parameter') }, shortenWithAnalyticsTool.execute ); }

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/kesslerio/yourls-mcp'

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