Dipublikasikan 3 Agustus 2026
Model Context Protocol (MCP) adalah standar terbuka yang memungkinkan LLM seperti Microsoft 365 Copilot terhubung ke data privat dan tool khusus. Sebagian besar implementasi MCP berfokus pada setup lokal, tapi deploying MCP server di cloud-native serverless seperti Azure Functions membuka scalability, security, dan fleksibilitas untuk aplikasi enterprise. Artikel ini mengikuti panduan dari Nirav Raval untuk membangun gateway MCP server production-grade.
Arsitektur paling optimal untuk MCP di Azure Functions adalah Gateway Pattern. Alih-alih memetakan setiap tool ke endpoint fungsi terpisah, satu fungsi McpGateway bertindak sebagai protocol adapter yang mengekspos seluruh API melalui satu entry point.
Alur request berjalan secara terstruktur: client mengirimkan request JSON-RPC ke endpoint /api/mcp. Gateway memvalidasi request, mengidentifikasi user context, lalu memparse method yang diminta. Execution engine menggunakan reflection dan dependency injection untuk menemukan dan menjalankan tool yang sesuai. Hasilnya dipackage dalam JSON-RPC response dan dikembalikan ke client.
MCP beroperasi di atas JSON-RPC 2.0, protokol stateless. Gateway harus menangani tiga method inti: initialize, tools/list, dan tools/call.
Sebelum memanggil tool apa pun, client melakukan handshake dengan server untuk memahami kapabilitasnya. Berikut implementasi Azure Function untuk method initialize:
[Function("McpGateway")]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
var requestBody = await req.ReadAsStringAsync();
var jsonRequest = JsonConvert.DeserializeObject<JObject>(requestBody);
var method = jsonRequest["method"]?.ToString();
var id = jsonRequest["id"];
if (method == "initialize") {
return await CreateJsonRpcResponse(req, id, new {
protocolVersion = "2025-11-25",
capabilities = new { tools = new { listChanged = true } },
serverInfo = new { name = "EnterpriseMcpServer", version = "1.0.0" }
});
}
}
Contoh input:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {}
}
}
Contoh output:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-11-25",
"capabilities": { "tools": { "listChanged": true } },
"serverInfo": { "name": "McpServer", "version": "1.0.0" }
}
}
Dynamic tool discovery memungkinkan server menemukan tool secara otomatis tanpa hard-coding. Anda cukup menandai class dan method dengan attribute, lalu sistem memindainya saat runtime.
Definisi attribute:
[AttributeUsage(AttributeTargets.Class)]
public class McpToolProviderAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Method)]
public class McpToolAttribute : Attribute {
public string Name { get; set; }
public string Description { get; set; }
}
Server menggunakan reflection untuk membangun daftar tool:
var toolList = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetCustomAttribute<McpToolProviderAttribute>() != null)
.SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttribute<McpToolAttribute>() != null)
.Select(m => new {
name = m.GetCustomAttribute<McpToolAttribute>().Name,
description = m.GetCustomAttribute<McpToolAttribute>().Description,
inputSchema = new {
type = "object",
properties = m.GetParameters().ToDictionary(
p => p.Name,
p => new { type = GetJsonType(p.ParameterType), description = GetDescription(p) }
),
required = m.GetParameters().Where(p => !p.IsOptional).Select(p => p.Name)
}
});
Contoh definisi tool:
[McpToolProvider]
public class SharePointTools {
[McpTool(Name = "search_documents", Description = "Search for files in a document library")]
public string SearchDocs(string query, int limit = 5) => $"Results for {query}";
}
Execution engine adalah jembatan antara AI dan logika aplikasi Anda. Engine menemukan tool yang sesuai, menyiapkan input, menjalankan method, lalu mengembalikan hasil secara terstruktur.
private async Task<string> InvokeToolAsync(string toolName, JObject arguments)
{
var toolInfo = _toolRegistry[toolName];
var toolInstance = _serviceProvider.GetRequiredService(toolInfo.Type);
var method = toolInfo.Method;
var parameters = method.GetParameters();
object[] methodArgs = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++) {
var p = parameters[i];
if (arguments.TryGetValue(p.Name, out var token)) {
methodArgs[i] = token.ToObject(p.ParameterType);
} else if (p.IsOptional) {
methodArgs[i] = p.DefaultValue;
}
}
var result = method.Invoke(toolInstance, methodArgs);
return result is Task<string> t ? await t : result?.ToString();
}
Contoh input tools/call:
{
"method": "tools/call",
"params": {
"name": "Get_record",
"arguments": {
"recordId": "REC-99",
"status": "InProgress"
}
}
}
Beberapa praktik terbaik untuk MCP server di Azure Functions:
Ekstrak JWT token dari header Authorization untuk autentikasi dan otorisasi.
Implementasikan semua tool sebagai Task<string> agar selaras dengan natur asynchronous Azure Functions dan external API calls.
Gunakan dependency injection untuk akses database, logging, dan service enterprise lainnya.
Pisahkan tool read dan write dengan izin yang berbeda untuk meminimalkan blast radius.
Deploying MCP server di Azure Functions memberikan beberapa keunggulan dibanding setup lokal:
Scalability otomatis: Azure Functions scale on-demand, cocok untuk beban kerja yang fluktuatif.
Cost-efficiency: Bayar hanya saat fungsi berjalan, ideal untuk proof-of-concept hingga production.
Enterprise security: Integrasi native dengan Azure AD, managed identity, dan network isolation.
Maintenance minimal: Serverless menghilangkan overhead patching dan OS management.
Membangun MCP server dengan Gateway Pattern bukan soal menambah kompleksitas, melainkan menciptakan jembatan yang clean, aman, dan scalable antara LLM dengan sistem enterprise Anda.
Dapatkan feedback, users, dan eksposur dari komunitas kreator, developer, dan entrepreneur digital Indonesia.
Submit Produk → Pelajari Dulu