Skip to main content
Glama
kongyo2

GitHub URL MCP Server

github/build_url

Read-only

Convert GitHub owner and repository names into valid GitHub URLs with built-in validation. Ensure correct URL formatting for public, private, or non-existent repositories.

Instructions

Converts GitHub owner and repository name into a properly formatted GitHub URL with validation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ownerYesGitHub username or organization name (e.g., 'microsoft', 'facebook')
repoYesRepository name (e.g., 'vscode', 'react')

Implementation Reference

  • The main handler function 'buildGitHubUrl' that executes the tool logic: builds GitHub URL and validates repository status.
    export const buildGitHubUrl = async (args: { owner: string; repo: string }) => {
      const { owner, repo } = args;
    
      // Basic validation
      if (!owner.trim() || !repo.trim()) {
        throw new Error("Owner and repository name cannot be empty");
      }
    
      const url = `https://github.com/${owner}/${repo}`;
      const validation = await validateRepository(owner, repo);
    
      switch (validation.status) {
        case "error": {
          const errorInfo = validation.error ? ` (${validation.error})` : "";
          return `${url}\n\n❌ Error: Unable to verify repository${errorInfo}`;
        }
        case "not_found":
          return `${url}\n\n⚠️ Warning: Repository does not exist`;
        case "private":
          return `${url}\n\n🔒 Note: Repository exists but is private`;
        case "public":
          return url;
        default:
          return url;
      }
    };
  • Zod input schema defining 'owner' and 'repo' parameters with validation rules and descriptions.
      parameters: z.object({
        owner: z
          .string()
          .min(1, "Owner cannot be empty")
          .describe(
            "GitHub username or organization name (e.g., 'microsoft', 'facebook')",
          ),
        repo: z
          .string()
          .min(1, "Repository name cannot be empty")
          .describe("Repository name (e.g., 'vscode', 'react')"),
      }),
    });
  • src/server.ts:194-216 (registration)
    Tool registration via server.addTool, specifying name 'github/build_url', handler, schema, description, and annotations.
    server.addTool({
      annotations: {
        openWorldHint: false, // No external system interaction beyond validation
        readOnlyHint: true, // Does not modify any data
        title: "Build GitHub URL",
      },
      description:
        "Converts GitHub owner and repository name into a properly formatted GitHub URL with validation",
      execute: buildGitHubUrl,
      name: "github/build_url",
      parameters: z.object({
        owner: z
          .string()
          .min(1, "Owner cannot be empty")
          .describe(
            "GitHub username or organization name (e.g., 'microsoft', 'facebook')",
          ),
        repo: z
          .string()
          .min(1, "Repository name cannot be empty")
          .describe("Repository name (e.g., 'vscode', 'react')"),
      }),
    });
  • Helper function 'validateRepository' that checks repository existence and accessibility via HEAD requests to GitHub, distinguishing public/private/not_found/error statuses. Used by the tool handler.
    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 already provide readOnlyHint=true and openWorldHint=false, indicating this is a safe, deterministic operation. The description adds value by mentioning 'validation', which implies error-checking or formatting rules beyond basic concatenation, but does not detail specific behaviors like rate limits, authentication needs, or exact validation rules. 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, efficient sentence that front-loads the core purpose ('Converts GitHub owner and repository name into a properly formatted GitHub URL') and adds a useful detail ('with validation'). There is no wasted text, and every word contributes to understanding the tool's function.

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?

For a simple tool with 2 parameters, 100% schema coverage, and annotations indicating safety and determinism, the description is largely complete. It covers the purpose, hints at validation, and distinguishes from siblings. However, without an output schema, it could briefly mention the return type (e.g., a string URL) to enhance completeness, though this is a minor gap given the tool's simplicity.

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?

The input schema has 100% description coverage, with clear descriptions for both parameters (owner and repo). The description adds minimal semantics by contextualizing the parameters as 'GitHub owner and repository name' and hinting at validation, but does not provide additional details beyond what the schema already covers. With high schema coverage, the baseline score of 3 is appropriate.

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 action ('Converts'), the resources involved ('GitHub owner and repository name'), and the output ('properly formatted GitHub URL with validation'). It distinguishes itself from the sibling tool github/parse_url by focusing on construction rather than parsing of 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 owner and repository name' and 'validation', suggesting it should be used when you have these components and need a valid URL. However, it does not explicitly state when to use this tool versus alternatives like manual string concatenation or the sibling parse_url tool, nor does it provide exclusion criteria.

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