TL;DR
- An MCP server is an independent application that exposes tools, data resources, and prompt templates to AI models through the standardized Model Context Protocol (MCP).
- Communication between an MCP client and an MCP server relies on JSON-RPC 2.0 over standard input/output (stdio) or Server-Sent Events (SSE) and HTTP.
- MCP servers eliminate custom glue code by replacing fragmented, point-to-point integrations with a single universal interface for external context and execution.
- Production deployments require strict access control, because ungoverned MCP servers expose databases, local filesystems, and internal APIs to prompt injection and unauthorized execution.
- Platforms like Bifrost provide centralized gateway governance, tool filtering, and low-latency proxying to manage MCP servers safely across distributed engineering teams.
An MCP server is a lightweight, standardized program that exposes tools, data resources, and prompt templates to AI models through the Model Context Protocol. Rather than writing custom integration code for every combination of large language model and external service, developers implement the server protocol once to make external systems available to any compatible client. Bifrost, an open-source AI gateway written in Go by Maxim AI, provides centralized routing, tool filtering, and governance across multi-model architectures. Understanding what an MCP server means in practice requires examining its architectural role, the primitives it exposes, its communication mechanisms, and the governance controls necessary to run it securely in production.
What is an MCP Server?
An MCP server is a specialized software component that acts as a standardized context and capability broker between an external system and a large language model. It translates proprietary interfaces, such as database query engines, third-party software-as-a-service (SaaS) APIs, or local operating system utilities, into a uniform protocol defined by the open-source Model Context Protocol specification.
The Model Context Protocol was originally introduced by Anthropic in November 2024 and later contributed to the Linux Foundation under the Agentic AI Foundation. It was created to solve the structural "N-by-M" integration problem in AI engineering. Historically, if an organization used four different AI clients or models and needed access to five different internal data stores, developers had to write and maintain twenty custom integrations. Each connector required unique authentication handling, custom schema conversions, and bespoke error recovery.
Without MCP (N × M integrations):
AI Client A ──┬── Custom Code ── Database
AI Client B ──┼── Custom Code ── File System
AI Client C ──┴── Custom Code ── GitHub API
With MCP (N + M integrations):
AI Client A ──┐
AI Client B ──┼── Standard MCP ── [ MCP Server ] ── External Systems
AI Client C ──┘
An MCP server resolves this fragmentation by establishing an architectural separation between model interaction and tool execution. The server runs as an independent process, either locally on a developer's workstation or remotely on a server. It advertises its available capabilities to connected clients using a standardized schema. When an AI client connects, the server delivers an inventory of what it can do or what data it can read. The AI model inspects this inventory at runtime, selects the appropriate action based on user input, and instructs the client to invoke the server. The server executes the operation and returns structured results directly to the model.
Core Architecture: Hosts, Clients, and Servers
An MCP architecture separates responsibilities across three distinct entities: the host application, the MCP client, and the MCP server. Each layer maintains a specific boundary to ensure that models do not execute arbitrary code directly on underlying systems.
The host application is the user-facing environment where the AI session originates. Common hosts include developer environments like Cursor, desktop applications like Claude Desktop, command-line coding agents like Claude Code, or custom internal web applications. The host is responsible for managing the user interface, instantiating the MCP client, and enforcing user consent or confirmation dialogs before high-risk actions execute.
The MCP client is the protocol engine embedded within or alongside the host application. The client maintains direct connections to one or more MCP servers. It handles connection lifecycles, negotiates protocol versions, sends discovery queries, translates model function calls into protocol requests, and routes server responses back into the model's active context window. A single MCP client can connect to multiple independent MCP servers concurrently, combining capabilities from a database server, a repository server, and an issue-tracker server within a single chat session.
The MCP server is the downstream target that hosts the actual capabilities. It does not communicate with the language model directly; instead, it communicates strictly with the MCP client over a structured transport layer. The server maintains isolation from the model provider, meaning an MCP server does not need to know whether the request originated from Claude, GPT-4, Gemini, or a local open-weight model running on Ollama.
┌────────────────────────────────────────────────────────┐
│ Host Application (IDE, Desktop Chat, CLI Agent) │
│ │
│ ┌─────────────┐ ┌──────────────────────┐ │
│ │ LLM Engine │ ◄────────► │ MCP Client │ │
│ └─────────────┘ └──────────┬───────────┘ │
└─────────────────────────────────────────┼──────────────┘
│ JSON-RPC 2.0
▼
┌──────────────────────────────────────┐
│ MCP Server │
│ ┌───────────┬───────────┬─────────┐ │
│ │ Tools │ Resources │ Prompts │ │
│ └─────┬─────┴─────┬─────┴────┬────┘ │
└────────┼───────────┼──────────┼──────┘
▼ ▼ ▼
Databases File Systems APIs
The Three Core Primitives Exposed by an MCP Server
An MCP server exposes functionality through three primary primitives defined in the protocol specification: Tools, Resources, and Prompts. Each primitive serves a distinct operational purpose and operates under a different control model.
1. Tools: Model-Controlled Execution
Tools are executable routines that allow an AI model to take actions or fetch dynamic data from external environments. Tools are designated as "model-controlled" because the language model decides whether, when, and with what arguments to call them based on the user's instructions and the tool's published schema.
When an MCP server exposes a tool, it provides a JSON Schema detailing the tool's name, description, and required parameters. For example, an MCP server connected to an enterprise PostgreSQL database might expose a tool named execute_query that accepts a SQL string parameter. When a user asks, "How many customers signed up today?", the model inspects the schema, generates the structured JSON parameters, and initiates the call. Tools can perform read-only tasks or state-changing operations, such as creating Jira tickets, modifying cloud infrastructure, or writing files to disk.
2. Resources: Application-Controlled Context
Resources are passive, data-bearing payloads that provide contextual background to the AI model. Unlike tools, resources are "application-controlled." They do not perform computation or alter external state; instead, they function similarly to file attachments or document endpoints.
Resources are identified by unique URIs (for example, file:///logs/app.log or postgres://schema/customers). They allow the client or user to attach structured text, binary blobs, or real-time application context directly into the prompt without requiring the model to trigger an active function call. An MCP server can also emit notifications when a resource changes, allowing the client to refresh its context dynamically when an underlying file or database table updates.
3. Prompts: User-Controlled Templates
Prompts are reusable, structured templates and workflows stored on the server and exposed directly to the end user. Prompts are "user-controlled" because they are typically surfaced in client interfaces as slash commands, dropdown options, or guided workflows.
A prompt template can accept arguments and compose predefined instructions with relevant server resources. For example, a development-focused MCP server might provide a prompt called /analyze-pull-request that automatically retrieves git diffs, formats them according to organizational coding guidelines, and presents a prepared prompt to the model.
| Primitive | Control Hierarchy | Operational Purpose | Example Implementations |
|---|---|---|---|
| Tools | Model-controlled | Dynamic actions, API mutations, and active data retrieval |
query_db, create_github_issue, send_slack_message
|
| Resources | Application-controlled | Structured, contextual read-only data attached via URIs |
file:///var/log/system.log, api://metrics/daily_summary
|
| Prompts | User-controlled | Pre-packaged prompt templates, slash commands, and workflows |
/review-security-policy, /generate-sql-migration
|
How Communication Works: The JSON-RPC 2.0 Protocol
MCP servers do not use custom binary encodings or REST conventions. Instead, the Model Context Protocol relies strictly on JSON-RPC 2.0 as its wire format. All interactions, whether local or remote, take the form of standard JSON-RPC requests, responses, and notifications.
1. Lifecycle and Initialization
When an MCP client initiates a connection to an MCP server, it executes an initialization handshake to negotiate capabilities and protocol versions. The client sends an initialize request containing its client metadata and supported feature set.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": { "listChanged": true },
"sampling": {}
},
"clientInfo": {
"name": "enterprise-agent-runner",
"version": "1.4.0"
}
}
}
The MCP server responds with its own capabilities, declaring whether it supports tools, resources, prompts, or custom logging features:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": { "listChanged": true },
"resources": { "subscribe": true }
},
"serverInfo": {
"name": "internal-db-mcp-server",
"version": "2.1.0"
}
}
}
Once the client sends an empty notifications/initialized message, normal protocol operations begin.
2. Tool Discovery and Execution Flow
To make tools available to the model, the client queries the server by issuing a tools/list request. The server returns an array of tool objects, each accompanied by a standard JSON Schema definition.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
The server returns:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "get_customer_metrics",
"description": "Retrieve daily ARR and churn statistics for a specific tenant ID.",
"inputSchema": {
"type": "object",
"properties": {
"tenant_id": {
"type": "string",
"description": "The unique enterprise tenant identifier."
}
},
"required": ["tenant_id"]
}
}
]
}
}
When the model decides to run this tool, the client formats a tools/call request containing the model-generated arguments. The server processes the request against the target service and returns the output:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_customer_metrics",
"arguments": {
"tenant_id": "tenant-8492"
}
}
}
The server responds with content blocks (either text, image, or resource embeddings) that the client passes back into the model context:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\"arr\": 142000, \"churn_risk\": \"low\", \"active_seats\": 84}"
}
],
"isError": false
}
}
Transport Mechanisms: stdio vs HTTP and SSE
The Model Context Protocol decouples its message format from the underlying transmission layer. The specification officially defines two standard transport mechanisms: standard input/output (stdio) and Server-Sent Events (SSE) combined with HTTP POST.
stdio Transport (Local Subprocess):
┌────────────┐ stdin (JSON-RPC) ┌────────────┐
│ MCP Client │ ──────────────────> │ MCP Server │
│ │ <────────────────── │ (Child OS │
└────────────┘ stdout (JSON-RPC) │ Process) │
└────────────┘
HTTP + SSE Transport (Distributed / Remote):
┌────────────┐ SSE Stream (Server to Client) ┌────────────┐
│ MCP Client │ <════════════════════════════════════ │ MCP Server │
│ │ ────────────────────────────────────> │ (Remote │
└────────────┘ HTTP POST (Client to Server) │ Service) │
└────────────┘
Standard Input and Output (stdio)
In the stdio transport, the MCP client spawns the MCP server executable as a local child process. The client writes newline-delimited JSON-RPC messages directly to the server's standard input stream (stdin) and reads responses from its standard output stream (stdout).
Because stdio communication occurs entirely in memory across local operating system pipes, it introduces virtually zero network overhead. It is the dominant transport used by desktop editors and terminal agents connecting to local filesystem tools, Git helpers, or utility scripts. A critical engineering constraint of stdio servers is that the server process must never print unstructured debugging strings to stdout, as doing so corrupts the JSON-RPC parsing pipeline. All application logging must be directed strictly to standard error (stderr).
Server-Sent Events (SSE) and HTTP POST
When an MCP server must run remotely in a Kubernetes cluster, virtual private cloud, or SaaS environment, standard streams cannot be used. In this scenario, the protocol specifies HTTP with Server-Sent Events.
The client opens a persistent SSE connection to an endpoint (such as https://mcp.internal.net/sse) to receive a streaming channel of messages and notifications from the server. Simultaneously, the client transmits commands and requests to the server via independent HTTP POST requests. This transport allows centralized servers to serve multiple client connections concurrently, run behind load balancers, and integrate with cloud identity providers.
| Architectural Feature | stdio Transport | HTTP with SSE Transport |
|---|---|---|
| Execution Model | Local subprocess spawned by client | Independent long-running daemon or cloud service |
| Network Exposure | None (local Unix pipes / Windows anonymous pipes) | Network ports exposed over HTTP/HTTPS |
| Concurrency | Single-client dedicated process (1:1) | Multi-client connection pooling (1:Many) |
| Overhead | Sub-millisecond IPC latency | Network round-trip latency + TLS termination |
| Primary Use Cases | CLI agents, local file inspection, desktop IDEs | Centralized databases, corporate APIs, shared enterprise tools |
How MCP Servers Differ From Traditional APIs
A common point of confusion among engineers is why MCP servers are necessary if an organization already maintains robust REST, GraphQL, or gRPC APIs. While traditional APIs connect software to software, MCP servers are designed specifically to connect software to probabilistic language models.
Traditional APIs assume deterministic callers. A client SDK or frontend developer knows the exact endpoint path, parameter types, error statuses, and invocation sequence ahead of time at compile time. In contrast, an AI model does not have hardcoded endpoint calls. Instead, it must discover available capabilities dynamically at runtime, inspect natural-language documentation explaining what a tool does, formulate arguments based on conversational intent, and recover when operations fail.
MCP servers bridge this gap in several ways:
- Semantic Self-Description: Every tool on an MCP server includes a human-readable description optimized for model reasoning. These descriptions explain not just parameter types, but when and why the model should select the tool.
-
Standardized Tool Contracts: Instead of requiring custom client code to parse OpenAPI specs, handle disparate pagination patterns, or manage varied header configurations, an MCP client interacts with every MCP server through identical
tools/listandtools/callmechanics. - Dynamic Discovery: A model can query an MCP server to detect new or updated capabilities without requiring the client application to recompile or update its dependencies.
- Context Injection: Beyond returning raw payloads, MCP servers format data specifically for ingestion into context windows, packaging complex system state as consumable text or structured references.
Security Risks and Governance Challenges
While MCP servers provide immense flexibility for autonomous agents, they also expand the attack surface of production systems. Connecting an AI model to an unauthenticated or unmonitored MCP server introduces serious security vulnerabilities that engineering teams must address.
Prompt Injection and Indirect Exploitation
The most significant operational risk in an MCP deployment is indirect prompt injection. If an MCP server has access to untrusted external data (such as reading unvetted web pages, processing incoming customer emails, or scanning shared document repositories), an attacker can embed hidden instructions within that data. When the MCP server returns the data to the model, the model may execute those instructions, triggering dangerous tool calls such as exfiltrating database records or deleting cloud resources.
Excessive Permissions and Confused Deputy Attacks
Many community and early-stage MCP servers operate with blanket credentials. For example, a local database MCP server might connect using an administrative connection string with full read and write access across all schemas. If the model invokes a tool without proper sandboxing, it can inadvertently execute destructive updates. Furthermore, because MCP clients often run on developer workstations, malicious prompts can exploit local stdio servers to read sensitive configuration files, SSH keys, or environment variables.
Governance at the Gateway and Endpoint Layer
Production architectures require comprehensive control over which agents and users can reach specific MCP servers. Beyond routing, Bifrost applies governance and security controls (virtual keys, budgets, guardrails, audit logs) centrally, and Bifrost Edge extends that same governance and security to AI traffic on employee machines, with endpoint enforcement on each device.
Because endpoint tools like Claude Desktop, Cursor, and terminal agents run locally, organizations often suffer from "shadow AI", where developers configure unvetted local MCP servers without security review. Bifrost Edge, which is currently in alpha, provides centralized visibility into installed developer tools and MCP connections across company laptops. Security administrators can enforce strict allowlists for MCP servers and ensure that all prompts passing to external models undergo redaction and guardrail evaluation via MCP governance policies.
Governing MCP Servers in Production with Bifrost
As organizations transition from running individual MCP servers locally to managing fleets of tools across distributed environments, managing raw, point-to-point connections becomes unmaintainable. Managing dozens of disparate servers across multiple engineering teams requires a centralized infrastructure layer.
Bifrost addresses these challenges by operating as an open-source MCP gateway. Written in Go, it acts simultaneously as an MCP client to upstream tool servers and as an MCP server to downstream AI applications, adding only 11 microseconds of overhead per request at 5,000 requests per second in sustained benchmarks.
Downstream Clients Bifrost Gateway Upstream MCP Servers
┌──────────────────┐ ┌─────────────────┐ ┌────────────────────┐
│ Claude Desktop │ ──Streamable──│ │ ──stdio/SSE── │ Postgres Database │
└──────────────────┘ HTTP │ Virtual Keys │ └────────────────────┘
┌──────────────────┐ ─────────────>│ Tool Filtering │ ──Streamable──┌────────────────────┐
│ Cursor / IDE │ │ Audit Logging │ HTTP │ Internal Jira API │
└──────────────────┘ │ Guardrails │ └────────────────────┘
┌──────────────────┐ │ Code Mode │ ──Streamable──┌────────────────────┐
│ Coding CLI Agent │ ─────────────>│ │ HTTP │ GitHub Server │
└──────────────────┘ └─────────────────┘ └────────────────────┘
Centralized Tool Aggregation
Rather than configuring each developer's IDE or agent framework with multiple database passwords, API tokens, and transport configs, all upstream MCP servers connect directly into the Bifrost gateway. Bifrost aggregates tools from local and remote servers across stdio, SSE, and Streamable HTTP. It exposes these tools through a single, secure gateway URL, serving as a unified control plane across all connected models and clients.
Access Control via Virtual Keys
Bifrost uses virtual keys as the core governance entity. Administrators can generate isolated virtual keys for specific teams, applications, or developers. Each key can be configured with strict MCP tool filtering, ensuring that an automated testing agent only sees read-only database tools, while deployment tools are restricted to authorized platform engineers. In enterprise environments, teams can curate tools into distinct MCP tool groups, presenting customized subsets of organizational capabilities to different consumer tiers.
Optimizing Execution with Code Mode
When an AI application connects to dozens of MCP servers, advertising every tool schema directly inside the model's context window consumes thousands of prompt tokens on every request. This causes high token costs and increased latency.
To solve this, Bifrost provides Code Mode. Instead of passing full tool schemas and requiring iterative, round-trip function calls between the model and client, Code Mode allows the model to write a short programmatic script (such as Python) that orchestrates multiple tools inside an isolated execution environment. This workflow reduces token usage by more than 50% and lowers execution latency by 40% compared to standard iterative MCP tool calling.
For autonomous agent workloads, Bifrost also supports Agent Mode, enabling automated tool execution with configurable approval thresholds, while applying strict guardrails to inspect inputs and outputs for sensitive data or policy violations before executing external side effects.
Frequently Asked Questions
What is the difference between an MCP client and an MCP server?
An MCP client is the component embedded within an AI application (like an IDE or chat interface) that connects to servers, sends requests, and feeds results to a language model. An MCP server is an independent process that connects to external systems (like databases, APIs, or files) and executes actions or returns data when requested by the client.
Can an MCP server run on a remote cloud host?
Yes. While many MCP servers run locally as child processes using the standard input/output (stdio) transport, the Model Context Protocol specification supports network-based transports using HTTP and Server-Sent Events (SSE). Remote MCP servers can run in containers, Kubernetes clusters, or serverless infrastructure.
How does an AI model know which MCP server tool to call?
During connection initialization, the MCP server provides a list of available tools accompanied by natural language descriptions and JSON Schema parameter definitions. The AI model reads these descriptions in its context window and uses semantic reasoning to decide which tool matches the user's intent.
What happens when an MCP server tool call fails?
When an error occurs during tool execution, the MCP server returns a JSON-RPC response containing an isError: true flag along with descriptive error text in its content block. The MCP client passes this error message back to the language model, which can analyze the failure, adjust its parameters, or explain the issue to the user.
Do MCP servers replace REST APIs?
No. MCP servers do not replace existing APIs; they wrap them. Traditional REST, GraphQL, and gRPC APIs remain the foundational communication layer for modern software services. MCP servers provide an AI-ready interface on top of those APIs, translating probabilistic model requests into deterministic API calls.
How do virtual keys secure MCP servers in Bifrost?
In Bifrost, virtual keys act as access tokens that enforce granular permissions, rate limits, and tool allowlists. By attaching specific tool policies to each virtual key, administrators ensure that an AI client or user can only discover and invoke the exact MCP tools they are authorized to access.
Getting Started with MCP Server Infrastructure
The Model Context Protocol has emerged as the universal standard for bridging large language models with the tools, files, and enterprise data sources they need to operate autonomously. Understanding what an MCP server means marks the shift from isolated chatbot demos to fully integrated agentic workflows. However, running these servers in production demands rigorous visibility, least-privilege tool filtering, and enterprise security enforcement.
Engineering teams evaluating how to scale, route, and secure their MCP infrastructure can request a Bifrost demo or review the open-source repository to explore high-performance gateway governance for modern AI architectures.
Sources
- Model Context Protocol Specification - The official specification for architecture, JSON-RPC schema, and transports maintained under the Linux Foundation.
- Introducing the Model Context Protocol - Anthropic's original announcement detailing the vision, architecture, and open standard for LLM integrations.
- JSON-RPC 2.0 Specification - The transport-agnostic remote procedure call specification used as the wire protocol for all MCP messages.
- Bifrost MCP Gateway Documentation - Architectural guidelines and implementation patterns for deploying, securing, and governing MCP servers in production.



Top comments (0)