Most developers view Model Context Protocol (MCP) servers as exclusive backends for AI agents, but that mindset is limiting your architecture. A recent deep dive on DEV.to argues that these servers can serve as a unified data layer for both your autonomous agents and your human-facing web applications. By exposing the same search_orders tool to a dashboard that an agent uses, you eliminate data inconsistency and reduce backend duplication. The key is implementing a secure, thin proxy layer that speaks JSON-RPC on the backend and standard REST on the frontend.
The Browser vs. Proxy Debate
You technically have two options for connecting a frontend to an MCP server. The first is running the official TypeScript SDK (@modelcontextprotocol/sdk) directly in the browser using Streamable HTTP. While this is fast for demos, it requires exposing MCP tokens to the client and managing CORS strictly. The recommended approach is a thin backend proxy. This keeps credentials off the client, allows you to enforce user session checks before every call, and lets you allowlist specific tools. It transforms the MCP server from an opaque AI tool into a governed API endpoint.
Handling JSON-RPC and Tool Calls
MCP communication relies on JSON-RPC 2.0. After the initial initialize handshake, your backend proxy needs to handle specific methods like tools/call. For example, calling search_orders with the argument { "customer": "Acme" } returns a JSON-RPC result containing the data. The source article provides a Node.js Express example where the proxy connects to the MCP server via StreamableHTTPClientTransport. It validates the incoming request against an ALLOWED set of tool names, ensuring that a malicious or buggy frontend cannot invoke arbitrary backend functions. This pattern keeps the security boundary on the server, where it belongs.
Streaming and Error Management
Modern applications need more than just request-response cycles. The MCP Streamable HTTP transport supports Server-Sent Events (SSE), allowing servers to send progress notifications for long-running tasks. Your proxy must pass these SSE streams through to the frontend, which can then use fetch with a stream reader or EventSource to update the UI in real-time. Error handling is equally critical and exists in three distinct layers: transport errors (network/5xx), JSON-RPC errors (protocol bugs like -32602), and tool errors (business logic failures like isError: true). You must treat tool output as untrusted data, never injecting it directly as raw HTML, to prevent XSS vulnerabilities.
Key Takeaways
- Use a backend proxy to hide MCP credentials and enforce tool allowlisting.
- Implement JSON-RPC 2.0 correctly, distinguishing between protocol errors and tool execution failures.
- Support SSE for streaming responses to improve UX for long-running tools.
- Validate arguments on the server side and treat all tool output as untrusted.
The Bottom Line
MCP servers are not just for AI agents; they are robust, unified data layers waiting to be utilized. By implementing a thin proxy, you get consistent data access for both humans and bots without compromising security.