Protokol Konteks Model (MCP) dengan cepat muncul sebagai cara standar untuk memberdayakan Model Bahasa Besar (LLM) seperti Claude, ChatGPT, dan lainnya untuk berinteraksi dengan dunia luar. Dengan mendefinisikan alat secara terstruktur, MCP memungkinkan LLM untuk meminta tindakan, mengambil data waktu nyata, atau berinteraksi dengan API eksternal, melampaui data pelatihan statis mereka.
Namun, menerapkan "server" MCP ini (yang menyediakan alat) sering kali menjadi tantangan, terutama di lingkungan cloud modern. Banyak implementasi awal MCP dirancang untuk eksekusi lokal, berkomunikasi melalui input/output standar (stdio), atau menggunakan protokol seperti Server-Sent Events (SSE) untuk streaming. Meskipun fungsional, pendekatan ini sering kali mengandalkan koneksi persisten dan perilaku stateful, menjadikannya tidak cocok untuk platform yang dapat diskalakan, stateless, dan berbasis peristiwa seperti AWS Lambda.
AWS Lambda menawarkan manfaat luar biasa: penskalaan otomatis, efisiensi biaya berbasis penggunaan, dan tanpa overhead manajemen server. Bagaimana kita dapat menjembatani kesenjangan ini dan menjalankan server MCP yang kuat dan siap produksi di lingkungan tanpa server ini?
Masuklah MCPEngine, implementasi Python sumber terbuka dari MCP yang dirancang khusus untuk mengatasi tantangan ini. MCPEngine mendukung HTTP yang dapat di-streaming di samping SSE, menjadikannya sepenuhnya kompatibel dengan model permintaan/respons AWS Lambda. Ini juga menyertakan fitur penting untuk penyebaran produksi, termasuk dukungan otentikasi bawaan dan pengemasan yang disederhanakan.
Artikel ini mengeksplorasi cara memanfaatkan MCPEngine untuk membangun dan menerapkan server MCP di AWS Lambda, mencakup alat stateless, manajemen status, dan otentikasi.
Apidog-MCP-Server memungkinkan Cursor untuk langsung membaca Dokumen API, yang bisa berupa dokumentasi online yang diterbitkan, atau bahkan file OpenAPI lokal.
Dengan menjadikan desain API Anda sebagai sumber kebenaran untuk AI, Apidog MCP Server memfasilitasi tugas-tugas seperti generasi kode berdasarkan skema, pencarian cerdas melalui endpoint, dan memastikan modifikasi kode selaras dengan kontrak API, yang pada akhirnya menyederhanakan alur kerja pengembangan.
Kami sangat senang untuk membagikan bahwa dukungan MCP akan segera hadir di Apidog! 🚀
— Apidog (@ApidogHQ) 19 Maret 2025
Apidog MCP Server memungkinkan Anda memberikan dokumen API langsung ke AI Agentic, meningkatkan pengalaman pengkodean Anda! Apakah Anda menggunakan Cursor, Cline, atau Windsurf - ini akan membuat proses pengembangan Anda lebih cepat dan lancar.… pic.twitter.com/ew8U38mU0K

Konsep Inti: MCPEngine dan Lambda
Sebelum masuk ke penerapan, mari kita pahami komponen utama MCPEngine untuk integrasi Lambda:
MCPEngine
: Kelas pusat yang mengatur alat Anda dan menangani komunikasi MCP.@engine.tool()
Dekorator: Mendaftarkan fungsi Python sebagai alat MCP. Nama fungsi menjadi nama alat, dan docstring-nya berfungsi sebagai deskripsi yang diberikan kepada LLM.engine.get_lambda_handler()
: Metode ini menghasilkan fungsi handler yang kompatibel dengan AWS Lambda. Anda mengekspos handler ini, dan MCPEngine mengurus penerjemahan payload acara Lambda menjadi permintaan MCP dan memformat respons.
Membangun Alat Stateless Sederhana
Mari kita mulai dengan dasar-dasar: alat stateless yang diterapkan di Lambda. Contoh ini menyediakan alat salam sederhana.
Prasyarat:
- Python 3.8+
- Akun AWS dengan izin untuk mengelola Lambda, ECR, dan IAM.
- Docker terpasang secara lokal.
- AWS CLI dikonfigurasi.
1. Instal MCPEngine:
pip install mcpengine[cli,lambda]
2. Buat Aplikasi (app.py
):
# app.py
from mcpengine import MCPEngine, Context
# Inisialisasi mesin
engine = MCPEngine()
@engine.tool()
def personalized_greeting(name: str) -> str:
"""
Menghasilkan salam ramah untuk nama yang ditentukan.
Gunakan alat ini saat diminta untuk menyapa seseorang.
"""
# Logika stateless sederhana
return f"Halo, {name}! Selamat datang di dunia MCP tanpa server."
# Dapatkan fungsi handler Lambda
handler = engine.get_lambda_handler()
Kode ini mendefinisikan satu alat, personalized_greeting
, yang menerima name
dan mengembalikan sebuah string. Variabel handler
adalah yang akan dipanggil oleh AWS Lambda.
Alur Kerja Penerapan: Kode ke Cloud
Menerapkan aplikasi MCPEngine ke Lambda melibatkan pengemasan dengan Docker, mendorongnya ke Amazon Elastic Container Registry (ECR), dan mengonfigurasi fungsi Lambda.
1. Dockerize Aplikasi (Dockerfile
):
# Gunakan gambar dasar Python AWS Lambda resmi
FROM public.ecr.aws/lambda/python:3.12
# Set direktori kerja di dalam kontainer
WORKDIR ${LAMBDA_TASK_ROOT}
# Salin persyaratan terlebih dahulu untuk memanfaatkan cache Docker
COPY requirements.txt .
# Instal dependensi (asumsikan mcpengine terdaftar di requirements.txt)
# Atau instal langsung: RUN pip install --no-cache-dir mcpengine[cli,lambda]
RUN pip install --no-cache-dir -r requirements.txt
# Salin sisa kode aplikasi
COPY app.py .
# Set perintah untuk menjalankan fungsi handler (app.handler berarti handler di app.py)
CMD ["app.handler"]
(Pastikan Anda memiliki file requirements.txt
yang mencantumkan mcpengine[cli,lambda]
atau ubah perintah RUN
sesuai kebutuhan).
2. Bangun dan Dorong Gambar Docker ke ECR:
Pertama, buat repositori ECR (ganti <region>
dan <repo-name>
):
aws ecr create-repository --repository-name <repo-name> --region <region>
Catat ID Akun AWS Anda dan URI repositori dari keluaran (<account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>
).
Sekarang, bangun, beri tag, dan dorong gambar:
# Autentikasi Docker dengan ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com
# Bangun gambar (gunakan --platform untuk build lintas arsitektur jika perlu)
docker build --platform=linux/amd64 -t <repo-name>:latest .
# Beri tag gambar untuk ECR
docker tag <repo-name>:latest <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:latest
# Dorong gambar ke ECR
docker push <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:latest
3. Buat dan Konfigurasi Fungsi Lambda:
Anda memerlukan peran eksekusi IAM untuk Lambda terlebih dahulu. Jika Anda tidak memilikinya, buat yang dasar:
# (Disederhanakan - sesuaikan kebijakan kepercayaan dan izin sesuai kebutuhan)
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
Sekarang, buat fungsi Lambda menggunakan gambar ECR (ganti placeholder):
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. Ekspose melalui URL Fungsi:
Untuk membuat Lambda dapat dipanggil melalui HTTP tanpa API Gateway, buat URL Fungsi:
aws lambda create-function-url-config \
--function-name mcp-greeter-function \
--auth-type NONE \
--region <region>
# Tambahkan izin untuk akses publik (sesuaikan jika otentikasi diperlukan)
aws lambda add-permission \
--function-name mcp-greeter-function \
--statement-id FunctionURLAllowPublicAccess \
--action lambda:InvokeFunctionUrl \
--principal '*' \
--function-url-auth-type NONE \
--region <region>
Catat URL Fungsi yang dikembalikan oleh perintah create-function-url-config
. Server MCP stateless Anda sekarang sudah aktif!
Mengelola Status dengan Konteks lifespan
Lambda adalah stateless, tetapi banyak alat memerlukan akses ke basis data, kolam koneksi, atau sumber daya lain yang diinisialisasi saat startup. MCPEngine mengatasi ini dengan argumen lifespan
, yang menerima manajer konteks async.
Fungsi lifespan
menjalankan kode setup-nya (sebelum yield
) saat kontainer Lambda dimulai dan kode teardown-nya (setelah yield
) saat kontainer dimatikan. Nilai yang dihasilkan tersedia dalam fungsi alat Anda melalui objek ctx
(Konteks).
Mari kita buat pencatat peristiwa sederhana yang menyimpan peristiwa dalam basis data RDS Postgres.
1. Modifikasi app.py
:
# app.py (Contoh Stateful)
import os
import psycopg2
from contextlib import asynccontextmanager
from mcpengine import MCPEngine, Context
# Anggap detail koneksi DB ada di variabel lingkungan
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():
"""Mengelola kolam koneksi basis data."""
conn = None
try:
print("Membangun koneksi DB...")
conn = psycopg2.connect(
host=DB_HOST,
user=DB_USER,
password=DB_PASS,
dbname=DB_NAME
)
# Buat tabel jika belum ada (contoh sederhana)
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("Koneksi DB siap.")
yield {"db_conn": conn} # Buat koneksi tersedia melalui ctx.db_conn
finally:
if conn:
print("Menutup koneksi DB.")
conn.close()
# Inisialisasi mesin dengan manajer lifespan
engine = MCPEngine(lifespan=db_connection_manager)
@engine.tool()
def log_event(event_name: str, ctx: Context) -> str:
"""Mencatat sebuah peristiwa dengan nama yang diberikan ke dalam basis data."""
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"Peristiwa '{event_name}' berhasil dicatat."
except Exception as e:
# Penanganan kesalahan dasar
ctx.db_conn.rollback()
return f"Kesalahan mencatat peristiwa: {e}"
@engine.tool()
def get_latest_events(limit: int = 5, ctx: Context) -> list[str]:
"""Mengambil peristiwa terbaru yang dicatat dari basis data."""
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"Kesalahan mengambil peristiwa: {e}"]
# Dapatkan handler Lambda
handler = engine.get_lambda_handler()
2. Pertimbangan Penerapan:
- Basis Data: Anda memerlukan instance RDS yang dapat diakses (atau basis data lain).
- Jaringan: Konfigurasi pengaturan VPC fungsi Lambda untuk mengizinkan akses ke instance RDS (Grup Keamanan, Subnet).
- Variabel Lingkungan: Pass
DB_HOST
,DB_USER
,DB_PASS
,DB_NAME
sebagai variabel lingkungan ke fungsi Lambda. - IAM: Peran eksekusi Lambda mungkin perlu izin tambahan jika mengakses layanan AWS lainnya (misalnya, Secrets Manager untuk kredensial DB).
Perbarui Dockerfile
jika diperlukan (misalnya, untuk menginstal psycopg2-binary
), bangun ulang/dorong gambar, dan perbarui kode dan konfigurasi fungsi Lambda (variabel lingkungan, pengaturan VPC).
Mengamankan Alat dengan Otentikasi
Alat produksi memerlukan otentikasi. MCPEngine terintegrasi dengan penyedia OpenID Connect (OIDC) seperti Google, AWS Cognito, Auth0, dll.
1. Konfigurasi Penyedia OIDC:
Atur ID klien OAuth dengan penyedia pilihan Anda (misalnya, Google Cloud Console). Anda akan memerlukan Client ID dan mungkin Client Secret (tergantung pada alur).
2. Perbarui app.py
untuk Otentikasi:
# app.py (Contoh Terautentikasi - Snippet)
import os
# ... impor lainnya ...
from mcpengine import MCPEngine, Context, GoogleIdpConfig # Atau IdpConfig lainnya
# ... db_connection_manager ...
# Konfigurasi IDP - menggunakan Google sebagai contoh
# Menganggap GOOGLE_CLIENT_ID disetel sebagai variabel lingkungan
google_config = GoogleIdpConfig(
client_id=os.environ.get("GOOGLE_CLIENT_ID")
# penerbit dapat sering diturunkan, atau diatur secara eksplisit
)
# Inisialisasi mesin dengan lifespan dan konfigurasi IDP
engine = MCPEngine(
lifespan=db_connection_manager,
idp_config=google_config
)
# Amankan alat log_event
@engine.auth() # Tambahkan dekorator ini
@engine.tool()
def log_event(event_name: str, ctx: Context) -> str:
"""Mencatat sebuah peristiwa dengan nama yang diberikan ke dalam basis data. Memerlukan otentikasi."""
# Akses informasi pengguna yang terautentikasi jika diperlukan: user_email = ctx.user.email
user_email = ctx.user.email if ctx.user else "tidak diketahui"
print(f"Pengguna terautentikasi: {user_email}")
try:
# ... (logika basis data tetap sama) ...
return f"Peristiwa '{event_name}' berhasil dicatat oleh {user_email}."
except Exception as e:
# ... penanganan kesalahan ...
return f"Kesalahan mencatat peristiwa untuk {user_email}: {e}"
# get_latest_events dapat tetap tidak terautentikasi atau diamankan juga
@engine.tool()
def get_latest_events(limit: int = 5, ctx: Context) -> list[str]:
# ... (logika tetap sama) ...
# Dapatkan handler Lambda
handler = engine.get_lambda_handler()
Perubahan Utama:
- Mengimpor
GoogleIdpConfig
(atau yang sesuai untuk penyedia Anda). - Menginstansiasi
MCPEngine
dengan argumenidp_config
. - Menambahkan dekorator
@engine.auth()
di atas@engine.tool()
untuk fungsi yang memerlukan otentikasi. MCPEngine akan secara otomatis menolak permintaan tanpa token JWT yang valid yang diverifikasi terhadap kunci publik IDP. - Informasi pengguna terautentikasi (dari klaim JWT) tersedia melalui
ctx.user
.
3. Penerapan:
- Pass variabel lingkungan yang diperlukan untuk otentikasi (misalnya,
GOOGLE_CLIENT_ID
) ke fungsi Lambda Anda. - Bangun ulang/dorong gambar dan perbarui fungsi Lambda.
Menghubungkan Klien LLM
Setelah server MCP Anda diterapkan di Lambda dengan URL Fungsi, Anda dapat menghubungkan klien yang kompatibel. Menggunakan mcpengine proxy
adalah cara yang nyaman untuk menjembatani klien seperti Claude:
mcpengine proxy <nama-layanan-yang-anda-pilih> <url-fungsi-lambda-anda> --mode http --claude
Jika menggunakan otentikasi:
mcpengine proxy <nama-layanan-yang-anda-pilih> <url-fungsi-lambda-anda> \
--mode http \
--claude \
--client-id <client-id-google-anda> \
--client-secret <client-secret-google-anda> # Diperlukan untuk alur perolehan token
Perintah ini menjalankan proxy lokal yang terhubung ke Claude. Proxy kemudian meneruskan permintaan melalui HTTP ke URL Fungsi Lambda Anda, menangani alur otentikasi jika dikonfigurasi. LLM sekarang dapat menemukan dan memanggil alat tanpa server Anda.
Kesimpulan
Menerapkan server MCP di AWS Lambda membuka skala luar biasa dan efisiensi operasional untuk memperluas kemampuan LLM. Implementasi MCP tradisional sering kali kesulitan dalam lingkungan stateless, tetapi MCPEngine menyediakan solusi sumber terbuka yang kuat. Dengan mendukung HTTP yang dapat di-streaming, menawarkan manajemen konteks melalui lifespan
, dan terintegrasi secara mulus dengan OIDC untuk otentikasi, MCPEngine menjadikan MCP tanpa server bukan hanya mungkin, tetapi praktis untuk kasus penggunaan produksi. Baik membangun alat stateless sederhana maupun aplikasi kompleks, stateful, terautentikasi, MCPEngine yang digabungkan dengan AWS Lambda menawarkan platform yang kuat untuk generasi berikutnya dari interaksi yang didorong AI.
Ingin platform Terintegrasi, All-in-One untuk Tim Pengembang Anda bekerja sama dengan produktivitas maksimum?
Apidog memenuhi semua permintaan Anda, dan menggantikan Postman dengan harga yang jauh lebih terjangkau!