Scenario Experience


Feishu
Choose your preferred way to join


Understanding MCP's technical architecture and working principles can help you better use and optimize MCP services. This article will deeply analyze MCP's core technologies.
Application Layer:
Protocol Layer:
Service Layer:
MCP is based on JSON-RPC 2.0 protocol, a lightweight remote procedure call protocol.
Request Format:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query",
"arguments": {
"question": "Query order total",
"role_id": null,
"role_variables": null
}
}
}
Response Format:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"status\": \"success\", \"data\": \"Order total is ¥123,456\"}"
}
]
}
}
Working Principle:
Characteristics:
Startup Process:
# AI application starts MCP Server
$ uvx asktable-mcp-server@latest
# Environment variables
API_KEY=xxx
DATASOURCE_ID=yyy
# Communication
stdin ← JSON-RPC request
stdout → JSON-RPC response
stderr → Log output
Advantages:
Disadvantages:
Working Principle:
Characteristics:
Connection Process:
SSE Event Format:
event: message
data: {"jsonrpc":"2.0","id":1,"result":{...}}
event: endpoint
data: http://localhost:8095/messages/
Advantages:
Disadvantages:
API Key Authentication:
Authentication Flow:
Credential Passing in SSE Mode:
In SSE mode, API Key is passed in two ways:
Method 1: URL Parameter (Recommended):
GET /sse/?api_key=xxx&datasource_id=yyy
Method 2: Session Storage:
# Store credentials on connection
pending_credentials[f"{client_ip}_{timestamp}"] = {
"api_key": api_key,
"datasource_id": datasource_id
}
# Associate with session on first request
session_credentials[session_id] = pending_credentials[key]
# Read from session on subsequent requests
credentials = session_credentials[session_id]
Row-Level Permissions:
# User query
query(
question="Query orders",
role_id="role_sales",
role_variables={"region": "East China"}
)
# Actually executed SQL
SELECT * FROM orders
WHERE region = 'East China' # Permission condition automatically injected
Permission Injection Flow:
Permission Rule Examples:
# Role definition
role = {
"id": "role_sales",
"rules": [
"orders.region = {{region}}",
"orders.status IN ('approved', 'completed')"
]
}
# Variable substitution
variables = {"region": "East China"}
# Final SQL
SELECT * FROM orders
WHERE region = 'East China'
AND status IN ('approved', 'completed')
Read-Only Access:
SQL Injection Prevention:
Sensitive Data Masking:
Smart Schema Linking:
Optimization Strategies:
Example:
# User question
"Query student names"
# Before optimization
SELECT * FROM students
# After optimization
SELECT name FROM students LIMIT 1000
Multi-Layer Cache:
Cache Types:
Cache Strategy:
Database Connection Pool:
# Connection pool configuration
pool = create_pool(
min_size=5, # Minimum connections
max_size=20, # Maximum connections
timeout=30, # Connection acquisition timeout
recycle=3600 # Connection recycle time
)
Advantages:
Asynchronous Query:
async def query(question: str):
# Asynchronously generate SQL
sql = await generate_sql(question)
# Asynchronously execute query
result = await execute_query(sql)
# Asynchronously format results
formatted = await format_result(result)
return formatted
Advantages:
# server.py
from fastmcp import FastMCP
mcp = FastMCP(name="Asktable MCP Server")
@mcp.tool(name='Query data using AskTable')
async def query(
question: str,
role_id: str = None,
role_variables: dict = None
) -> dict:
# Call AskTable API
result = await get_asktable_answer(
api_key=os.getenv("API_KEY"),
datasource_id=os.getenv("DATASOURCE_ID"),
question=question,
role_id=role_id,
role_variables=role_variables
)
return result
# at_apis.py
from asktable import Asktable
async def get_asktable_answer(
api_key, datasource_id, question,
base_url=None, role_id=None, role_variables=None
) -> dict:
# Create client
client = Asktable(api_key=api_key, base_url=base_url)
# Call API
response = client.answers.create(
datasource_id=datasource_id,
question=question,
role_id=role_id,
role_variables=role_variables
)
# Return result
return {
"status": "success" if response.answer else "failure",
"data": response.answer.text if response.answer else None
}
# sse_server.py
from fastapi import FastAPI
from fastmcp.server import FastMCPServer
app = FastAPI()
# Create MCP Server
mcp_server = FastMCPServer(mcp)
# SSE endpoint
@app.get("/sse/")
async def sse_endpoint(
api_key: str,
datasource_id: str
):
# Store credentials
store_credentials(api_key, datasource_id)
# Return SSE stream
return mcp_server.sse_handler()
# Message endpoint
@app.post("/messages/")
async def messages_endpoint(
session_id: str,
request: dict
):
# Get credentials
credentials = get_credentials(session_id)
# Process request
return await mcp_server.handle_request(request, credentials)
Log Levels:
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
Key Logs:
Log Example:
2026-03-08 10:30:15 - INFO - Received query: Query order total
2026-03-08 10:30:16 - INFO - Generated SQL: SELECT SUM(amount) FROM orders
2026-03-08 10:30:17 - INFO - Query completed in 1.2s
Key Metrics:
Monitoring Tools:
Stdio Mode Debugging:
# Manually run MCP Server
$ uvx asktable-mcp-server@latest
# Input JSON-RPC request
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
# View response
{"jsonrpc":"2.0","id":1,"result":{...}}
SSE Mode Debugging:
# Test SSE connection
$ curl -N http://localhost:8095/sse/?api_key=xxx&datasource_id=yyy
# Test message endpoint
$ curl -X POST http://localhost:8095/messages/?session_id=abc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
@mcp.tool(name='Custom Tool')
async def custom_tool(param: str) -> dict:
# Implement custom logic
result = await do_something(param)
return {"status": "success", "data": result}
@mcp.resource("config://settings")
async def get_settings() -> str:
# Return configuration information
return json.dumps({"key": "value"})
@mcp.prompt(name="Data Analysis Template")
async def analysis_prompt(topic: str) -> str:
return f"Please analyze {topic}'s data, including trends, anomalies, and suggestions"
MCP's technical architecture reflects the following design principles:
Simplicity:
Security:
Performance:
Scalability:
Next Steps:
Related Reading:
Technical Exchange:
No coding required. Ask questions in natural language and AI generates SQL queries and visualizations automatically.
Start your free trial now and experience AI-powered data analysis with AskTable.