Skip to main content
Glama

get_url_keyword

Extract keywords from a long URL to identify its unique short link identifier. Optionally return a single result for precise URL management within the YOURLS-MCP server.

Instructions

Get the keyword(s) for a long URL

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exactly_oneNoWhether to return only one result (default: false)
urlYesThe URL to find keywords for

Implementation Reference

  • The execute handler function that implements the core logic of the 'get_url_keyword' tool, processing input, calling the YOURLS client, and formatting the response.
    execute: async ({ url, exactly_one = true }) => { try { // Normalize boolean parameter if it's passed as a string if (typeof exactly_one === 'string') { exactly_one = exactly_one.toLowerCase() === 'true'; } // Use the getUrlKeyword method with fallback enabled const result = await yourlsClient.getUrlKeyword(url, exactly_one, true); if (result.status === 'success' || result.message === 'success: found') { const responseData = { url: url }; // Add keyword information based on response format if (exactly_one && result.keyword) { responseData.keyword = result.keyword; if (result.shorturl) responseData.shorturl = result.shorturl; if (result.title) responseData.title = result.title; } else if (!exactly_one && result.keywords) { responseData.keywords = result.keywords; } // Add message if available if (result.simple) responseData.message = result.simple; // Add fallback information if applicable if (result.fallback_used) { responseData.fallback_used = true; if (result.fallback_limitations) { responseData.fallback_limitations = result.fallback_limitations; } } return createMcpResponse(true, responseData); } else { throw new Error(result.message || 'Unknown error'); } } catch (error) { return createMcpResponse(false, { message: error.message, url: url }); } }
  • Input schema definition for the 'get_url_keyword' tool parameters.
    inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'The long URL to look up' }, exactly_one: { type: 'boolean', description: 'If false, returns all keywords for this URL (default: true)' } }, required: ['url'] },
  • src/index.js:211-217 (registration)
    Registration of the 'get_url_keyword' tool with the MCP server, including Zod schema conversion and binding the execute handler.
    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
  • The YourlsClient.getUrlKeyword method called by the tool handler, with plugin detection and fallback logic.
    async getUrlKeyword(url, exactlyOne = true, useNativeFallback = true) { const params = { url }; if (!exactlyOne) { params.exactly_one = 'false'; } try { // First check if the plugin is available const isAvailable = await isPluginAvailable(this, 'edit_url', 'geturl', { url: 'https://example.com' }); if (isAvailable) { return this.request('geturl', params); } else if (useNativeFallback) { // Use our fallback implementation return this._getUrlKeywordFallback(url, exactlyOne); } else { throw new Error('The geturl action is not available. Please install the API Edit URL plugin.'); } } catch (error) { // If the error is not about a missing plugin, re-throw it if (!isPluginMissingError(error)) { throw error; } // If we're here, the plugin is missing and we need to use the fallback if (useNativeFallback) { return this._getUrlKeywordFallback(url, exactlyOne); } else { throw new Error('The geturl action is not available. Please install the API Edit URL plugin.'); } }
  • Fallback implementation _getUrlKeywordFallback used when the API Edit URL plugin is unavailable, searches via stats API.
    async _getUrlKeywordFallback(url, exactlyOne) { try { // Safety limit to prevent performance issues const MAX_RESULTS = 1000; // We can try to use the stats action with a filter const listResult = await this.request('stats', { limit: MAX_RESULTS, filter: 'url', search: encodeURIComponent(url) }); // Process the results to match the geturl plugin's output format const keywords = []; let urlExists = false; if (listResult.links) { // Iterate through the results and find exact URL matches for (const [keyword, data] of Object.entries(listResult.links)) { if (data.url === url) { urlExists = true; keywords.push({ keyword: keyword, shorturl: `${this.api_url.replace('yourls-api.php', '')}${keyword}`, title: data.title, url: data.url, date: data.timestamp, ip: data.ip, clicks: data.clicks }); // If we only want one result and we found it, break if (exactlyOne) { break; } } } } // Format the response similarly to what the geturl plugin would return if (urlExists) { if (exactlyOne && keywords.length > 0) { // Return just the first match return { status: 'success', keyword: keywords[0].keyword, url: keywords[0].url, title: keywords[0].title, shorturl: keywords[0].shorturl, message: 'success', ...createFallbackInfo('Search limited to latest URLs', false, 'API Edit URL') }; } else { // Return all matches return { status: 'success', keywords: keywords, url: url, message: 'success', ...createFallbackInfo('Search limited to latest URLs', false, 'API Edit URL') }; } } else { // No matches found return { status: 'fail', message: 'URL not found', ...createFallbackInfo('Search limited to latest URLs', false, 'API Edit URL') }; } } catch (error) { console.error('Get URL keyword fallback error:', error.message); // In case of fallback failure, return a safe default return { status: 'fail', message: 'Error looking up URL: ' + error.message, ...createFallbackInfo('Error during fallback search', true, 'API Edit URL') }; } }

Other Tools

Related Tools

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

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