Giao thức ngữ cảnh mô hình (MCP) đang nhanh chóng trở thành một phương thức tiêu chuẩn để tăng cường các Mô hình Ngôn ngữ Lớn (LLMs) như Claude, ChatGPT và những người khác tương tác với thế giới bên ngoài. Bằng cách xác định các công cụ theo cách có cấu trúc, MCP cho phép các LLM yêu cầu hành động, lấy dữ liệu theo thời gian thực, hoặc tương tác với các API bên ngoài, vượt ra ngoài dữ liệu huấn luyện tĩnh của chúng.
Tuy nhiên, việc triển khai những "máy chủ" MCP này (cung cấp các công cụ) thường gặp khó khăn, đặc biệt là trong các môi trường đám mây hiện đại. Nhiều triển khai MCP ban đầu được thiết kế cho việc thực thi cục bộ, giao tiếp qua đầu vào/đầu ra chuẩn (stdout/stderr), hoặc sử dụng các giao thức như Server-Sent Events (SSE) để streaming. Mặc dù có chức năng, những cách tiếp cận này thường phụ thuộc vào các kết nối liên tục và hành vi có trạng thái, khiến chúng trở nên không phù hợp cho các nền tảng sự kiện không có trạng thái, có khả năng mở rộng như AWS Lambda.
AWS Lambda cung cấp nhiều lợi ích to lớn: khả năng tự động mở rộng, hiệu quả chi phí theo từng lần sử dụng, và không cần quản lý máy chủ. Làm thế nào để chúng ta có thể thu hẹp khoảng cách và chạy các máy chủ MCP vững chắc, sẵn sàng sản xuất trong môi trường không máy chủ này?
Giới thiệu MCPEngine, một việc triển khai Python mã nguồn mở của MCP được thiết kế đặc biệt để giải quyết những thách thức này. MCPEngine hỗ trợ HTTP có thể streaming bên cạnh SSE, làm cho nó hoàn toàn tương thích với mô hình yêu cầu/đáp ứng của AWS Lambda. Nó cũng gói gọn các tính năng thiết yếu cho việc triển khai sản xuất, bao gồm hỗ trợ xác thực tích hợp và đóng gói hợp lý.
Bài viết này khám phá cách khai thác MCPEngine để xây dựng và triển khai các máy chủ MCP trên AWS Lambda, bao gồm các công cụ không có trạng thái, quản lý trạng thái và xác thực.
Apidog-MCP-Server cho phép Cursor đọc trực tiếp tài liệu API, có thể là tài liệu đã được xuất bản trực tuyến, hoặc thậm chí là các tệp OpenAPI cục bộ.
Bằng cách làm cho thiết kế API của bạn là nguồn sự thật cho AI, Apidog MCP Server giúp việc tạo mã dựa trên các sơ đồ, tìm kiếm thông minh qua các điểm cuối, và đảm bảo các phép sửa đổi mã hoàn toàn đồng nhất với hợp đồng API, cuối cùng giúp tối ưu hóa quy trình phát triển.
Chúng tôi rất vui mừng thông báo rằng hỗ trợ MCP sắp có mặt trên Apidog! 🚀
— Apidog (@ApidogHQ) Ngày 19 tháng 3 năm 2025
Apidog MCP Server cho phép bạn cung cấp tài liệu API trực tiếp cho AI Agentic, nâng cao trải nghiệm lập trình của bạn! Dù bạn đang sử dụng Cursor, Cline, hay Windsurf - nó sẽ làm cho quá trình phát triển của bạn nhanh hơn và mượt mà hơn.… pic.twitter.com/ew8U38mU0K

Các khái niệm cơ bản: MCPEngine và Lambda
Trước khi đi vào triển khai, hãy hiểu các thành phần chính của MCPEngine cho tích hợp với Lambda:
MCPEngine
: Lớp trung tâm điều phối các công cụ của bạn và xử lý giao tiếp MCP.@engine.tool()
Bộ ghi chú: Đăng ký một hàm Python dưới dạng một công cụ MCP. Tên hàm trở thành tên công cụ, và chuỗi tài liệu của nó được cung cấp dưới dạng mô tả cho LLM.engine.get_lambda_handler()
: Phương thức này tạo ra một hàm xử lý tương thích với AWS Lambda. Bạn công bố hàm xử lý này, và MCPEngine sẽ chuyển đổi tải trọng sự kiện của Lambda thành các yêu cầu MCP và định dạng các phản hồi.
Xây dựng một công cụ đơn giản không có trạng thái
Chúng ta hãy bắt đầu với các khái niệm cơ bản: một công cụ không có trạng thái được triển khai trên Lambda. Ví dụ này cung cấp một công cụ chào hỏi đơn giản.
Các yêu cầu tiên quyết:
- Python 3.8+
- Một tài khoản AWS với quyền quản lý Lambda, ECR, và IAM.
- Docker được cài đặt cục bộ.
- AWS CLI đã được cấu hình.
1. Cài đặt MCPEngine:
pip install mcpengine[cli,lambda]
2. Tạo ứng dụng (app.py
):
# app.py
from mcpengine import MCPEngine, Context
# Khởi tạo động cơ
engine = MCPEngine()
@engine.tool()
def personalized_greeting(name: str) -> str:
"""
Tạo ra một lời chào thân thiện cho tên được chỉ định.
Sử dụng công cụ này khi được yêu cầu chào ai đó.
"""
# Logic đơn giản không có trạng thái
return f"Xin chào, {name}! Chào mừng bạn đến với thế giới MCP không máy chủ."
# Lấy hàm xử lý Lambda
handler = engine.get_lambda_handler()
Mã này định nghĩa một công cụ duy nhất, personalized_greeting
, nhận một name
và trả về một chuỗi. Biến handler
là cái mà AWS Lambda sẽ gọi.
Luồng triển khai: Mã lên đám mây
Triển khai một ứng dụng MCPEngine lên Lambda bao gồm việc đóng gói nó với Docker, đẩy nó lên Amazon Elastic Container Registry (ECR), và cấu hình chức năng Lambda.
1. Đóng gói ứng dụng (Dockerfile
):
# Sử dụng hình ảnh cơ sở Python Lambda của AWS chính thức
FROM public.ecr.aws/lambda/python:3.12
# Đặt thư mục làm việc trong container
WORKDIR ${LAMBDA_TASK_ROOT}
# Sao chép các yêu cầu trước để tận dụng bộ nhớ đệm Docker
COPY requirements.txt .
# Cài đặt các phụ thuộc (giả sử mcpengine có trong requirements.txt)
# Hoặc cài đặt trực tiếp: RUN pip install --no-cache-dir mcpengine[cli,lambda]
RUN pip install --no-cache-dir -r requirements.txt
# Sao chép phần còn lại của mã ứng dụng
COPY app.py .
# Đặt lệnh để chạy hàm xử lý (app.handler có nghĩa là hàm xử lý trong app.py)
CMD ["app.handler"]
(Hãy đảm bảo bạn có tệp requirements.txt
liệt kê mcpengine[cli,lambda]
hoặc điều chỉnh lệnh RUN
cho phù hợp).
2. Xây dựng và đẩy hình ảnh Docker lên ECR:
Đầu tiên, tạo một kho ECR (thay thế <region>
và <repo-name>
):
aws ecr create-repository --repository-name <repo-name> --region <region>
Ghi nhớ ID tài khoản AWS của bạn và URI kho từ đầu ra (<account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>
).
Hiện tại, xây dựng, gán thẻ và đẩy hình ảnh:
# Xác thực Docker với ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com
# Xây dựng hình ảnh (sử dụng --platform cho các bản dựng đa kiến trúc nếu cần)
docker build --platform=linux/amd64 -t <repo-name>:latest .
# Gán thẻ cho hình ảnh để ECR
docker tag <repo-name>:latest <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:latest
# Đẩy hình ảnh lên ECR
docker push <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:latest
3. Tạo và cấu hình chức năng Lambda:
Bạn sẽ cần một vai trò thực thi IAM cho Lambda trước. Nếu bạn không có một cái, hãy tạo một cái cơ bản:
# (Đơn giản hóa - điều chỉnh chính sách lòng tin và quyền truy cập theo yêu cầu)
aws iam create-role --role-name lambda-mcp-role --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "lambda.amazonaws.com"},"Action": "sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name lambda-mcp-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Bây giờ, hãy tạo chức năng Lambda bằng cách sử dụng hình ảnh ECR (thay thế các giá trị chỗ cho phù hợp):
aws lambda create-function \
--function-name mcp-greeter-function \
--package-type Image \
--code ImageUri=<account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:latest \
--role arn:aws:iam::<account-id>:role/lambda-mcp-role \
--timeout 30 \
--memory-size 512 \
--region <region>
4. Tiếp cận qua URL chức năng:
Để làm cho Lambda có thể gọi qua HTTP mà không cần API Gateway, hãy tạo một URL chức năng:
aws lambda create-function-url-config \
--function-name mcp-greeter-function \
--auth-type NONE \
--region <region>
# Thêm quyền truy cập công khai (điều chỉnh nếu cần xác thực)
aws lambda add-permission \
--function-name mcp-greeter-function \
--statement-id FunctionURLAllowPublicAccess \
--action lambda:InvokeFunctionUrl \
--principal '*' \
--function-url-auth-type NONE \
--region <region>
Ghi nhớ URL chức năng được trả về bởi lệnh create-function-url-config
. Máy chủ MCP không có trạng thái của bạn giờ đã hoạt động!
Quản lý trạng thái với ngữ cảnh lifespan
Lambda không có trạng thái, nhưng nhiều công cụ cần truy cập vào cơ sở dữ liệu, hồ bơi kết nối, hoặc các tài nguyên khác được khởi tạo khi khởi động. MCPEngine giải quyết vấn đề này bằng cách sử dụng tham số lifespan
, chấp nhận một trình quản lý ngữ cảnh bất đồng bộ.
Hàm lifespan
chạy mã thiết lập của nó (trước yield
) khi container Lambda khởi động và mã tắt của nó (sau yield
) khi container tắt. Giá trị được trả về sẽ có sẵn trong các hàm công cụ của bạn thông qua đối tượng ctx
(Ngữ cảnh).
Hãy xây dựng một nhật ký sự kiện đơn giản lưu trữ các sự kiện trong cơ sở dữ liệu RDS Postgres.
1. Chỉnh sửa app.py
:
# app.py (Ví dụ có trạng thái)
import os
import psycopg2
from contextlib import asynccontextmanager
from mcpengine import MCPEngine, Context
# Giả sử chi tiết kết nối DB nằm trong biến môi trường
DB_HOST = os.environ.get("DB_HOST")
DB_USER = os.environ.get("DB_USER")
DB_PASS = os.environ.get("DB_PASS")
DB_NAME = os.environ.get("DB_NAME")
@asynccontextmanager
async def db_connection_manager():
"""Quản lý hồ bơi kết nối cơ sở dữ liệu."""
conn = None
try:
print("Thiết lập kết nối DB...")
conn = psycopg2.connect(
host=DB_HOST,
user=DB_USER,
password=DB_PASS,
dbname=DB_NAME
)
# Tạo bảng nếu nó không tồn tại (ví dụ đơn giản)
with conn.cursor() as cur:
cur.execute("""
CREATE TABLE IF NOT EXISTS events (
id SERIAL PRIMARY KEY,
event_name TEXT NOT NULL,
timestamp TIMESTAMP DEFAULT now()
);
""")
conn.commit()
print("Kết nối DB đã sẵn sàng.")
yield {"db_conn": conn} # Làm cho kết nối có sẵn thông qua ctx.db_conn
finally:
if conn:
print("Đóng kết nối DB.")
conn.close()
# Khởi tạo động cơ với trình quản lý tuổi thọ
engine = MCPEngine(lifespan=db_connection_manager)
@engine.tool()
def log_event(event_name: str, ctx: Context) -> str:
"""Ghi lại một sự kiện với tên đã cho vào cơ sở dữ liệu."""
try:
with ctx.db_conn.cursor() as cur:
cur.execute("INSERT INTO events (event_name) VALUES (%s)", (event_name,))
ctx.db_conn.commit()
return f"Sự kiện '{event_name}' đã được ghi lại thành công."
except Exception as e:
# Xử lý lỗi cơ bản
ctx.db_conn.rollback()
return f"Lỗi ghi sự kiện: {e}"
@engine.tool()
def get_latest_events(limit: int = 5, ctx: Context) -> list[str]:
"""Lấy các sự kiện đã ghi gần đây từ cơ sở dữ liệu."""
try:
with ctx.db_conn.cursor() as cur:
cur.execute("SELECT event_name, timestamp FROM events ORDER BY timestamp DESC LIMIT %s", (limit,))
events = [f"[{row[1].strftime('%Y-%m-%d %H:%M:%S')}] {row[0]}" for row in cur.fetchall()]
return events
except Exception as e:
return [f"Lỗi khi lấy các sự kiện: {e}"]
# Lấy hàm xử lý Lambda
handler = engine.get_lambda_handler()
2. Các điều cần lưu ý khi triển khai:
- Cơ sở dữ liệu: Bạn cần một phiên bản RDS có thể truy cập (hoặc cơ sở dữ liệu khác).
- Mạng: Cấu hình cài đặt VPC của chức năng Lambda để cho phép truy cập vào phiên bản RDS (Nhóm bảo mật, Mạng con).
- Biến môi trường: Truyền
DB_HOST
,DB_USER
,DB_PASS
,DB_NAME
làm các biến môi trường cho chức năng Lambda. - IAM: Vai trò thực thi Lambda có thể cần thêm quyền nếu truy cập các dịch vụ AWS khác (ví dụ: Secrets Manager cho thông tin xác thực DB).
Cập nhật Dockerfile
nếu cần (ví dụ: để cài đặt psycopg2-binary
), xây dựng/lại hình ảnh và cập nhật mã và cấu hình của chức năng Lambda (các biến môi trường, cài đặt VPC).
Bảo mật Các công cụ với Xác thực
Các công cụ sản xuất cần xác thực. MCPEngine tích hợp với các nhà cung cấp OpenID Connect (OIDC) như Google, AWS Cognito, Auth0, v.v.
1. Cấu hình Nhà cung cấp OIDC:
Cài đặt một ID khách OAuth với nhà cung cấp mà bạn đã chọn (ví dụ: Bảng điều khiển Google Cloud). Bạn sẽ cần Client ID và có thể là Client Secret (tùy thuộc vào luồng).
2. Cập nhật app.py
cho Xác thực:
# app.py (Ví dụ đã xác thực - Các đoạn mã)
import os
# ... các nhập khác ...
from mcpengine import MCPEngine, Context, GoogleIdpConfig # Hoặc IdpConfig khác
# ... db_connection_manager ...
# Cấu hình IDP - sử dụng Google làm ví dụ
# Giả sử GOOGLE_CLIENT_ID được đặt làm biến môi trường
google_config = GoogleIdpConfig(
client_id=os.environ.get("GOOGLE_CLIENT_ID")
# nhà phát hành thường có thể được suy ra, hoặc đặt một cách rõ ràng
)
# Khởi tạo động cơ với tuổi thọ và cấu hình IDP
engine = MCPEngine(
lifespan=db_connection_manager,
idp_config=google_config
)
# Bảo mật công cụ log_event
@engine.auth() # Thêm bộ ghi chú này
@engine.tool()
def log_event(event_name: str, ctx: Context) -> str:
"""Ghi lại một sự kiện với tên đã cho vào cơ sở dữ liệu. Cần xác thực."""
# Truy cập thông tin người dùng đã xác thực nếu cần: user_email = ctx.user.email
user_email = ctx.user.email if ctx.user else "không xác định"
print(f"Người dùng đã xác thực: {user_email}")
try:
# ... (logic cơ sở dữ liệu vẫn như cũ) ...
return f"Sự kiện '{event_name}' đã được ghi lại thành công bởi {user_email}."
except Exception as e:
# ... xử lý lỗi ...
return f"Lỗi ghi sự kiện cho {user_email}: {e}"
# get_latest_events có thể vẫn không xác thực hoặc cũng được bảo mật
@engine.tool()
def get_latest_events(limit: int = 5, ctx: Context) -> list[str]:
# ... (logic vẫn như cũ) ...
# Lấy hàm xử lý Lambda
handler = engine.get_lambda_handler()
Các thay đổi chính:
- Nhập
GoogleIdpConfig
(hoặc cái phù hợp với nhà cung cấp của bạn). - Khởi tạo
MCPEngine
với tham sốidp_config
. - Thêm bộ ghi chú
@engine.auth()
trên@engine.tool()
cho các chức năng yêu cầu xác thực. MCPEngine sẽ tự động từ chối các yêu cầu mà không có một mã JWT hợp lệ được xác minh với các khóa công khai của IDP. - Thông tin người dùng đã xác thực (từ các yêu cầu JWT) có sẵn thông qua
ctx.user
.
3. Triển khai:
- Truyền các biến môi trường cần thiết cho xác thực (ví dụ:
GOOGLE_CLIENT_ID
) cho chức năng Lambda của bạn. - Xây dựng/lại hình ảnh và cập nhật chức năng Lambda.
Kết nối một Khách hàng LLM
Ngay khi máy chủ MCP của bạn đã được triển khai trên Lambda với một URL chức năng, bạn có thể kết nối các khách hàng tương thích. Sử dụng mcpengine proxy
là một cách tiện lợi để kết nối với các khách hàng như Claude:
mcpengine proxy <your-chosen-service-name> <your-lambda-function-url> --mode http --claude
Nếu sử dụng xác thực:
mcpengine proxy <your-chosen-service-name> <your-lambda-function-url> \
--mode http \
--claude \
--client-id <your-google-client-id> \
--client-secret <your-google-client-secret> # Cần cho luồng thu nhận mã
Lệnh này chạy một proxy cục bộ mà Claude sẽ kết nối đến. Proxy sau đó chuyển tiếp các yêu cầu qua HTTP đến URL chức năng Lambda của bạn, xử lý luồng xác thực nếu được cấu hình. LLM bây giờ có thể khám phá và gọi các công cụ không máy chủ của bạn.
Kết luận
Triển khai các máy chủ MCP trên AWS Lambda mở ra khả năng mở rộng và hiệu quả hoạt động đáng kinh ngạc để mở rộng khả năng của LLM. Các triển khai MCP truyền thống thường gặp khó khăn trong các môi trường không có trạng thái, nhưng MCPEngine cung cấp một giải pháp mã nguồn mở vững chắc. Bằng cách hỗ trợ HTTP có thể streaming, cung cấp quản lý ngữ cảnh thông qua lifespan
, và tích hợp liền mạch với OIDC cho xác thực, MCPEngine làm cho MCP không máy chủ không chỉ khả dĩ, mà còn thực tiễn cho các trường hợp sử dụng sản xuất. Cho dù xây dựng các công cụ không có trạng thái đơn giản hay các ứng dụng có trạng thái phức tạp, đã xác thực, MCPEngine kết hợp với AWS Lambda cung cấp một nền tảng mạnh mẽ cho thế hệ tương tác AI tiếp theo.
Bạn muốn một nền tảng tích hợp, Tất cả trong Một để đội ngũ phát triển của bạn làm việc cùng nhau với năng suất tối đa?
Apidog đáp ứng mọi yêu cầu của bạn, và thay thế Postman với giá cả phải chăng hơn nhiều!