Skip to main content
Glama
jankowtf

MCP Server Template for Cursor IDE

by jankowtf

fetch_railway_docs_optimized

Retrieve Railway CLI documentation directly within Cursor IDE. This tool fetches up-to-date documentation to help developers access CLI commands and usage information without leaving their development environment.

Instructions

Fetches the most recent Railway CLI documentation. Optionally, provide a custom URL.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlNoOptional custom URL for fetching Railway CLI docs.

Implementation Reference

  • The core handler function that fetches Railway CLI documentation from the given URL, parses the HTML using BeautifulSoup to extract CLI commands from headings and lists/code blocks, and returns optimized text content.
    async def fetch_railway_docs_optimized(
        url: str = "https://docs.railway.app/guides/cli",
    ) -> list[types.TextContent]:
        headers = {
            "User-Agent": "MCP Railway Docs Fetcher (github.com/modelcontextprotocol/python-sdk)"
        }
    
        try:
            timeout = httpx.Timeout(10.0, connect=5.0)
            async with httpx.AsyncClient(
                follow_redirects=True, headers=headers, timeout=timeout
            ) as client:
                response = await client.get(url)
                response.raise_for_status()
    
                # Parse HTML content
                soup = BeautifulSoup(response.text, "html.parser")
                content = []
    
                # Try to find any command sections
                for heading in soup.find_all(["h1", "h2", "h3", "h4"]):
                    heading_text = heading.get_text(strip=True).lower()
                    if any(
                        keyword in heading_text for keyword in ["command", "cli", "usage"]
                    ):
                        # Look for the next element that might contain commands
                        next_elem = heading.find_next_sibling()
                        while next_elem and next_elem.name not in [
                            "ul",
                            "ol",
                            "h1",
                            "h2",
                            "h3",
                            "h4",
                        ]:
                            next_elem = next_elem.find_next_sibling()
    
                        if next_elem and next_elem.name in ["ul", "ol"]:
                            commands = []
                            for li in next_elem.find_all("li"):
                                cmd_text = li.get_text(strip=True)
                                if cmd_text:  # Only add non-empty commands
                                    commands.append(cmd_text)
    
                            if commands:  # Only add sections that have commands
                                content.append(f"\n{heading.get_text(strip=True)}:")
                                content.extend(f"- {cmd}" for cmd in commands)
    
                if content:
                    return [types.TextContent(type="text", text="\n".join(content))]
    
                # If we couldn't find any command sections, try to extract any code blocks
                code_blocks = soup.find_all(["pre", "code"])
                if code_blocks:
                    content = ["Railway CLI Commands:"]
                    for block in code_blocks:
                        code_text = block.get_text(strip=True)
                        if code_text and any(
                            keyword in code_text.lower() for keyword in ["railway", "cli"]
                        ):
                            content.append(code_text)
                    return [types.TextContent(type="text", text="\n".join(content))]
    
                # If still nothing found, return a more helpful message
                return [
                    types.TextContent(
                        type="text",
                        text="Could not find any CLI commands in the documentation. The page structure might have changed.",
                    )
                ]
        except Exception as e:
            return [
                types.TextContent(
                    type="text",
                    text=f"Error: Failed to fetch or parse Railway CLI docs: {str(e)}",
                )
            ]
  • Dispatch registration in the @app.call_tool() handler (fetch_tool function) that routes calls to the fetch_railway_docs_optimized function when the tool name matches.
    if name == "fetch_railway_docs_optimized":
        url = arguments.get("url", "https://docs.railway.app/guides/cli")
        return await fetch_railway_docs_optimized(url)
  • Tool schema and metadata registration in the @app.list_tools() function, defining the tool name, description, and optional 'url' input schema.
    types.Tool(
        name="fetch_railway_docs_optimized",
        description="Fetches the most recent Railway CLI documentation. Optionally, provide a custom URL.",
        inputSchema={
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "Optional custom URL for fetching Railway CLI docs.",
                },
            },
        },
    ),

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/jankowtf/mcp-hitchcode'

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