mcp.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import { McpResource, McpResourceTemplate } from "../../../src/shared/mcp"
  2. /**
  3. * Matches a URI against an array of URI templates and returns the matching template
  4. * @param uri The URI to match
  5. * @param templates Array of URI templates to match against
  6. * @returns The matching template or undefined if no match is found
  7. */
  8. export function findMatchingTemplate(
  9. uri: string,
  10. templates: McpResourceTemplate[] = [],
  11. ): McpResourceTemplate | undefined {
  12. return templates.find((template) => {
  13. // Convert template to regex pattern
  14. const pattern = String(template.uriTemplate)
  15. // First escape special regex characters
  16. .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  17. // Then replace {param} with ([^/]+) to match any non-slash characters
  18. // We need to use \{ and \} because we just escaped them
  19. .replace(/\\\{([^}]+)\\\}/g, "([^/]+)")
  20. const regex = new RegExp(`^${pattern}$`)
  21. return regex.test(uri)
  22. })
  23. }
  24. /**
  25. * Finds either an exact resource match or a matching template for a given URI
  26. * @param uri The URI to find a match for
  27. * @param resources Array of concrete resources
  28. * @param templates Array of resource templates
  29. * @returns The matching resource, template, or undefined
  30. */
  31. export function findMatchingResourceOrTemplate(
  32. uri: string,
  33. resources: McpResource[] = [],
  34. templates: McpResourceTemplate[] = [],
  35. ): McpResource | McpResourceTemplate | undefined {
  36. // First try to find an exact resource match
  37. const exactMatch = resources.find((resource) => resource.uri === uri)
  38. if (exactMatch) return exactMatch
  39. // If no exact match, try to find a matching template
  40. return findMatchingTemplate(uri, templates)
  41. }