{"slug": "cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere", "title": "Cross-Harness Tool Parity: Write One Custom MCP Tool, Deploy It Everywhere", "summary": "The Model Context Protocol (MCP) enables developers to write a single custom tool that works across multiple AI coding environments including Claude Code, Cursor, Codex, Gemini CLI, Copilot, and Windsurf. A developer demonstrates how to create an MCP server for a weather alert tool that achieves true tool parity, eliminating redundant setup and maintenance across different AI harnesses.", "body_md": "Achieving true tool parity across AI coding environments is no longer a theoretical challenge. Learn how the Model Context Protocol (MCP) enables a single, custom tool configuration to function seamlessly within Claude Code, Cursor, Codex, Gemini CLI, Copilot, and Windsurf, eliminating redundant setup and accelerating development workflows.\n\nToday’s developer landscape is fractured by AI tool choice. While having options like Cursor, Windsurf, and GitHub Copilot is beneficial, it creates a significant maintenance burden. If you build a custom internal tool—say, a wrapper around your company’s deployment API—you often find yourself maintaining six different integration scripts, configuration files, and authentication flows. One for Claude Code, another for the Gemini CLI, a separate one for Cursor’s extensions. This lack of **tool parity** means time is wasted on plumbing, not product.\n\nThe core issue is that each \"harness\" or AI coding environment has its own proprietary way of discovering, authenticating, and invoking tools. The result is a siloed ecosystem where a powerful utility locked inside one editor remains inaccessible in another. What developers need is a universal contract—a standard way to define a tool that any AI harness can understand and execute with zero modification.\n\nThe Model Context Protocol (MCP) provides this exact contract. An MCP tool is not a plugin for a single editor; it is a standalone server that exposes a typed interface. Your tool is defined once, in a single configuration file and codebase. AI harnesses that support MCP act as clients, automatically discovering and invoking your tool based on this shared contract.\n\nThink of it as building a REST API but for AI agents. You define the endpoints (your tool's functions) and their schemas. Any compliant client—whether it's the agent running in your IDE or a CLI tool—can then call those endpoints. This architecture delivers immediate **tool parity**. The configuration for your \"Deploy to Staging\" tool is authored exactly once and then works identically across the entire ecosystem.\n\nLet's build a concrete example: a custom MCP tool called `weather-alert` that fetches severe weather alerts for a given location using a public API. This tool will be usable in all six environments without modification.\n\n**Step 1: Create the MCP Server.** We'll use TypeScript and the official MCP SDK. The key is defining clear tool schemas and implementing the logic.\n\n``` js\n// weather-alert-server.ts\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nconst server = new McpServer({\n  name: \"weather-alerts\",\n  version: \"1.0.0\",\n});\n\n// Define the tool schema with strict validation\nserver.tool(\n  \"getSevereAlerts\",\n  \"Fetches active severe weather alerts from NOAA for a specified US location.\",\n  {\n    location: z.string().describe(\"US state code, e.g., 'CA' or 'TX'\"),\n    severity: z.enum([\"minor\", \"moderate\", \"severe\", \"extreme\"]).optional()\n      .describe(\"Filter by minimum severity level\"),\n  },\n  async ({ location, severity }) => {\n    // ... Actual API call to NOAA's alerts.weather.gov\n    const alerts = await fetchAlerts(location, severity);\n    return {\n      content: [{ type: \"text\", text: formatAlerts(alerts) }],\n    };\n  }\n);\n\n// Start the server\nserver.listen({ port: 3000 });\n```\n\n**Step 2: Declare the MCP Configuration.** This is the magic file. You place an `mcp.json` in your project root. This single file is what every harness will read.\n\n```\n// mcp.json\n{\n  \"servers\": {\n    \"weather-alerts\": {\n      \"command\": \"node\",\n      \"args\": [\"./weather-alert-server.ts\"],\n      \"env\": {\n        \"NOAA_API_KEY\": \"${NOAA_API_KEY}\"\n      }\n    }\n  }\n}\n```\n\nThat's it for the tool development. This configuration declares a server named `weather-alerts`, how to start it, and what environment variables it needs. The tool itself, `getSevereAlerts`, is discovered dynamically when a client connects.\n\nNow, let's see how this single `mcp.json` file grants your tool parity across the landscape. The following integrations require no changes to your tool's configuration—only a one-time enablement in each harness's settings.\n\n**1. Claude Code:** Reads `mcp.json` automatically from your project root. When you prompt Claude to \"check for severe weather in Texas,\" it will see the `getSevereAlerts` tool in its available tools list and invoke it directly. Authentication via environment variables is handled by the session.\n\n**2. Cursor:** Natively supports MCP. In `Settings > Features > Model Context Protocol`, point it to your project's root. Cursor's AI sidebar and inline completions can now leverage your `weather-alerts` server as if it were a built-in extension. The tool's help text and schema are used for inline suggestions.\n\n**3. Codex (OpenAI):** The Codex CLI and its ecosystem can utilize MCP tools by starting the client with the `--mcp-config` flag pointing to your `mcp.json`. The tool becomes part of the function-calling vocabulary for Codex models.\n\n**4. Gemini CLI:** Google's CLI tool supports MCP servers defined in its configuration. By adding a reference to your `mcp.json` or copying its server definition, the Gemini agent gains access. You can ask it, \"Get me all 'extreme' alerts for Florida,\" and it will use your tool.\n\n**5. GitHub Copilot:** Via the Copilot Extensions API, you can register your MCP server as an extension. Once registered in your organization's settings, any Copilot user in VS Code or on github.com can interact with your tool through natural language in the chat pane.\n\n**6. Windsurf:** Windsurf’s Cascade AI is built with deep MCP support. It will automatically parse `mcp.json` from your open workspace. The `weather-alerts` tool immediately becomes available for Cascade to use in agentic workflows, such as automatically checking weather before a planned deployment.\n\nTo ensure your tools are robust across all environments, consider these production patterns. First, **versioning** is critical. Include a `version` field in your tool's schema. Clients like Cursor will use this to cache schemas and prevent breaking changes. Second, **robust error handling** is non-negotiable. Return clear, structured errors from your MCP server. Harnesses will parse these and present them to the user uniformly—whether it's a 401 Unauthorized in Claude Code or a connection timeout in Gemini CLI.\n\nFinally, **security** must be uniform. The `${NOAA_API_KEY}` variable in our `mcp.json` is a reference. Each harness has its own mechanism for securely injecting secrets (e.g., Cursor's `.env`, Claude Code's shell environment). Your tool's configuration remains neutral, and secrets are managed at the harness level, maintaining both security and parity.\n\nStop writing six versions of the same tool. Embrace the Model Context Protocol to achieve true, effortless tool parity. Start building your first universal MCP tool today at [https://tormentnexus.site](https://tormentnexus.site).\n\n*Originally published at tormentnexus.site*", "url": "https://wpnews.pro/news/cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere", "canonical_source": "https://dev.to/robertpelloni/cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere-1elo", "published_at": "2026-07-25 00:02:29+00:00", "updated_at": "2026-07-25 00:31:20.785667+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "artificial-intelligence"], "entities": ["Model Context Protocol", "Claude Code", "Cursor", "Codex", "Gemini CLI", "GitHub Copilot", "Windsurf", "NOAA"], "alternates": {"html": "https://wpnews.pro/news/cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere", "markdown": "https://wpnews.pro/news/cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere.md", "text": "https://wpnews.pro/news/cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere.txt", "jsonld": "https://wpnews.pro/news/cross-harness-tool-parity-write-one-custom-mcp-tool-deploy-it-everywhere.jsonld"}}