Skip to main content
Glama
COMPARISON.md9.17 kB
# MCP4GVA - Python vs TypeScript Comparison This repository contains **two implementations** of the same MCP server for the GVA GIS ArcGIS API: 1. **Python version** (root directory) - Uses `uvx` 2. **TypeScript version** (`typescript/` directory) - Uses `npx` Both implementations provide identical functionality, allowing you to compare approaches and learn from the differences. ## Quick Comparison | Feature | Python | TypeScript | |---------|--------|------------| | **Location** | Root directory | `typescript/` directory | | **Runtime** | Python 3.10+ | Node.js 18+ | | **Package Manager** | uv/uvx | npm/npx | | **MCP SDK** | `mcp` | `@modelcontextprotocol/sdk` | | **HTTP Client** | `requests` | `node-fetch` | | **Type System** | Type hints (optional) | TypeScript (enforced) | | **Build Step** | ❌ Not needed | ✅ Required (`tsc`) | | **Entry Point** | `mcp4gva.server:main` | `build/index.js` | | **Config Command** | `uvx mcp4gva` | `npx -y mcp4gva-typescript` | ## File Structure Comparison ### Python Version ``` mcp4gva/ # Root directory ├── mcp4gva/ │ ├── __init__.py │ └── server.py # ~265 lines ├── pyproject.toml # Package config ├── requirements.txt ├── gva_gis_client.py # Bonus: standalone client ├── examples.py # Bonus: examples └── README.md ``` ### TypeScript Version ``` typescript/ ├── src/ │ └── index.ts # ~360 lines ├── build/ # Generated by tsc ├── package.json # Package config ├── tsconfig.json # TypeScript config └── README.md ``` ## Code Comparison ### 1. Server Initialization **Python:** ```python from mcp.server import Server from mcp.types import Tool, TextContent import mcp.server.stdio app = Server("mcp4gva") ``` **TypeScript:** ```typescript import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new Server( { name: "mcp4gva-typescript", version: "0.1.0" }, { capabilities: { tools: {} } } ); ``` ### 2. Listing Tools **Python:** ```python @app.list_tools() async def list_tools() -> list[Tool]: return [ Tool( name="gva_layer_info", description="Get metadata...", inputSchema={...} ), # ... ] ``` **TypeScript:** ```typescript server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "gva_layer_info", description: "Get metadata...", inputSchema: {...} }, // ... ] }; }); ``` ### 3. Handling Tool Calls **Python:** ```python @app.call_tool() async def call_tool(name: str, arguments: Any) -> list[TextContent]: if name == "gva_layer_info": data = make_request(url, params) return [TextContent( type="text", text=json.dumps(result, indent=2) )] ``` **TypeScript:** ```typescript server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (name === "gva_layer_info") { const data = await makeRequest(url, params); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } }); ``` ### 4. HTTP Requests **Python:** ```python import requests def make_request(url: str, params: dict) -> dict: headers = { 'User-Agent': 'Mozilla/5.0...', 'Accept': 'application/json' } response = requests.get(url, params=params, headers=headers) response.raise_for_status() return response.json() ``` **TypeScript:** ```typescript import fetch from "node-fetch"; async function makeRequest(url: string, params: RequestParams): Promise<ApiResponse> { const queryParams = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { queryParams.append(key, String(value)); } const response = await fetch(`${url}?${queryParams}`, { headers: { "User-Agent": "Mozilla/5.0...", "Accept": "application/json" } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json() as ApiResponse; } ``` ### 5. Main Entry Point **Python:** ```python def main(): """Main entry point for the MCP server""" import asyncio asyncio.run(run_server()) async def run_server(): """Run the async server""" async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await app.run(read_stream, write_stream, app.create_initialization_options()) if __name__ == "__main__": main() ``` **TypeScript:** ```typescript async function main() { const server = createServer(); const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP4GVA TypeScript server running on stdio"); } main().catch((error) => { console.error("Fatal error:", error); process.exit(1); }); ``` ## Installation & Usage ### Python Version ```bash # Install uv curl -LsSf https://astral.sh/uv/install.sh | sh # Configure Claude Desktop { "mcpServers": { "mcp4gva": { "command": "uvx", "args": ["--from", "/path/to/mcp4gva", "mcp4gva"] } } } # Test manually uvx --from . mcp4gva ``` ### TypeScript Version ```bash # Install dependencies cd typescript npm install # Build npm run build # Configure Claude Desktop { "mcpServers": { "mcp4gva-ts": { "command": "node", "args": ["/path/to/mcp4gva/typescript/build/index.js"] } } } # Test manually npm run dev ``` ## Key Differences ### 1. Type Safety **Python:** Optional type hints ```python def make_request(url: str, params: dict) -> dict: # Type hints are optional and not enforced at runtime pass ``` **TypeScript:** Compile-time type checking ```typescript async function makeRequest(url: string, params: RequestParams): Promise<ApiResponse> { // Types are checked at compile time // Compilation fails if types don't match } ``` ### 2. Async/Await **Python:** Built-in asyncio ```python async def call_tool(name: str, arguments: Any) -> list[TextContent]: data = make_request(url, params) # Synchronous call return [TextContent(...)] ``` **TypeScript:** Promise-based ```typescript async function callTool(name: string, args: any): Promise<Content[]> { const data = await makeRequest(url, params); // Must await return [{ type: "text", text: "..." }]; } ``` ### 3. Error Handling **Python:** Try-except ```python try: data = make_request(url, params) except requests.RequestException as e: logger.error(f"Request failed: {e}") raise ``` **TypeScript:** Try-catch with instanceof ```typescript try { const data = await makeRequest(url, params); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`Request failed: ${errorMessage}`); throw error; } ``` ### 4. Dependency Management **Python (pyproject.toml):** ```toml [project] dependencies = [ "mcp>=0.9.0", "requests>=2.31.0", ] [project.scripts] mcp4gva = "mcp4gva.server:main" ``` **TypeScript (package.json):** ```json { "dependencies": { "@modelcontextprotocol/sdk": "^0.5.0", "node-fetch": "^3.3.2" }, "bin": { "mcp4gva-ts": "./build/index.js" } } ``` ## Performance Both implementations have similar performance: - **Startup time:** Python slightly faster (no build step needed at runtime) - **Runtime performance:** Comparable for I/O-bound operations like HTTP requests - **Memory usage:** Similar, both lightweight ## Which Should You Choose? ### Choose Python if: - You're more comfortable with Python - You want simpler deployment (no build step) - Your team already uses Python tooling - You want the bonus standalone client and examples ### Choose TypeScript if: - You prefer strong typing and compile-time checks - Your team uses JavaScript/TypeScript - You want better IDE support and autocomplete - You're building on top of existing Node.js infrastructure ## Learning From Both This repository is designed for learning. You can: 1. **Compare implementations side by side** - See how the same functionality is implemented in both languages 2. **Test both versions** - Configure both in Claude Desktop and compare behavior 3. **Modify and experiment** - Try adding a new tool to both versions 4. **Understand MCP SDK differences** - See how Python and TypeScript SDKs differ ## Contributing Both implementations should be kept in sync feature-wise. When adding a new tool: 1. Implement it in both Python and TypeScript 2. Update both READMEs 3. Test both versions 4. Update this comparison document ## Resources - [MCP Documentation](https://modelcontextprotocol.io/) - [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) - [ArcGIS REST API](https://developers.arcgis.com/rest/) - [GVA GIS API](https://gvagis.icv.gva.es/server/rest/services)

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/pepo1275/mcp4gva'

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