From MCP to LSP: Securing AI Agents, Standardizing Context, and the Rise of Rust-Powered Infrastructure The convergence of Anthropic's Model Context Protocol (MCP) and Microsoft's Language Server Protocol (LSP) is enabling secure, context-aware AI agents that can navigate codebases with precision, while Rust is emerging as the preferred language for building the infrastructure that supports these interactions. The integration allows AI models to query structured code intelligence via LSP and interact with external tools via MCP, but introduces new security risks that require careful mitigation. Originally published on tamiz.pro. The landscape of AI-assisted development is undergoing a structural shift. We are moving from isolated, prompt-based interactions to interconnected, protocol-driven ecosystems. At the heart of this shift are two critical standards: the Model Context Protocol MCP by Anthropic, which standardizes how AI models connect to external data, and the Language Server Protocol LSP , which has long standardized how developers interact with code intelligence. Simultaneously, the infrastructure layer powering these interactions is increasingly dominated by Rust . Why? Because as AI agents gain access to file systems, APIs, and database connections, the security and performance requirements for the transport layers become non-negotiable. This article dives deep into the convergence of these technologies, examining how MCP and LSP are evolving to support secure, context-aware AI agents, and why Rust is becoming the de facto language for building the infrastructure that makes this possible. Historically, integrating AI into software engineering workflows was a fragile process. Developers wrote scripts to call OpenAI or Anthropic APIs, parsing JSON responses and injecting them into their IDEs or CI/CD pipelines. This approach was brittle, insecure, and difficult to scale. LSP was introduced by Microsoft in 2016 to solve a specific problem: how to provide intelligent code features autocomplete, go-to-definition, refactoring across different editors and language servers. By abstracting the communication between the editor client and the language analysis engine server into a JSON-RPC protocol, LSP enabled the rich IDE experiences we take for granted today. LSP proved that standardizing the interface between code and intelligence was more valuable than any single implementation. It created a modular ecosystem where VS Code, Neovim, and IntelliJ could all share the same underlying language servers. MCP, launched by Anthropic in mid-2024, addresses a similar problem but for AI models. Before MCP, connecting an LLM to external data sources like a PostgreSQL database or a REST API required custom, ad-hoc integrations. Each integration had its own authentication, error handling, and data formatting logic. MCP standardizes this connection. It defines a protocol where: This three-tier architecture mirrors the LSP model but is designed specifically for the stochastic, context-window-constrained nature of LLMs. It allows models to dynamically discover and interact with tools and resources without hard-coded integrations. The real power emerges when LSP and MCP converge. Modern AI agents don’t just need to generate code; they need to understand the codebase, navigate its structure, and interact with its runtime environment. One of the biggest challenges in AI-assisted development is context management . LLMs have limited context windows, and feeding them an entire codebase is inefficient and expensive. LSP provides structured information about the codebase: symbols, types, references, and definitions. MCP can expose this LSP-derived data as a resource or tool to the AI model. For example: file:// URI that points to a specific file, with metadata about its size and language. find references tool that queries the LSP server to find all usages of a symbol.This convergence allows AI agents to operate with the precision of a static analysis tool while maintaining the flexibility of natural language interaction. Instead of asking an LLM to "find all bugs related to authentication," the agent can query the LSP server for all functions marked with @auth decorators, then ask the LLM to analyze the logic within those functions. This integration introduces new security risks. If an AI agent can query your codebase via LSP and execute tools via MCP, it effectively has read/write access to your development environment. To mitigate these risks and handle the high-throughput, low-latency requirements of AI agents, the infrastructure layer is increasingly built in Rust. Rust offers several advantages that make it ideal for this role: AI agents often handle large volumes of data codebases, logs, metrics and must process them quickly. Rust’s ownership model ensures memory safety without a garbage collector, leading to predictable performance and reduced latency. This is critical for real-time AI interactions in IDEs. Rust’s type system prevents common vulnerabilities like buffer overflows and data races. When building MCP servers or LSP clients that interact with sensitive systems, Rust provides a safer foundation than Python or JavaScript, which are more prone to runtime errors and security exploits. Rust can easily compile to WebAssembly Wasm , allowing AI infrastructure to run securely in browser-based environments or sandboxed containers. This is essential for running MCP servers in untrusted environments. The Rust ecosystem has matured significantly, with libraries like tower for async services, serde for serialization, and tokio for concurrency. These libraries make it straightforward to build robust, high-performance MCP and LSP servers. Let’s look at a practical example of how to build a secure MCP server using Rust. We’ll use the mcp-rs library hypothetical, based on current trends to create a server that exposes a tool for reading code snippets from a local repository. cargo new mcp-code-server cd mcp-code-server Add the necessary dependencies to your Cargo.toml : dependencies mcp = "0.1.0" Hypothetical MCP library for Rust tokio = { version = "1.0", features = "full" } serde = { version = "1.0", features = "derive" } serde json = "1.0" tracing = "0.1" use mcp::{Server, Tool, Resource}; use serde json::json; use std::fs; tokio::main async fn main - Result< , Box