Skip to main content
Glama
registry.ts4.89 kB
/** * WP Navigator MCP Resource Registry * * Central registry for managing MCP resources. * Supports static resources (fixed URIs) and dynamic resources (pattern-based). * * @package WP_Navigator_MCP * @since 2.6.0 */ import type { StaticResource, DynamicResourceTemplate, ResourceContent, ResourceGeneratorContext, StaticResourceGenerator, DynamicResourceGenerator, } from './types.js'; /** * Resource Registry * * Manages registration and lookup of MCP resources. * Similar pattern to ToolRegistry but for read-only resources. */ export class ResourceRegistry { private staticResources: Map<string, StaticResource> = new Map(); private staticGenerators: Map<string, StaticResourceGenerator> = new Map(); private dynamicTemplates: DynamicResourceTemplate[] = []; private dynamicGenerators: Map<string, DynamicResourceGenerator> = new Map(); /** * Register a static resource with its content generator */ registerStatic(resource: StaticResource, generator: StaticResourceGenerator): void { this.staticResources.set(resource.uri, resource); this.staticGenerators.set(resource.uri, generator); } /** * Register a dynamic resource template with its content generator * * Dynamic resources are pattern-based and expand to multiple URIs at runtime. * The generator receives the full URI and must parse the slug from it. */ registerDynamic(template: DynamicResourceTemplate, generator: DynamicResourceGenerator): void { this.dynamicTemplates.push(template); // Use pattern source as key for generator lookup this.dynamicGenerators.set(template.uriPattern.source, generator); } /** * List all available resources (for ListResources response) * * Returns both static resources and expanded dynamic resources. */ listResources(): Array<{ uri: string; name: string; description?: string; mimeType?: string }> { const resources: Array<{ uri: string; name: string; description?: string; mimeType?: string; }> = []; // Add static resources for (const resource of this.staticResources.values()) { resources.push({ uri: resource.uri, name: resource.name, description: resource.description, mimeType: resource.mimeType, }); } // Add dynamic resources by calling listUris for each template for (const template of this.dynamicTemplates) { try { const uris = template.listUris(); for (const uri of uris) { const slug = this.extractSlug(uri, template.uriPattern); if (slug) { const meta = template.getResourceMeta(slug); if (meta) { resources.push({ uri, name: meta.name, description: meta.description, mimeType: template.mimeType, }); } } } } catch { // Skip templates that fail to list URIs continue; } } return resources; } /** * Read a specific resource by URI * * Tries static resources first, then dynamic templates. */ async readResource( uri: string, context: ResourceGeneratorContext ): Promise<ResourceContent | null> { // Try static resource first const staticGenerator = this.staticGenerators.get(uri); if (staticGenerator) { return staticGenerator(context); } // Try dynamic templates for (const template of this.dynamicTemplates) { if (template.uriPattern.test(uri)) { const dynamicGenerator = this.dynamicGenerators.get(template.uriPattern.source); if (dynamicGenerator) { return dynamicGenerator(uri, context); } } } return null; } /** * Check if a resource exists */ hasResource(uri: string): boolean { // Check static if (this.staticResources.has(uri)) { return true; } // Check dynamic for (const template of this.dynamicTemplates) { if (template.uriPattern.test(uri)) { return true; } } return false; } /** * Get the count of registered resources */ getResourceCount(): { static: number; dynamicTemplates: number } { return { static: this.staticResources.size, dynamicTemplates: this.dynamicTemplates.length, }; } /** * Clear all registered resources (useful for testing) */ clear(): void { this.staticResources.clear(); this.staticGenerators.clear(); this.dynamicTemplates = []; this.dynamicGenerators.clear(); } /** * Extract slug from URI using pattern */ private extractSlug(uri: string, pattern: RegExp): string | null { const match = uri.match(pattern); return match?.[1] || null; } } /** * Singleton resource registry instance */ export const resourceRegistry = new ResourceRegistry();

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/littlebearapps/wp-navigator-mcp'

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