Skip to main content
Glama

tbls MCP Server

by yhosok
uri-patterns-resource.ts6.28 kB
import { Result, ok } from 'neverthrow'; import { UriPatternsResource, UriPatternInfo } from '../schemas/database'; import { ResourcePatterns, ResourcePattern } from '../server/resource-patterns'; import { PATTERN_IDS } from '../constants/uri-patterns'; /** * Convert a ResourcePattern to UriPatternInfo format */ function convertResourcePatternToUriPatternInfo( pattern: ResourcePattern ): UriPatternInfo { const uriPattern = convertUriPatternToSnakeCase(pattern.uriPattern); const parameters = extractParametersFromUriPattern(uriPattern); const examples = generateExamplesForPattern(pattern); return { id: pattern.id, uri: uriPattern, description: convertDescriptionForDisplay( pattern.id, pattern.descriptionPattern ), examples, parameters, }; } /** * Create the URI patterns resource entry itself */ function createUriPatternsResourceEntry(): UriPatternInfo { return { id: PATTERN_IDS.URI_PATTERNS, uri: 'db://uri-patterns', description: 'List of all available URI patterns supported by the MCP server', examples: ['db://uri-patterns'], parameters: [], }; } /** * Handles the db://uri-patterns MCP resource * Returns a list of all available URI patterns supported by the server * * @returns Result containing URI patterns resource or error */ export const handleUriPatternsResource = async (): Promise< Result<UriPatternsResource, Error> > => { const allPatterns = ResourcePatterns.getAllPatterns(); // Convert ResourcePattern objects to UriPatternInfo format const patterns: UriPatternInfo[] = allPatterns.map( convertResourcePatternToUriPatternInfo ); // Add the URI patterns resource itself patterns.push(createUriPatternsResourceEntry()); // Sort patterns by ID for consistent ordering patterns.sort((a, b) => a.id.localeCompare(b.id)); return ok({ patterns }); }; /** * Description mappings for consistent display text */ const DESCRIPTION_OVERRIDES: Record<string, string> = { [PATTERN_IDS.SCHEMA_LIST]: 'Complete list of all available database schemas with metadata including schema names, table counts, and version information.', [PATTERN_IDS.SCHEMA_TABLES]: 'Comprehensive list of all tables within the {schema_name} schema, including table metadata, row counts, and basic structure information.', [PATTERN_IDS.SCHEMA_INFO]: 'Information about the {schema_name} schema. This URI redirects to db://schemas/{schema_name}/tables.', [PATTERN_IDS.TABLE_INFO]: 'Complete detailed information about the {table_name} table including column definitions with data types, constraints, indexes, foreign key relationships, and table statistics.', [PATTERN_IDS.TABLE_INDEXES]: 'Detailed index information for the {table_name} table including index names, types (primary, unique, regular), column compositions, and performance statistics.', }; /** * Convert description to match test expectations */ function convertDescriptionForDisplay( patternId: string, originalDescription: string ): string { return DESCRIPTION_OVERRIDES[patternId] ?? originalDescription; } /** * Parameter name conversion mapping for consistency */ const PARAMETER_CONVERSIONS: Record<string, string> = { '{schemaName}': '{schema_name}', '{tableName}': '{table_name}', }; /** * Convert URI pattern from camelCase to snake_case for parameter names */ function convertUriPatternToSnakeCase(uriPattern: string): string { let result = uriPattern; Object.entries(PARAMETER_CONVERSIONS).forEach(([from, to]) => { result = result.replace(new RegExp(from.replace(/[{}]/g, '\\$&'), 'g'), to); }); return result; } /** * Parameter description mapping for consistent parameter documentation */ const PARAMETER_DESCRIPTIONS: Record<string, string> = { schema_name: 'Name of the database schema', table_name: 'Name of the database table', }; /** * Generate parameter description based on parameter name */ function generateParameterDescription(paramName: string): string { if (PARAMETER_DESCRIPTIONS[paramName]) { return PARAMETER_DESCRIPTIONS[paramName]; } // Fallback: convert underscore to space and add "parameter" return `${paramName.replace(/_/g, ' ')} parameter`; } /** * Extract parameter definitions from a URI pattern string */ function extractParametersFromUriPattern(uriPattern: string): Array<{ name: string; description: string; required: boolean; }> { const parameterMatches = uriPattern.match(/\{([^}]+)\}/g); if (!parameterMatches) { return []; } return parameterMatches.map((match) => { const paramName = match.slice(1, -1); // Remove { and } return { name: paramName, description: generateParameterDescription(paramName), required: true, }; }); } /** * Example mappings for each pattern type */ const PATTERN_EXAMPLES: Record<string, string[]> = { [PATTERN_IDS.SCHEMA_LIST]: ['db://schemas'], [PATTERN_IDS.SCHEMA_TABLES]: [ 'db://schemas/public/tables', 'db://schemas/default/tables', ], [PATTERN_IDS.SCHEMA_INFO]: ['db://schemas/public', 'db://schemas/default'], [PATTERN_IDS.TABLE_INFO]: [ 'db://schemas/public/tables/users', 'db://schemas/default/tables/products', ], [PATTERN_IDS.TABLE_INDEXES]: [ 'db://schemas/public/tables/users/indexes', 'db://schemas/default/tables/products/indexes', ], }; /** * Example values for parameter replacement in fallback generation */ const EXAMPLE_PARAMETER_VALUES: Record<string, string> = { schemaName: 'public', tableName: 'users', }; /** * Generate fallback examples by replacing parameters with example values */ function generateFallbackExamples(uriPattern: string): string[] { let example = uriPattern; Object.entries(EXAMPLE_PARAMETER_VALUES).forEach(([param, value]) => { example = example.replace(new RegExp(`\\{${param}\\}`, 'g'), value); }); return [example]; } /** * Generate example URIs for a given pattern */ function generateExamplesForPattern(pattern: ResourcePattern): string[] { const predefinedExamples = PATTERN_EXAMPLES[pattern.id]; if (predefinedExamples) { return predefinedExamples; } // Fallback: replace parameters with example values return generateFallbackExamples(pattern.uriPattern); }

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/yhosok/tbls-mcp-server'

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