Lessons Learned Developing Visor’s MCP Server

Summary & demo

At Visor we’ve been diving into Anthropic’s Model Context Protocol (MCP) to build more capable AI agents. It’s been a fun and challenging journey into a world of cutting edge technology very much in its infancy. Here’s what I’ve learned, along with practical advice for developers looking to harness MCPs.

Demo of Visor’s MCP & SDK

What are MCPs?

MCPs are applications that expose tools ↗prompts ↗, and resources ↗ that enable AI models to interact with external systems through a standardized and well documented protocol. Think of MCPs as the USB standard for AI assistants (like Claude ↗ or Cursor ↗) that need to access external capabilities.

Here is a fantastic HuggingFace article that goes into much greater depth into the nature of MCPs if you want to get deep into the topic: #14: What Is MCP, and Why Is Everyone – Suddenly!– Talking About It?

Key lessons & learnings

The setup & development experience needs work

Setting up MCPs is not yet a user friendly experience. End users have to manually craft JSON files and troubleshoot issues themselves. A better UI to setup MCPs and debug issues would be very useful. Until that happens, I recommend using a MCP proxy like supergateway to connect to your already running server via a localhost URL. This way you can launch the MCP server from your editor or favorite terminal, and add breakpoints or log statements to help you identify and fix issues with your implementation.

Here is our claude_desktop_config.json configuration using supergateway:

{
    "mcpServers": {
        "visor-ai-tools": {
            "command": "npx",
            "args": [
                "-y",
                "supergateway",
                "--sse",
                "http://localhost:3001/api/mcp/sse"
            ]
        }
    }
}

This is what you should see when your tools are connected

Claude desktop is currently limited in its ability to connect to remote MCP servers

Running an MCP (Model Context Protocol) server remotely and connecting to it via the Claude desktop app seems to be impossible right now. The protocol is mainly set up to work with servers running on the same machine as the desktop app, not remotely. This makes it more difficult to develop certain types of applications and effectively handle authentication, monitoring and logging.

There are community-driven solutions like supergateway and @remote-mcp/client to bridge this gap, but these solutions are not yet robust enough for enterprise adoption in my opinion. I was unable to connect to a remote HTTPS URL with those solutions (only localhost). If you know how to get Claude desktop to connect securely to an HTTPS MCP server, I’d love to hear from you!

Using Zod for validation limits server compatibility

One of the first hurdles I encountered was the reliance on Zod for data validation in Anthropic’s TypeScript reference implementation. While Zod is excellent for JavaScript developers, it created friction for us since we needed to build our tools on-demand for each user within our Python-based servers.

We had to extend and override some of the methods of the reference MCPServer to bypass Zod entirely and work directly with JSON Schema definitions. That way we could define our tools on our Python servers and expose them via an API endpoint.

If you have this problem, we’ve created a small gist containing our AjvMCPServer implementation which bypasses Zod and uses plain JSON Schema objects and Ajv for validation, you can access it here.

Tips & Tricks

Exit Claude desktop if your MCP changes

I ran into many situations where I was developing the MCP server and was seeing it working correctly on the logs, but Claude would get stuck and never receive the responses. I suspect this has to do with restarting the server while Claude desktop is running, which effectively resets the active session and causes Claude to time out requests, even new ones that you made after the server restarted.

The solution to this and other strange MCP issues was always to completely restart Claude desktop by first exiting it completely (File -> Exit).

If the AI agent makes poor choices, limit the number of tools you expose to it

Another interesting learning was that if we added too many tools, Claude would lose the ability to select the correct one to use to accomplish the task at hand. There is limit on the number of tools (and I suspect their individual complexity contributes to this) that Claude and other AI agents can consider at one time. If you overwhelm the AI with too many choices, it will start to make poor decisions about what tool to use next.

We found that for our use case, having more than 25 to 30 tools caused agent to fail more often than not. Keep in mind our definitions are quite complex, so you may get away with a lot more tools than that if your tools are simple. But there is a limit nonetheless, and finding the correct number (and complexity) of tools to give an AI agent seems to be more of an art than a science at this point.

Context Is King for Agents

Agents need more than machine identifiers to make sense of dropdowns or choice-based data. Random identifiers or numbers are meaningless without context. In order to work around this limitation: pair every identifier with a human-readable description, and use anyOf combined with constant values in your JSON Schemas to give agents fixed set of options to pick from. You must give the agent the context it needs if you want to get good results.

Keep in mind that context is limited, so look for ways to reduce the amount of text you use in descriptions while not losing important information. Test frequently as you change your functions and reduce the amount of text used, to ensure you don’t lose valuable signal that helps the AI do a good job.

Use mature frameworks like NestJS and Fastify to speed up your time to market

My final tip for you is to build on top of a mature and well-documented web frameworks like NestJS and Fastify. You’ll usually find more documentation when getting started and it will pay dividends in the long run as your application grows in scale and complexity. It might take a bit of extra effort to learn a new framework up front, but investing in yourself is always a wise move in my opinion. Learning new tools might help you become a better engineer, which is always something to strive for.

Thanks for reading

Good luck in your MCP journey, feel free to connect with me if you have questions about the contents of this article or just want to share something cool: sbatista[at]visor.us

Source code to replace Zod with Ajv

If you run into the same issue of having to bypass Zod, here is a gist of our AjvMCPServer class, which offers an example of how to replace Zod with Ajv for validation.

CEO Michael Yaroshefsky’s Take: Demo

Due to advancements with MCP servers in the last few months, Visor has incorporated AI into our own product, making Visor become a useful AI project management tool for our customers.

And now we’re building an MCP server for other companies to use this tech to enrich their products. Check out his demo below for a high-level view of what this technology will unlock for products.

Are you ready to begin?

Visor is secure, free, and doesn't require a credit card.

Get Started For Free