# **Model Context Protocol (MCP) & MCP-UI Engineering Guide: Architecture, Implementation, and Security**
## **1. Introduction: Standardizing AI Connectivity**
As Large Language Models (LLMs) evolve from simple text generators into agents capable of performing complex tasks, the connectivity between models and external systems (databases, file systems, APIs, etc.) has emerged as a core challenge in software engineering. Existing LLM integration methods required different APIs and tool definition styles for each model provider (OpenAI, Anthropic, etc.), leading to a fragmentation problem where "n models" and "m data sources" required "n × m" integration codes.
**Model Context Protocol (MCP)** is an open standard protocol designed to solve this problem. MCP standardizes communication between AI applications (hosts) and data sources or tools (servers). Much like how a USB-C port connects various peripherals via a single interface, MCP allows various AI models to utilize resources with a single implementation. Furthermore, **MCP-UI** is an extension specification that goes beyond functional connection, supporting AI interactions with users through Rich UI elements instead of just text, dramatically improving the user experience (UX) of AI agents.
This technical report covers detailed API specifications, implementation patterns by language (Python, Node.js), JSON-RPC message structures, and security guidelines to enable developers to build production-level MCP servers, clients, and MCP-UI even in environments without internet connectivity.
---
## **2. MCP Protocol Architecture and Core Principles**
MCP is based on a client-host-server model and operates by exchanging JSON-RPC 2.0 messages over a transport layer. This architecture is designed to ensure both scalability and security by clearly separating data ownership and execution authority.
### **2.1 System Components**
The MCP ecosystem consists of three independent execution entities:
1. **MCP Host**: The top-level application that runs or connects to the LLM. Examples include Claude Desktop, IDEs (VS Code, Cursor), or custom agent apps built by developers. The host provides the user interface and embeds an MCP client to manage connections with servers.
2. **MCP Client**: A module that runs within the host application and maintains a 1:1 connection with an MCP server. It handles protocol handshakes, capability negotiation, and message routing.
3. **MCP Server**: An independent process that exposes actual data or functionality. It communicates directly with local file systems, databases, or external APIs, providing them to the client in a standardized form (Resource, Tool, Prompt).
### **2.2 Transport Layer**
MCP is transport-agnostic but officially supports three primary transports:
| Transport Method | Mechanism | Typical Use Cases & Features | Implementation Complexity |
| :--- | :--- | :--- | :--- |
| **Stdio** | Standard Input (stdin) / Standard Output (stdout) | Communication between local processes. Standard for local host connections like Claude Desktop. High security (no network ports needed). | Low |
| **SSE** (Server-Sent Events) | HTTP Streaming (Server -> Client) + POST (Client -> Server) | One-way event stream. Ideal for web-based clients or remote server connections. Firewall friendly. | Medium |
| **Streamable HTTP** | Bidirectional HTTP Streaming | High-performance transport introduced in v2. Advantageous for large data transfers and real-time needs. | High |
**Implementation Note:** When using the Stdio transport, server applications must NEVER output logs to stdout. Output generated by `print()` (Python) or `console.log()` (Node.js) interferes with JSON-RPC message parsing and will break the connection. All logging must use stderr.
### **2.3 JSON-RPC Message Flow and Lifecycle**
All MCP communication follows the JSON-RPC 2.0 specification. Understanding the following message structures is essential for developers debugging or implementing the protocol directly without an SDK.
#### **2.3.1 Initialization**
Once a connection is established, the client immediately sends an `initialize` request.
**Request (Client -> Server):**
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": { "listChanged": true },
"sampling": {}
},
"clientInfo": { "name": "MyClient", "version": "1.0.0" }
}
}
```
**Response (Server -> Client):**
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": { "listChanged": true },
"resources": { "subscribe": true },
"prompts": {}
},
"serverInfo": { "name": "MyServer", "version": "1.0.0" }
}
}
```
After initialization, the client sends a `notifications/initialized` notification to complete the handshake.
### **2.4 Core Primitives**
An MCP server can provide the following three capabilities:
1. **Resources**: Read-only data endpoints, similar to GET requests. Identified by URIs (e.g., `file:///logs/error.log`), the client reads them and injects them into the LLM's context window. Includes database records, file contents, system status, etc.
2. **Tools**: Executable functions, similar to POST requests. They can have side effects (e.g., writing files, calling APIs) and are invoked by the LLM as needed.
3. **Prompts**: Reusable templates stored on the server side. When the client provides arguments, the server returns a completed message (system prompt, etc.).
---
## **3. MCP-UI Technical Specification and Implementation**
MCP-UI is an experimental standard that extends MCP capabilities into the visual realm. It allows tool execution results to return UI component definitions that the host application can render, rather than just simple text.
### **3.1 UIResource Data Structure**
The core of MCP-UI is the `UIResource` object included in the content list of a tool execution result (`CallToolResult`).
```typescript
interface UIResource {
type: 'resource';
resource: {
uri: string; // Unique identifier for the UI component (e.g., ui://dashboard/main)
mimeType:
| 'text/html'
| 'text/uri-list'
| 'application/vnd.mcp-ui.remote-dom';
text?: string; // Inline content (HTML, etc.)
blob?: string; // Base64 encoded binary
_meta?: Record<string, any>; // Metadata
};
}
```
### **3.2 Rendering Strategies and MIME Types**
1. **text/html**:
* **Behavior**: The server returns a complete HTML string. The host injects this into a sandboxed iframe's `srcDoc` attribute for rendering.
* **Pros**: Simplest to implement, allows using existing web technologies.
* **Cons**: Difficult to integrate styles with the host, and security isolation may limit functionality.
2. **text/uri-list**:
* **Behavior**: Returns an external URL. The host loads this as the `src` of an iframe.
* **Use Case**: Used for embedding already-hosted dashboards or external services.
3. **application/vnd.mcp-ui.remote-dom**:
* **Behavior**: Utilizes Shopify's `remote-dom` library. The server sends DOM manipulation commands, and the host renders them using native components or UI matching the host's design system.
* **Pros**: Provides the highest security (script execution isolation) and a UX perfectly integrated with the host application.
### **3.3 Bidirectional Interaction (UI Actions)**
MCP-UI is not a static view. Events occurring within the UI (button clicks, form submissions) are passed to the host via `onUIAction` callbacks. The host then cycles this back by calling MCP tools or executing prompts.
---
## **4. Python-based MCP Development Guide**
The Python ecosystem provides a robust development environment through the official `mcp` package and the `FastMCP` library. Python 3.10 or higher is recommended.
### **4.1 Project Setup**
```bash
# Create virtual environment and install packages
python -m venv .venv
source .venv/bin/activate
pip install "mcp[cli]" pydantic python-dotenv uvicorn
```
### **4.2 Server Implementation using FastMCP (High-Level API)**
FastMCP uses the decorator pattern to instantly convert standard Python functions into MCP tools. It includes built-in automatic schema generation and validation via Pydantic models.
**Example Code: stock_server.py**
```python
from mcp.server.fastmcp import FastMCP, Context
from pydantic import BaseModel, Field
import json
# Create server instance
mcp = FastMCP("StockAnalytics")
# Define data model (Pydantic)
class StockAnalysisRequest(BaseModel):
symbol: str = Field(..., description="Stock symbol to analyze (e.g., AAPL)")
days: int = Field(7, description="Analysis period (days)")
# Mock data store
STOCK_DATA = {
"AAPL": {"price": 150.0, "trend": "bullish"},
"GOOGL": {"price": 2800.0, "trend": "neutral"}
}
# 1. Tool Definition
@mcp.tool()
def analyze_stock(request: StockAnalysisRequest, ctx: Context = None) -> str:
"""
Performs technical analysis on a stock and returns the result.
"""
if ctx:
ctx.info(f"Analyzing stock: {request.symbol}") # Logs are passed via Context
data = STOCK_DATA.get(request.symbol.upper())
if not data:
return f"Error: Symbol {request.symbol} not found."
return json.dumps({
"symbol": request.symbol,
"price": data["price"],
"analysis": f"{request.days}-day analysis result: {data['trend']}"
}, ensure_ascii=False)
# 2. Resource Definition
@mcp.resource("stock://{symbol}/realtime")
def get_realtime_price(symbol: str) -> str:
"""Returns real-time price information for a specific symbol."""
data = STOCK_DATA.get(symbol.upper())
return str(data["price"]) if data else "N/A"
# 3. Prompt Definition
@mcp.prompt()
def investment_advisor(symbol: str) -> str:
"""Investment Advisor Persona Prompt"""
return f"""
You are a fund manager with 20 years of experience on Wall Street.
A user has inquired about the symbol '{symbol}'.
Analyze the risks and opportunities for this stock in a professional tone.
"""
# 4. MCP-UI Resource Return Tool
@mcp.tool()
def show_dashboard(symbol: str) -> dict:
"""Returns a stock dashboard UI."""
html_content = f"""
<div class="dashboard">
<h1>{symbol} Dashboard</h1>
<div class="chart-placeholder">Chart Area</div>
<button onclick="window.parent.postMessage({{'type': 'action', 'action': 'refresh'}}, '*')">Refresh</button>
</div>
"""
# Return UIResource structure (directly as a dictionary)
return {
"content": [
{
"type": "resource",
"resource": {
"uri": f"ui://stock/{symbol}/dashboard",
"mimeType": "text/html",
"text": html_content
}
}
]
}
if __name__ == "__main__":
# Run in Stdio mode
mcp.run(transport="stdio")
```
### **4.2.1 Best Practices for Tool Schemas**
To ensure LLMs can correctly understand and use your tools, providing a rich schema is critical.
1. **Avoid `object` or Missing Type Hints**: If you do not provide type hints, FastMCP cannot generate a schema, and the LLM will see the argument as a generic object, leading to poor performance.
2. **Use Pydantic Models**: For tools with multiple arguments or complex validation logic, define a Pydantic `BaseModel`. This allows you to group arguments and provide detailed descriptions for each field.
3. **Use `Field` and `Annotated`**: Even for simple arguments, use `Field(..., description="...")` to explain what the argument does.
### **4.3 Python Client Implementation (Low-Level API)**
The client controls the server process using `ClientSession` and the `stdio_client` context manager.
**Example Code: client_app.py**
```python
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def run_client():
# Server process configuration
server_params = StdioServerParameters(
command="python",
args=["stock_server.py"], # Update with actual path
env=None
)
# Establish Stdio connection
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Handshake
await session.initialize()
# List tools
tools = await session.list_tools()
print(f"[Client] Available Tools: {[t.name for t in tools.tools]}")
# Call tool
result = await session.call_tool(
"analyze_stock",
arguments={"symbol": "AAPL", "days": 30}
)
print(f"[Client] Tool Result: {result.content[0].text}")
# List resources
resources = await session.list_resources()
print(f"[Client] Resources: {[r.uri for r in resources.resources]}")
if __name__ == "__main__":
asyncio.run(run_client())
```
---
## **5. Node.js (TypeScript) based MCP Development Guide**
The Node.js environment is particularly well-suited for integration with web technologies (SSE) and asynchronous processing. Using TypeScript and the `zod` library to ensure type safety is the standard pattern.
### **5.1 Project Setup**
```bash
mkdir mcp-node-server
cd mcp-node-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
```
### **5.2 TypeScript Server Implementation**
The server is configured using the `McpServer` class. Input schemas for tools are defined as `zod` objects, which are automatically converted to JSON Schema for the MCP protocol.
**Example Code: src/index.ts**
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create server instance
const server = new McpServer({
name: "FileSystemManager",
version: "1.0.0",
});
// 1. Tool Registration: Read File
server.tool(
"read_file_safe",
"Safely reads a file at a specified path.",
{
path: z.string().describe("Absolute path of the file to read"),
},
async ({ path }) => {
// Security check (Path Traversal Check) is essential in a real implementation
const content = ``;
return {
content: [
{
type: "text",
text: content,
},
],
};
}
);
// 2. Tool Registration: Return MCP-UI Card
server.tool(
"show_status_card",
"Displays a system status card in the UI.",
{}, // No arguments
async () => {
const html = `
<div style="border: 1px solid #ccc; padding: 15px; border-radius: 8px;">
<h3>System Status: Online</h3>
<p>CPU Usage: 12%</p>
<progress value="12" max="100"></progress>
</div>
`;
return {
content: [
{
type: "resource",
resource: {
uri: "ui://system/status",
mimeType: "text/html",
text: html
}
}
],
};
}
);
// 3. Resource Registration
server.resource(
"app-config",
"config://app/settings",
async (uri) => {
return {
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify({ theme: "dark", notifications: true })
}
],
};
}
);
// Run Server (Stdio)
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP Server is running on stdio transport");
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});
```
### **5.3 Node.js Client Implementation**
The Node.js client uses the `Client` class and spawns the process by passing the server execution command to `StdioClientTransport`.
**Example Code: src/client.ts**
```typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
async function runClient() {
// Transport setup: execute server script
const transport = new StdioClientTransport({
command: "npx",
args: ["tsx", "./src/index.ts"],
});
const client = new Client(
{ name: "NodeClient", version: "1.0.0" },
{ capabilities: { tools: {}, resources: {} } }
);
await client.connect(transport);
// List tools
const tools = await client.listTools();
console.log("Available Tools:", tools.tools.map(t => t.name));
// Call tool
const result = await client.callTool({
name: "read_file_safe",
arguments: { path: "/var/log/syslog" },
});
console.log("Tool Result:", result.content);
}
runClient().catch(console.error);
```
---
## **6. Security Guidelines and Best Practices**
Since MCP servers act as proxies to the local system, security vulnerabilities can lead to system-wide compromise. Strict adherence to the following security principles is required from the development stage.
### **6.1 Root Restrictions and Path Traversal Prevention**
When providing file system access tools, the most important security measure is blocking access outside of **allowed directories (Allowlist)**.
**Python Security Implementation Example:**
```python
import os
from pathlib import Path
ALLOWED_ROOT = Path("/app/safe_data").resolve()
def validate_path(user_path: str) -> Path:
# 1. Convert to absolute path
target_path = (ALLOWED_ROOT / user_path).resolve()
# 2. Prevent jailbreak by checking the common path
if not str(target_path).startswith(str(ALLOWED_ROOT)):
raise PermissionError(f"Access Denied: Path must be within {ALLOWED_ROOT}")
return target_path
```
Attackers may attempt to access system files by entering paths like `../../etc/passwd`. Rather than simply checking strings, it is safer to resolve the path at the OS level and then compare prefixes.
### **6.2 Sandboxing**
In production environments or when running untrusted tools, isolated environments must be used.
* **Utilize Docker**: Run the MCP server itself inside a Docker container and mount only necessary volumes as read-only (`:ro`).
* **Minimize Privileges**: The server process must never be run with root privileges.
### **6.3 Sampling and Human-in-the-Loop**
MCP servers can request tasks back from the client (LLM) via `sampling/createMessage`. In this case, a malicious server could hijack the LLM to attempt prompt injection or consume excessive tokens.
* **Approval Process**: The client (host) must receive **explicit approval (Yes/No)** from the user for any server sampling requests or sensitive tool execution requests (e.g., payments, sending emails).
* **Token Limits**: Resource exhaustion should be prevented by enforcing `maxTokens`, etc., during sampling requests.
---
## **7. Debugging and Development Tools: MCP Inspector**
MCP Inspector is a powerful web-based tool that allows you to test servers without implementing a client yourself. It enables developers to visually inspect tool calls, resource lookups, and protocol message flows.
### **7.1 How to Run Inspector**
Use the `npx` command to wrap your local server with an Inspector proxy.
**Python Server Debugging:**
```bash
# When using uv (recommended)
npx @modelcontextprotocol/inspector uv run stock_server.py
# When using standard python
npx @modelcontextprotocol/inspector python stock_server.py
```
**Node.js Server Debugging:**
```bash
npx @modelcontextprotocol/inspector node dist/index.js
```
### **7.2 Inspector Tips**
1. **Transport Type**: Ensure the transport type (usually Stdio) used by the server matches the Inspector UI connection.
2. **Log Monitoring**: Check for parsing errors or schema validation failure messages through the 'Notifications' tab in Inspector or the terminal's stderr output.
3. **Environment Variables**: Environment variables required for server execution (e.g., API keys) can be passed when running Inspector using the `-e KEY=VALUE` option.
---
## **8. Conclusion**
MCP is a vital standard unifying the fragmented AI ecosystem, and MCP-UI has the potential to revolutionize the user experience through this. This guide has provided all the knowledge necessary for developers to build secure and scalable MCP systems even without an internet connection.
For a successful MCP project, developers should remember these three principles:
1. **Maintain Stdio Communication Purity**: Prevent stdout contamination and strictly separate logging.
2. **Security-First Design**: Implement input validation, path restrictions, and sandboxing.
3. **Strategic Use of UIResource**: Provide rich interactions beyond simple text.
It is recommended to expand with tools and resources specialized for each domain based on this document.
---
**[Reference Identifiers]**
* **MCP Architecture and Concepts**: 1
* **Python SDK/Implementation**: 9
* **Node.js SDK/Implementation**: 10
* **MCP-UI and Resources**: 4
* **Security and Best Practices**: 21
* **Inspector and Debugging**: 26
#### **Works cited**
1. Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/](https://modelcontextprotocol.io/)
2. What is Model Context Protocol (MCP)? A guide - Google Cloud, accessed January 25, 2026, [https://cloud.google.com/discover/what-is-model-context-protocol](https://cloud.google.com/discover/what-is-model-context-protocol)
3. Model Context Protocol (MCP). MCP is an open protocol that… | by Aserdargun, accessed January 25, 2026, [https://medium.com/@aserdargun/model-context-protocol-mcp-e453b47cf254](https://medium.com/@aserdargun/model-context-protocol-mcp-e453b47cf254)
4. MCP-UI-Org/mcp-ui: UI over MCP. Create next-gen UI experiences with the protocol and SDK! - GitHub, accessed January 25, 2026, [https://github.com/MCP-UI-Org/mcp-ui](https://github.com/MCP-UI-Org/mcp-ui)
5. Specification - Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/specification/2025-06-18](https://modelcontextprotocol.io/specification/2025-06-18)
6. Model Context Protocol (MCP) and AI, accessed January 25, 2026, [https://chesterbeard.medium.com/model-context-protocol-mcp-and-ai-3e86d2908d1f](https://chesterbeard.medium.com/model-context-protocol-mcp-and-ai-3e86d2908d1f)
7. New Prompt Injection Attack Vectors Through MCP Sampling - Palo Alto Networks Unit 42, accessed January 25, 2026, [https://unit42.paloaltonetworks.com/model-context-protocol-attack-vectors/](https://unit42.paloaltonetworks.com/model-context-protocol-attack-vectors/)
8. MCP Docs - Model Context Protocol (MCP), accessed January 25, 2026, [https://modelcontextprotocol.info/docs/](https://modelcontextprotocol.info/docs/)
9. modelcontextprotocol/python-sdk: The official Python SDK for Model Context Protocol servers and clients - GitHub, accessed January 25, 2026, [https://github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk)
10. modelcontextprotocol/typescript-sdk: The official TypeScript ... - GitHub, accessed January 25, 2026, [https://github.com/modelcontextprotocol/typescript-sdk](https://github.com/modelcontextprotocol/typescript-sdk)
11. Build an MCP server - Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/docs/develop/build-server](https://modelcontextprotocol.io/docs/develop/build-server)
12. model-context-protocol-resources/guides/mcp-client-development-guide.md at main, accessed January 25, 2026, [https://github.com/cyanheads/model-context-protocol-resources/blob/main/guides/mcp-client-development-guide.md](https://github.com/cyanheads/model-context-protocol-resources/blob/main/guides/mcp-client-development-guide.md)
13. MCP Message Types: Complete MCP JSON-RPC Reference Guide - Portkey, accessed January 25, 2026, [https://portkey.ai/blog/mcp-message-types-complete-json-rpc-reference-guide/](https://portkey.ai/blog/mcp-message-types-complete-json-rpc-reference-guide/)
14. MCP Python SDK - PyPI, accessed January 25, 2026, [https://pypi.org/project/mcp/1.7.1/](https://pypi.org/project/mcp/1.7.1/)
15. postman/mcp-ui-client - NPM, accessed January 25, 2026, [https://www.npmjs.com/package/%40postman%2Fmcp-ui-client](https://www.npmjs.com/package/%40postman%2Fmcp-ui-client)
16. MCP-UI: A Technical Overview of Interactive Agent Interfaces - WorkOS, accessed January 25, 2026, [https://workos.com/blog/mcp-ui-a-technical-deep-dive-into-interactive-agent-interfaces](https://workos.com/blog/mcp-ui-a-technical-deep-dive-into-interactive-agent-interfaces)
17. jlowin/fastmcp: The fast, Pythonic way to build MCP servers and clients - GitHub, accessed January 25, 2026, [https://github.com/jlowin/fastmcp](https://github.com/jlowin/fastmcp)
18. Build an MCP client - Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/docs/develop/build-client](https://modelcontextprotocol.io/docs/develop/build-client)
19. Zod: Intro, accessed January 25, 2026, [https://zod.dev/](https://zod.dev/)
20. Building MCP clients-Node.js, accessed January 25, 2026, [https://modelcontextprotocol.info/docs/tutorials/building-a-client-node/](https://modelcontextprotocol.info/docs/tutorials/building-a-client-node/)
21. SEP-1708: MCP Client-Brokered Filesystem Access - GitHub, accessed January 25, 2026, [https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1708](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1708)
22. Best Practices for Secure MCP Resource Access (Client & Server) | by Yani - Medium, accessed January 25, 2026, [https://medium.com/@yany.dong/best-practices-for-secure-mcp-resource-access-client-server-25a9f98055d4](https://medium.com/@yany.dong/best-practices-for-secure-mcp-resource-access-client-server-25a9f98055d4)
23. The complete guide to MCP security: How to secure MCP servers & clients - WorkOS, accessed January 25, 2026, [https://workos.com/blog/mcp-security-risks-best-practices](https://workos.com/blog/mcp-security-risks-best-practices)
24. How To Sandbox or Containerize Your MCP Servers, accessed January 25, 2026, [https://mcpmanager.ai/blog/sandbox-mcp-servers/](https://mcpmanager.ai/blog/sandbox-mcp-servers/)
25. Sampling - Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/specification/draft/client/sampling](https://modelcontextprotocol.io/specification/draft/client/sampling)
26. How to use MCP Inspector - by Laurent Kubaski - Medium, accessed January 25, 2026, [https://medium.com/@laurentkubaski/how-to-use-mcp-inspector-2748cd33faeb](https://medium.com/@laurentkubaski/how-to-use-mcp-inspector-2748cd33faeb)
27. MCP Inspector - Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/docs/tools/inspector](https://modelcontextprotocol.io/docs/tools/inspector)
28. 10 - MCP Inspector: Test and Debug your MCP Server Locally - YouTube, accessed January 25, 2026, [https://www.youtube.com/watch?v=Y0tZ35dFFx4](https://www.youtube.com/watch?v=Y0tZ35dFFx4)
29. modelcontextprotocol/inspector: Visual testing tool for MCP servers - GitHub, accessed January 25, 2026, [https://github.com/modelcontextprotocol/inspector](https://github.com/modelcontextprotocol/inspector)
30. Resources & Templates - FastMCP, accessed January 25, 2026, [https://gofastmcp.com/servers/resources](https://gofastmcp.com/servers/resources)
31. modelcontextprotocol/sdk - NPM, accessed January 25, 2026, [https://www.npmjs.com/package/@modelcontextprotocol/sdk?ref=blog.promptlayer.com](https://www.npmjs.com/package/@modelcontextprotocol/sdk?ref=blog.promptlayer.com)
32. How to build MCP servers with TypeScript SDK - DEV Community, accessed January 25, 2026, [https://dev.to/shadid12/how-to-build-mcp-servers-with-typescript-sdk-1c28](https://dev.to/shadid12/how-to-build-mcp-servers-with-typescript-sdk-1c28)
33. MCP-UI Just Gave MCP a Frontend - Medium, accessed January 25, 2026, [https://medium.com/@kenzic/mcp-ui-just-gave-mcp-a-frontend-aea0ebc02253](https://medium.com/@kenzic/mcp-ui-just-gave-mcp-a-frontend-aea0ebc02253)
34. Security Best Practices - Model Context Protocol, accessed January 25, 2026, [https://modelcontextprotocol.io/specification/draft/basic/security_best_practices](https://modelcontextprotocol.io/specification/draft/basic/security_best_practices)