Mendalami dua primitives pasif MCP: Resources sebagai penyedia data konteks lewat resources/list dan resources/read dengan resource URIs dan templates, serta Prompts sebagai template reusable lewat prompts/list dan prompts/get dengan argument binding.

Di episode 4 kita membedah Tools — primitives yang "bertindak". Sekarang giliran dua primitives yang lebih pasif tapi sama pentingnya: Resources dan Prompts. Kalau tools adalah tangan server, maka resources adalah perpustakaan dan prompts adalah resep siap pakai.
Episode ini membahas bagaimana resources didaftarkan dan dibaca lewat resources/list dan resources/read, apa itu resource URIs dan resource templates, lalu bagaimana prompt template didaftarkan lewat prompts/list dan diambil lewat prompts/get dengan argument binding. Paham dua primitives ini, dan pemahaman MCP kalian sudah tiga perempat jalan.
Resources adalah data berformat yang bisa dibaca model sebagai konteks. Beberapa contoh nyata:
README.md atau konfigurasi server.Sifat pembeda resources: pasif. Membaca resource tidak mengubah state apa pun — model membaca, server mengirim data, selesai. Karena sifatnya ini, resources sangat cocok untuk pola RAG (retrieval-augmented generation) yang akan kita bahas di episode 20.
Setiap resource punya alamat unik berupa URI. MCP memakai URI standar (file://, https://, atau skema custom) dengan format scheme diikuti host dan path. Contoh: file:///home/user/config.json, weather://jakarta/current, atau git://repo/main/README.md. URI inilah yang dipakai client untuk meminta resource tertentu — tidak peduli apakah resource itu file fisik, entri database, atau data buatan server.
Method resources/list mengembalikan daftar resource yang tersedia:
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list",
"params": {}
}Server menjawab dengan daftar resource berisi uri dan name. Sama seperti tools, daftar ini mendukung pagination lewat nextCursor jika jumlahnya besar.
Untuk mengambil isi sebuah resource, client memanggil resources/read dengan URI:
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/read",
"params": {
"uri": "file:///home/user/config.json"
}
}Server membalas dengan konten ber-format (text atau blob):
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"contents": [
{
"uri": "file:///home/user/config.json",
"mimeType": "application/json",
"text": "{ \"port\": 8080 }"
}
]
}
}mimeType memberi tahu host jenis konten, sementara text (atau blob untuk biner) memuat datanya. Dari sinilah model mendapatkan konteks untuk menjawab pertanyaan.
Kadang resource tidak bisa didaftarkan satu per satu — misalnya "file apa pun di dalam direktori". Di sinilah resource templates bekerja. Template adalah pola URI dengan parameter placeholder:
{
"resourceTemplates": [
{
"uriTemplate": "file://{path}",
"name": "File di workspace"
}
]
}Pola URI dengan placeholder path cocok dengan URI mana pun seperti file:///home/user/app.py. Ketika client ingin membaca file:///home/user/app.py, server cukup mencocokkan URI dengan template dan melayani request. Template ini membuat resource tak hingga jumlahnya — dari satu pola.
Kalau tools dan resources menyediakan isi, prompts menyediakan struktur. Prompt adalah template pesan reusable yang dirancang untuk menyelesaikan tugas tertentu — misalnya "ringkas meeting", "generate commit message", atau "review pull request".
Perbedaan penting dari tools: prompt tidak "melakukan" apa pun. Ia menyiapkan pesan yang nantinya dikirim ke model. Model lah yang bertindak — tapi arah tugasnya sudah dirancang server.
Method prompts/list mengembalikan daftar prompt yang tersedia:
{
"jsonrpc": "2.0",
"id": 1,
"method": "prompts/list",
"params": {}
}Setiap prompt didefinisikan dengan name, description, dan daftar arguments yang bisa diisi pengguna.
Saat pengguna memilih prompt, host memanggil prompts/get dengan nama prompt dan argumen:
{
"jsonrpc": "2.0",
"id": 2,
"method": "prompts/get",
"params": {
"name": "summarize-meeting",
"arguments": {
"meetingId": "2026-08-03"
}
}
}Server membalas dengan rangkaian pesan (messages) yang siap dikirim ke model. Perhatikan bagian argument binding: server mengisi nilai meetingId ke dalam template sehingga menghasilkan pesan yang spesifik untuk rapat itu.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"description": "Ringkas catatan rapat",
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Ringkas catatan rapat dengan ID 2026-08-03 menjadi tiga poin."
}
}
]
}
}Info
Resource dan prompt adalah primitives pasif, tapi perannya beda: resource menyediakan data yang dibaca model, sedangkan prompt menyediakan instruksi yang dikirim ke model. Tools yang melakukan aksi bisa memakai keduanya sebagai input maupun output.
Biar tidak tertukar, ini panduan cepatnya:
| Kebutuhan | Pilih |
|---|---|
| Model butuh data/fakta (isi file, hasil query) | Resources |
| Model butuh struktur tugas (ringkas, review, generate) | Prompts |
| Model harus melakukan aksi (kirim email, tulis file) | Tools |
Aturan sederhananya: data dibaca lewat resources, pekerjaan distrukturkan lewat prompts, dan tindakan dieksekusi lewat tools. Ketiganya saling melengkapi dalam satu server. Untuk melihat daftar lengkap resource dan prompt server kalian secara interaktif, jalankan npx @modelcontextprotocol/inspector dan buka tab yang sesuai.
Pada episode 5 ini kalian sudah memahami Resources sebagai penyedia data konteks (dengan resource URIs dan resource templates), serta Prompts sebagai template reusable (dengan argument binding). Kalian juga tahu kapan memakai masing-masing primitives.
Inti yang harus dibawa pulang:
resources/read memakai resource URIs.prompts/get dan menghasilkan pesan siap kirim ke model.Di episode 6 berikutnya kita akan mulai hands-on: membangun server MCP dengan SDK — TypeScript memakai McpServer dan FastMCP, serta Python memakai FastMCP, sampai menghasilkan tool server sederhana yang siap diuji. Sampai jumpa di episode 6!