Skip to main content
Glama

Sentry MCP

Official
by getsentry
url-utils.test.ts8.03 kB
import { describe, expect, it } from "vitest"; import { validateSentryHostThrows, validateAndParseSentryUrlThrows, validateOpenAiBaseUrlThrows, getIssueUrl, getIssuesSearchUrl, getTraceUrl, getEventsExplorerUrl, } from "./url-utils"; describe("url-utils", () => { describe("validateSentryHostThrows", () => { it("should accept valid hostnames", () => { expect(() => validateSentryHostThrows("sentry.io")).not.toThrow(); expect(() => validateSentryHostThrows("example.com")).not.toThrow(); expect(() => validateSentryHostThrows("localhost:8000")).not.toThrow(); expect(() => validateSentryHostThrows("sentry.example.com"), ).not.toThrow(); }); it("should reject hostnames with http protocol", () => { expect(() => validateSentryHostThrows("http://sentry.io")).toThrow( "SENTRY_HOST should only contain a hostname", ); expect(() => validateSentryHostThrows("http://example.com:8000")).toThrow( "SENTRY_HOST should only contain a hostname", ); }); it("should reject hostnames with https protocol", () => { expect(() => validateSentryHostThrows("https://sentry.io")).toThrow( "SENTRY_HOST should only contain a hostname", ); expect(() => validateSentryHostThrows("https://example.com:443")).toThrow( "SENTRY_HOST should only contain a hostname", ); }); }); describe("validateOpenAiBaseUrlThrows", () => { it("should accept valid HTTPS URLs", () => { expect(() => validateOpenAiBaseUrlThrows("https://api.openai.com/v1"), ).not.toThrow(); expect(() => validateOpenAiBaseUrlThrows( "https://custom.example.com/openai/deployments/model", ), ).not.toThrow(); }); it("should accept valid HTTP URLs for local development", () => { expect(() => validateOpenAiBaseUrlThrows("http://localhost:8080/v1"), ).not.toThrow(); }); it("should reject empty strings", () => { expect(() => validateOpenAiBaseUrlThrows(" ")).toThrow( "OPENAI base URL must not be empty.", ); }); it("should reject URLs with unsupported protocols", () => { expect(() => validateOpenAiBaseUrlThrows("ftp://example.com")).toThrow( "OPENAI base URL must use http or https scheme", ); }); it("should reject invalid URLs", () => { expect(() => validateOpenAiBaseUrlThrows("not-a-url")).toThrow( "OPENAI base URL must be a valid HTTP or HTTPS URL", ); }); }); describe("validateAndParseSentryUrlThrows", () => { it("should accept and parse valid HTTPS URLs", () => { expect(validateAndParseSentryUrlThrows("https://sentry.io")).toBe( "sentry.io", ); expect(validateAndParseSentryUrlThrows("https://example.com")).toBe( "example.com", ); expect(validateAndParseSentryUrlThrows("https://localhost:8000")).toBe( "localhost:8000", ); expect( validateAndParseSentryUrlThrows("https://sentry.example.com"), ).toBe("sentry.example.com"); expect(validateAndParseSentryUrlThrows("https://example.com:443")).toBe( "example.com", ); }); it("should reject URLs without protocol", () => { expect(() => validateAndParseSentryUrlThrows("sentry.io")).toThrow( "SENTRY_URL must be a full HTTPS URL", ); expect(() => validateAndParseSentryUrlThrows("example.com")).toThrow( "SENTRY_URL must be a full HTTPS URL", ); }); it("should reject HTTP URLs", () => { expect(() => validateAndParseSentryUrlThrows("http://sentry.io")).toThrow( "SENTRY_URL must be a full HTTPS URL", ); expect(() => validateAndParseSentryUrlThrows("http://example.com:8000"), ).toThrow("SENTRY_URL must be a full HTTPS URL"); }); it("should reject invalid URLs", () => { expect(() => validateAndParseSentryUrlThrows("https://")).toThrow( "SENTRY_URL must be a valid HTTPS URL", ); expect(() => validateAndParseSentryUrlThrows("https://[invalid-bracket"), ).toThrow("SENTRY_URL must be a valid HTTPS URL"); }); }); describe("getIssueUrl", () => { it("should handle regional URLs correctly for SaaS", () => { const result = getIssueUrl("us.sentry.io", "myorg", "PROJ-123"); expect(result).toBe("https://myorg.sentry.io/issues/PROJ-123"); }); it("should handle EU regional URLs correctly", () => { const result = getIssueUrl("eu.sentry.io", "myorg", "PROJ-456"); expect(result).toBe("https://myorg.sentry.io/issues/PROJ-456"); }); it("should handle standard sentry.io correctly", () => { const result = getIssueUrl("sentry.io", "myorg", "PROJ-789"); expect(result).toBe("https://myorg.sentry.io/issues/PROJ-789"); }); it("should handle self-hosted correctly", () => { const result = getIssueUrl("sentry.example.com", "myorg", "PROJ-123"); expect(result).toBe( "https://sentry.example.com/organizations/myorg/issues/PROJ-123", ); }); }); describe("getIssuesSearchUrl", () => { it("should handle regional URLs correctly for SaaS", () => { const result = getIssuesSearchUrl( "us.sentry.io", "myorg", "is:unresolved", "proj1", ); expect(result).toBe( "https://myorg.sentry.io/issues/?project=proj1&query=is%3Aunresolved", ); }); it("should handle EU regional URLs correctly", () => { const result = getIssuesSearchUrl("eu.sentry.io", "myorg", "is:resolved"); expect(result).toBe( "https://myorg.sentry.io/issues/?query=is%3Aresolved", ); }); it("should handle self-hosted correctly", () => { const result = getIssuesSearchUrl( "sentry.example.com", "myorg", "is:unresolved", "proj1", ); expect(result).toBe( "https://sentry.example.com/organizations/myorg/issues/?project=proj1&query=is%3Aunresolved", ); }); }); describe("getTraceUrl", () => { it("should handle regional URLs correctly for SaaS", () => { const result = getTraceUrl("us.sentry.io", "myorg", "abc123def456"); expect(result).toBe( "https://myorg.sentry.io/explore/traces/trace/abc123def456", ); }); it("should handle EU regional URLs correctly", () => { const result = getTraceUrl("eu.sentry.io", "myorg", "xyz789"); expect(result).toBe( "https://myorg.sentry.io/explore/traces/trace/xyz789", ); }); it("should handle self-hosted correctly", () => { const result = getTraceUrl("sentry.example.com", "myorg", "abc123"); expect(result).toBe( "https://sentry.example.com/organizations/myorg/explore/traces/trace/abc123", ); }); }); describe("getEventsExplorerUrl", () => { it("should handle regional URLs correctly for SaaS", () => { const result = getEventsExplorerUrl( "us.sentry.io", "myorg", "level:error", "errors", "proj1", ); expect(result).toBe( "https://myorg.sentry.io/explore/?query=level%3Aerror&dataset=errors&layout=table&project=proj1", ); }); it("should handle EU regional URLs correctly", () => { const result = getEventsExplorerUrl( "eu.sentry.io", "myorg", "level:warning", "spans", ); expect(result).toBe( "https://myorg.sentry.io/explore/?query=level%3Awarning&dataset=spans&layout=table", ); }); it("should handle self-hosted correctly", () => { const result = getEventsExplorerUrl( "sentry.example.com", "myorg", "level:error", "logs", "proj1", ); expect(result).toBe( "https://sentry.example.com/organizations/myorg/explore/?query=level%3Aerror&dataset=logs&layout=table&project=proj1", ); }); }); });

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/getsentry/sentry-mcp'

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