Skip to main content
Glama
kongyo2

GitHub URL MCP Server

github/parse_url

Read-only

Extract and validate owner, repository name, and path details from any GitHub URL for accurate repository parsing and integration workflows.

Instructions

Parses a GitHub URL to extract owner, repository name, and additional path information with validation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesGitHub URL to parse (e.g., 'https://github.com/microsoft/vscode' or 'https://github.com/facebook/react/tree/main/packages')

Implementation Reference

  • The main handler function that executes the tool logic: parses the GitHub URL, validates repository status, constructs result object, and returns formatted JSON string based on validation outcome.
    export const parseGitHubUrlTool = async (args: { url: string }) => {
      const parsed = parseGitHubUrl(args.url);
      const validation = await validateRepository(parsed.owner, parsed.repo);
    
      const result = {
        owner: parsed.owner,
        repo: parsed.repo,
        status: validation.status,
        url: `https://github.com/${parsed.owner}/${parsed.repo}`,
        ...(parsed.path && { additionalPath: parsed.path }),
      };
    
      switch (validation.status) {
        case "error": {
          const errorInfo = validation.error ? ` (${validation.error})` : "";
          return JSON.stringify({
            ...result,
            accessible: false,
            error: `Unable to verify repository${errorInfo}`,
          });
        }
        case "not_found":
          return JSON.stringify({
            ...result,
            accessible: false,
            warning: "Repository does not exist",
          });
        case "private":
          return JSON.stringify({
            ...result,
            accessible: false,
            note: "Repository exists but is private",
          });
        case "public":
          return JSON.stringify({
            ...result,
            accessible: true,
          });
        default:
          return JSON.stringify(result);
      }
    };
  • Zod schema defining the input parameters for the tool: a single 'url' string that must be a valid URL with description.
    parameters: z.object({
      url: z
        .string()
        .url("Must be a valid URL")
        .describe(
          "GitHub URL to parse (e.g., 'https://github.com/microsoft/vscode' or 'https://github.com/facebook/react/tree/main/packages')",
        ),
    }),
  • src/server.ts:219-237 (registration)
    Registers the 'github/parse_url' tool with FastMCP server, specifying name, description, annotations, input schema, and handler function.
    server.addTool({
      annotations: {
        openWorldHint: false, // No external system interaction beyond validation
        readOnlyHint: true, // Does not modify any data
        title: "Parse GitHub URL",
      },
      description:
        "Parses a GitHub URL to extract owner, repository name, and additional path information with validation",
      execute: parseGitHubUrlTool,
      name: "github/parse_url",
      parameters: z.object({
        url: z
          .string()
          .url("Must be a valid URL")
          .describe(
            "GitHub URL to parse (e.g., 'https://github.com/microsoft/vscode' or 'https://github.com/facebook/react/tree/main/packages')",
          ),
      }),
    });
  • Helper function that performs the core URL parsing: extracts owner, repo, and optional additional path from the GitHub URL pathname, with validation for format and domain.
    const parseGitHubUrl = (
      urlString: string,
    ): { owner: string; path?: string; repo: string } => {
      let url: URL;
    
      try {
        url = new URL(urlString);
      } catch {
        throw new Error("Invalid URL format");
      }
    
      if (url.hostname !== "github.com") {
        throw new Error("URL must be from github.com domain");
      }
    
      const pathParts = url.pathname.slice(1).split("/").filter(Boolean);
    
      if (pathParts.length < 2) {
        throw new Error(
          "URL must contain both owner and repository name (e.g., https://github.com/owner/repo)",
        );
      }
    
      const [owner, repo, ...remainingPath] = pathParts;
    
      if (!owner || !repo) {
        throw new Error("Invalid owner or repository name in URL");
      }
    
      return {
        owner,
        path: remainingPath.length > 0 ? remainingPath.join("/") : undefined,
        repo,
      };
    };
  • Helper function that validates repository existence and accessibility using HEAD requests to GitHub, distinguishing between not found, private, public, and errors with timeout handling.
    const validateRepository = async (
      owner: string,
      repo: string,
    ): Promise<{
      error?: string;
      exists: boolean;
      isPrivate?: boolean;
      status: "error" | "not_found" | "private" | "public";
    }> => {
      try {
        const response = await fetch(`https://github.com/${owner}/${repo}`, {
          method: "HEAD",
          // Add timeout to prevent hanging
          signal: AbortSignal.timeout(5000),
        });
    
        if (response.status === 200) {
          return {
            exists: true,
            isPrivate: false,
            status: "public",
          };
        } else if (response.status === 404) {
          // 404 can mean either the repo doesn't exist or it's private
          // Try to access the owner's profile to distinguish
          const ownerResponse = await fetch(`https://github.com/${owner}`, {
            method: "HEAD",
            signal: AbortSignal.timeout(5000),
          });
    
          if (ownerResponse.status === 200) {
            // Owner exists, so the repo is likely private
            return {
              exists: true,
              isPrivate: true,
              status: "private",
            };
          } else {
            // Owner doesn't exist, so repo doesn't exist
            return {
              exists: false,
              status: "not_found",
            };
          }
        } else {
          // Other status codes (403, 500, etc.)
          return {
            error: `HTTP ${response.status}`,
            exists: false,
            status: "error",
          };
        }
      } catch (error) {
        const errorMessage =
          error instanceof Error ? error.message : "Unknown error";
        return {
          error: errorMessage.includes("timeout")
            ? "Request timeout"
            : "Network error",
          exists: false,
          status: "error",
        };
      }
    };
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=true and openWorldHint=false, which already inform the agent that this is a safe, deterministic read operation. The description adds value by specifying 'with validation', which is a behavioral trait not covered by annotations, but does not detail error handling, rate limits, or output format. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that efficiently conveys the tool's purpose, what it extracts, and a key behavioral trait ('with validation'). It is front-loaded with essential information and has no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (single parameter, no output schema, simple annotations), the description is mostly complete. It covers the parsing action and validation, but could benefit from mentioning the output structure (e.g., what fields are returned) since there is no output schema. However, it adequately addresses the core functionality.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the parameter 'url' fully documented in the schema including examples. The description adds minimal semantic context by mentioning what is extracted from the URL, but does not provide additional details beyond what the schema already covers. Baseline 3 is appropriate given high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific verb 'parses' and the resource 'GitHub URL', and specifies what it extracts: 'owner, repository name, and additional path information with validation'. It distinguishes from the sibling tool 'github/build_url' by focusing on parsing rather than constructing URLs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by mentioning 'GitHub URL' and providing examples, but does not explicitly state when to use this tool versus alternatives like the sibling 'github/build_url' or other parsing methods. It gives clear context for when to use it (parsing GitHub URLs) but lacks explicit exclusions or comparisons.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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/kongyo2/GitHub-URL-MCP'

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