contract_url
Verify if a URL is already shortened in the YOURLS database to avoid duplicate entries, ensuring efficient URL management.
Instructions
Check if a URL has already been shortened without creating a new short URL
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The URL to check if it exists in the database |
Implementation Reference
- src/index.js:179-185 (registration)Registration of the 'contract_url' MCP tool, including inline Zod input schema validation for the 'url' parameter and references the execute handler.server.tool( contractUrlTool.name, contractUrlTool.description, { url: z.string().describe('The URL to check if it exists in the database') }, contractUrlTool.execute
- src/tools/index.js:133-140 (registration)Alternative registration of the 'contract_url' MCP tool in tools index module, with inline schema and execute handler reference.server.tool( contractUrlTool.name, contractUrlTool.description, { url: z.string().describe('The URL to check if it exists in the database') }, contractUrlTool.execute );
- src/api.js:428-455 (helper)Core implementation of contract URL check in YourlsClient, attempts to use 'contract' plugin API or falls back to native search if unavailable. This is the logic the tool handler would invoke.async contractUrl(url, useNativeFallback = true) { try { // First try using the Contract plugin const isAvailable = await isPluginAvailable(this, 'contract', 'contract', { url: 'https://example.com' }); if (isAvailable) { return this.request('contract', { url }); } else if (useNativeFallback) { // Plugin isn't available, use our fallback implementation return this._contractUrlFallback(url); } else { throw new Error('The contract action is not available. Please install the API Contract plugin.'); } } catch (error) { // If the error is from the plugin check or request, but not a missing plugin error, // pass it through if (!isPluginMissingError(error)) { throw error; } // If we're here, the plugin is missing and we need to use our fallback if (useNativeFallback) { return this._contractUrlFallback(url); } else { throw new Error('The contract action is not available. Please install the API Contract plugin.'); } } }
- src/api.js:464-516 (helper)Fallback implementation for contract URL check using YOURLS stats API to search for existing short links matching the given URL.async _contractUrlFallback(url) { try { // Safety limit to prevent performance issues const MAX_RESULTS = 1000; // We can try to use the stats action with a limited results count // and filter for the URL we're looking for const listResult = await this.request('stats', { limit: MAX_RESULTS, filter: 'url', search: encodeURIComponent(url) }); // Process the results to match the Contract plugin's output format const links = []; 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; links.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 }); } } } return { message: 'success', url_exists: urlExists, links: links, ...createFallbackInfo('Uses stats API, may be slower for large databases', false, 'API Contract') }; } catch (error) { console.error('Contract URL fallback error:', error.message); // In case of fallback failure, return a safe default return { message: 'success', url_exists: false, links: [], ...createFallbackInfo('Unable to search database completely', true, 'API Contract') }; } }