Lewati ke konten utama

Membangun Server dan Klien MCP dengan FastMCP 2.0

Membangun, Menguji, dan Mengintegrasikan Server MCP ArXiv Explorer.
Diperbarui 28 Sep 2026  · 8 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Di dunia AI, Model Context Protocol (MCP) dengan cepat menjadi topik hangat. MCP adalah standar terbuka yang memberi model AI seperti Claude 4 cara yang konsisten untuk terhubung dengan alat eksternal, layanan, dan sumber data waktu nyata. Konektivitas ini menjadi pengubah permainan karena memungkinkan model bahasa besar (LLM) memberikan respons yang lebih relevan, mutakhir, dan dapat ditindaklanjuti dengan menjembatani kesenjangan antara AI dan sistem.

Dalam tutorial ini, kita akan menyelami FastMCP 2.0, sebuah kerangka kerja andal yang memudahkan pembuatan server MCP kita sendiri hanya dengan beberapa baris kode. Kita akan mempelajari komponen inti FastMCP, cara membangun server dan klien MCP, serta cara mengintegrasikannya secara mulus ke dalam alur kerja Anda. Jika Anda baru mengenal MCP, lihat Panduan Model Context Protocol dengan Proyek Demo untuk mempelajari lebih lanjut. 

Apa itu FastMCP 2.0?

FastMCP 2.0 adalah kerangka kerja Python sumber terbuka yang dirancang untuk membuat pembuatan server dan klien Model Context Protocol (MCP) menjadi sederhana dan efisien. Hanya dengan beberapa baris kode, pengembang dapat membuat server MCP kustom dan menghubungkannya ke aplikasi AI mereka, seperti editor kode atau asisten chatbot.

FastMCP 2.0 adalah penerus FastMCP 1.0, yang sekarang dikenal sebagai MCP Python SDK, dan menawarkan seperangkat alat lengkap untuk bekerja dalam ekosistem MCP.

Yang membedakan FastMCP 2.0 adalah kumpulan fiturnya yang komprehensif, melampaui spesifikasi inti MCP. Ia merampingkan deployment, autentikasi, proxy klien dan server, dan bahkan memungkinkan pembuatan server dari REST API.  

Komponen Inti FastMCP 2.0

FastMCP 2.0 dibangun di atas tiga komponen penting: Tools, Resources, dan Prompts.

1. Tools

Tools adalah fungsi Python yang diekspos ke LLM melalui protokol MCP. Dengan menghias fungsi menggunakan @mcp.tool, Anda memungkinkan model AI memanggilnya selama percakapan. Ini memungkinkan LLM melakukan aksi di dunia nyata, seperti mengkueri basis data, memanggil API, atau menjalankan perhitungan.

from fastmcp import FastMCPmcp = FastMCP(name="UtilityServer")@mcp.tooldef convert_usd_to_eur(amount: float, rate: float = 0.91) -> float:    """Converts a given amount in USD to EUR using the provided rate."""    return round(amount * rate, 2)

2. Resources

Resources menyediakan akses baca-saja ke data bagi LLM atau aplikasi klien, seperti file, rekaman basis data, konfigurasi, atau konten yang dihasilkan secara dinamis. Contohnya:

from fastmcp import FastMCPmcp = FastMCP(name="WeatherResourceServer")@mcp.resource("config://weather-settings")def get_weather_settings() -> dict:    """Provides weather configuration."""    return {        "default_units": "metric",        "default_location": "Berlin",        "features_enabled": ["forecast", "alerts"]    }@mcp.resource("resource://welcome-message")def welcome_message() -> str:    """Returns a dynamic greeting for users based on time of day."""    from datetime import datetime    hour = datetime.now().hour    if hour < 12:        return "Good morning! Here's your weather update."    elif hour < 18:        return "Good afternoon! Need a forecast?"    else:        return "Good evening! Let's check the weather."

3. Prompts

Prompts adalah templat pesan yang dapat digunakan kembali dan diparameterisasi untuk membimbing respons LLM. Dengan mendefinisikan prompt sebagai fungsi, Anda memastikan instruksi yang konsisten dan kaya konteks yang dapat dipanggil oleh klien. 

Ini diperlukan untuk mengeksekusi beberapa alat secara berurutan dan membimbing LLM melakukan tugas tertentu menggunakan tools dan resources yang tersedia.

from fastmcp import FastMCPfrom fastmcp.prompts.prompt import PromptMessage, TextContentmcp = FastMCP(name="TutorPromptServer")@mcp.promptdef explain_math_concept(concept: str) -> PromptMessage:    """Creates a message asking an AI tutor to explain a math concept simply."""    text = f"Can you explain the math concept of '{concept}' in a way that's easy for a 12-year-old to understand?"    return PromptMessage(role="user", content=TextContent(type="text", text=text))

Membangun AI ArXiv Explorer dengan FastMCP 2.0 dan Tavily

Di bagian ini, kita akan membangun server MCP "ArXiv Explorer". Server ini akan terdiri dari dua alat: satu untuk mengekstrak tautan dan judul makalah riset, dan satu lagi untuk meringkas makalah tersebut. Selain tools ini, server juga akan menyertakan resources dan prompts untuk membantu membuat laporan komprehensif tentang topik yang dipilih.

1. Penyiapan

Sebelum mulai, Anda perlu mendapatkan kunci API Tavily. Anda bisa mendapatkan kunci gratis dengan 1.000 permintaan per bulan di tavily.com. Lalu, pasang pustaka Python yang diperlukan:

pip install fastmcp tavily-python

2. Membangun server "ArxivExplorer"

Kita akan terlebih dahulu membuat file Python server. File ini terdiri dari:

  1. Inisialisasi: Buat instance FastMCP dengan memberi nama server "ArxivExplorer".
  2. Resource: Dekorator @mcp.resource mengekspos fungsi arxiv_topics kita sebagai sumber data baca-saja. Klien AI dapat mengambil topik ini untuk mendapatkan ide riset, jika pengguna belum yakin.
  3. Tools: Dekorator @mcp.tool mengubah fungsi Python biasa menjadi aksi yang dapat dieksekusi LLM.
    1. search_arxiv: Alat ini menggunakan API Tavily untuk membatasi pencarian ke domain tertentu (arxiv.org), memastikan kita hanya mendapatkan makalah ilmiah relevan dari arxiv.org.
    2. summarize_paper: Alat ini menggunakan qna_search milik Tavily, yang dioptimalkan untuk memberikan jawaban langsung dan ringkas, sangat cocok untuk membuat ringkasan.
  4. Prompt: Dekorator @mcp.prompt membuat templat yang dapat digunakan kembali. Ini bukan sekadar prompt sederhana; melainkan rencana strategis yang menginstruksikan LLM cara menggunakan tools server secara berurutan untuk menjalankan tugas kompleks.
  5. HTTP Transport: mcp.run(transport="http") adalah baris yang krusial. Alih-alih menggunakan “stdio” untuk proses lokal, ini menjalankan server web. Ini memungkinkan klien mana pun di jaringan (atau di mesin yang sama) terhubung ke server kita melalui URL, menjadikannya alat yang benar-benar jarak jauh dan dapat dibagikan.

server.py:

import osfrom typing import Dict, Listfrom fastmcp import FastMCPfrom tavily import TavilyClient# --- Configuration ---TAVILY_API_KEY = os.environ.get("TAVILY_API_KEY")if not TAVILY_API_KEY:    raise ValueError("Please set the TAVILY_API_KEY environment variable.")tavily = TavilyClient(api_key=TAVILY_API_KEY)mcp = FastMCP(name="ArxivExplorer")print("✅ ArxivExplorer server initialized.")# --- Dynamic Resource: Suggested AI research topics ---@mcp.resource("resource://ai/arxiv_topics")def arxiv_topics() -> List[str]:    return [        "Transformer interpretability",        "Efficient large-scale model training",        "Federated learning privacy",        "Neural network pruning",    ]print("✅ Resource 'resource://ai/arxiv_topics' registered.")# --- Tool: Search ArXiv for recent papers ---@mcp.tool(annotations={"title": "Search Arxiv"})def search_arxiv(query: str, max_results: int = 5) -> List[Dict]:    """    Queries ArXiv via Tavily, returning title + link for each paper,    and *only* ArXiv results.    """    resp = tavily.search(        query=f"site:arxiv.org {query}",        max_results=max_results    )    return [        {"title": r["title"].strip(), "url": r["url"]} for r in resp.get("results", [])    ]# --- Tool: Summarize an ArXiv paper ---@mcp.tool(annotations={"title": "Summarize Paper"})def summarize_paper(paper_url: str) -> str:    """    Returns a one-paragraph summary of the paper at the given URL.    """    prompt = f"Summarize the key contributions of this ArXiv paper: {paper_url}"    return tavily.qna_search(query=prompt)print("✅ Tools 'Search Arxiv' and 'Summarize Paper' registered.")# --- Prompt Template: Explore a topic thoroughly ---@mcp.promptdef explore_topic_prompt(topic: str) -> str:    return (        f"I want to explore recent work on '{topic}'.\n"        f"1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n"        f"2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n"        f"3. Combine all summaries into an overview report."    )print("✅ Prompt 'explore_topic_prompt' registered.")if __name__ == "__main__":    print("\n🚀 Starting ArxivExplorer Server...")    mcp.run(transport="http")

3. Membangun klien interaktif

Kita perlu menguji fitur dan endpoint server MCP sebelum mengintegrasikannya ke aplikasi AI. Untuk ini, FastMCP menyediakan API sederhana untuk menghubungkan server MCP dan menguji semua fungsinya.

File klien terdiri dari:

  1. HTTP Transport: StreamableHttpTransport dirancang khusus untuk terhubung ke server FastMCP yang berjalan dalam mode HTTP.
  2. Helper unwrap_tool_result: Ini adalah utilitas penting. Klien FastMCP tidak mengembalikan data mentah; ia mengembalikan objek terstruktur. Fungsi ini dengan aman memeriksa objek respons dan mengekstrak data Python yang Anda butuhkan.
  3. Alur kerja: Fungsi utama menjalankan rangkaian pengujian lengkap.
    1. Melakukan ping ke server untuk memastikan server online.
    2. Mendaftar semua tools, resources, dan prompts yang tersedia.
    3. Membaca resource arxiv_topics dan mengurai hasilnya dengan benar.
    4. Memanggil alat search_arxiv dan menggunakan fungsi helper untuk membuka daftar makalah.
    5. Merangkaikan tools dengan mengambil URL dari hasil pencarian pertama dan memberikannya ke alat summarize_paper.
    6. Terakhir, mendapatkan explore_topic_prompt, menampilkan instruksi akhir siap pakai yang akan dikirim ke LLM.

client.py:

import astimport asyncioimport pprintfrom fastmcp import Clientfrom fastmcp.client.transports import StreamableHttpTransport# --- Configuration ---SERVER_URL = "http://localhost:8000/mcp"  # adjust if hosted elsewherepp = pprint.PrettyPrinter(indent=2, width=100)def unwrap_tool_result(resp):    """    Safely unwraps the content from a FastMCP tool call result object.    """    if hasattr(resp, "content") and resp.content:        # The content is a list containing a single content object        content_object = resp.content[0]        # It could be JSON or plain text        if hasattr(content_object, "json"):            return content_object.json        if hasattr(content_object, "text"):            try:                # Use ast.literal_eval for safely evaluating a string containing a Python literal                return ast.literal_eval(content_object.text)            except (ValueError, SyntaxError):                # If it's not a literal, return the raw text                return content_object.text    return respasync def main():    transport = StreamableHttpTransport(url=SERVER_URL)    client = Client(transport)    print("\n🚀 Connecting to FastMCP server at:", SERVER_URL)    async with client:        # 1. Ping to test connectivity        print("\n🔗 Testing server connectivity...")        await client.ping()        print("✅ Server is reachable!\n")        # 2. Discover server capabilities        print("🛠️  Available tools:")        pp.pprint(await client.list_tools())        print("\n📚 Available resources:")        pp.pprint(await client.list_resources())        print("\n💬 Available prompts:")        pp.pprint(await client.list_prompts())        # 3. Fetch the topics resource        print("\n\n📖 Fetching resource: resource://ai/arxiv_topics")        res = await client.read_resource("resource://ai/arxiv_topics")        topics = ast.literal_eval(res[0].text)        print("Today's AI topics:")        for i, t in enumerate(topics, 1):            print(f"  {i}. {t}")        # 4. Test the search tool        print("\n\n🔍 Testing tool: search_arxiv")        raw_search = await client.call_tool(            "search_arxiv",            {"query": "Transformer interpretability", "max_results": 3},        )        search_results = unwrap_tool_result(raw_search)        for i, paper in enumerate(search_results, 1):            print(f"  {i}. {paper['title']}\n     {paper['url']}")                # 5. Test the summarize tool on the first result        if search_results:            first_url = search_results[0]["url"]            print("\n\n📝 Testing tool: summarize_paper")            raw_summary = await client.call_tool(                "summarize_paper", {"paper_url": first_url}            )            summary = unwrap_tool_result(raw_summary)            print("\nSummary of first paper:\n", summary)        # 6. Test the prompt generator        print("\n\n🚀 Testing prompt: explore_topic_prompt")        prompt_resp = await client.get_prompt(            "explore_topic_prompt", {"topic": "Transformer interpretability"}        )        print("\nGenerated prompt for an LLM:")        for msg in prompt_resp.messages:            print(f"{msg.role.upper()}: {msg.content.text}\n")if __name__ == "__main__":    asyncio.run(main())

Semua file dan konfigurasi tersedia di repositori GitHub kingabzpro/FastMCP-Project. Anda dapat menggunakannya jika mengalami kendala. Saya juga menyertakan panduan penyiapan untuk menjalankannya secara lokal.

4. Menjalankan aplikasi

Sekarang kita akan menjalankan server dan klien MCP. 

Pertama, setel kunci API Tavily sebagai variabel lingkungan di sistem lokal Anda:  

export TAVILY_API_KEY='your_tavily_api_key'

Selanjutnya, jalankan server:  

python server.py

Dalam hitungan detik, Anda akan melihat server FastMCP berjalan di http://localhost:8000/mcp.

FastMCP server is running at http://localhost:8000/mcp

Buka terminal baru dan jalankan skrip klien untuk menguji apakah semuanya berjalan dengan baik:  

python client.py

Seperti yang kita lihat, semua fungsi, resource, tools, dan prompt berfungsi dengan sempurna. Server MCP kita berkinerja baik, bahkan dengan beberapa permintaan API Tavily.

🚀  Connecting to FastMCP server at: http://localhost:8000/mcp🔗 Testing server connectivity...✅ Server is reachable!🛠️  Available tools:[ Tool(name='search_arxiv', title='Search Arxiv', description='Queries ArXiv via Tavily, returning title + link for each paper,\nand *only* ArXiv results.', inputSchema={'properties': {'query': {'title': 'Query', 'type': 'string'}, 'max_results': {'default': 5, 'title': 'Max Results', 'type': 'integer'}}, 'required': ['query'], 'type': 'object'}, outputSchema={'properties': {'result': {'items': {'additionalProperties': True, 'type': 'object'}, 'title': 'Result', 'type': 'array'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=ToolAnnotations(title='Search Arxiv', readOnlyHint=None, destructiveHint=None, idempotentHint=None, openWorldHint=None), meta=None),  Tool(name='summarize_paper', title='Summarize Paper', description='Returns a one-paragraph summary of the paper at the given URL.', inputSchema={'properties': {'paper_url': {'title': 'Paper Url', 'type': 'string'}}, 'required': ['paper_url'], 'type': 'object'}, outputSchema={'properties': {'result': {'title': 'Result', 'type': 'string'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=ToolAnnotations(title='Summarize Paper', readOnlyHint=None, destructiveHint=None, idempotentHint=None, openWorldHint=None), meta=None)]📚 Available resources:[ Resource(name='arxiv_topics', title=None, uri=AnyUrl('resource://ai/arxiv_topics'), description=None, mimeType='text/plain', size=None, annotations=None, meta=None)]💬 Available prompts:[ Prompt(name='explore_topic_prompt', title=None, description=None, arguments=[PromptArgument(name='topic', description=None, required=True)], meta=None)]📖 Fetching resource: resource://ai/arxiv_topicsToday's AI topics:  1. Transformer interpretability  2. Efficient large-scale model training  3. Federated learning privacy  4. Neural network pruning🔍 Testing tool: search_arxiv  1. Transformer Interpretability Beyond Attention Visualization     https://arxiv.org/abs/2012.09838  2. A Practical Review of Mechanistic Interpretability for ...     https://arxiv.org/abs/2407.02646  3. Mechanistic Interpretability of Fine-Tuned Vision ...     https://arxiv.org/abs/2503.18762📝 Testing tool: summarize_paperSummary of first paper: The paper proposes a novel method for interpreting Transformer networks beyond attention visualization, introducing a new way to compute relevancy. It aims to enhance interpretability in vision tasks. The method is shown to provide more accurate insights into model decisions.🚀 Testing prompt: explore_topic_promptGenerated prompt:USER: type='text' text="I want to explore recent work on 'Transformer interpretability'.\n1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n3. Combine all summaries into an overview report." annotations=None meta=None

Mengintegrasikan server MCP di Cursor AI

Biarkan server MCP tetap berjalan, karena kita akan mengintegrasikannya ke editor kode Cursor AI. 

  1. Buka “Settings”.
  2. Klik tab “Tools & Integrations”.
  3. Klik tombol “New MCP Server”.
  4. Tambahkan konfigurasi berikut:
{  "mcpServers": {    "ArxivExplorer": {      "url": "http://127.0.0.1:8000/mcp/"    }  }}

Setelah Anda menyimpan file mcp.json dengan konfigurasi di atas, Anda akan melihat server MCP baru tercantum di bagian “Tools & Integrations”, yang akan menampilkan dua alat seperti terlihat di bawah.

ArxivExplorer configured in Cursor AI

Menguji Server MCP di Cursor AI

Sekarang masuk ke bagian yang menyenangkan. Mari kita lihat bagaimana kinerja server MCP kita dengan editor kode Cursor AI. Kita akan mempelajari cara menggunakan prompt untuk memanggil tools, mengakses resources, dan mengeksekusi custom prompt, semuanya di dalam editor kode.

1. Menguji resources

Mulailah dengan memeriksa apakah server MCP Anda dapat menyediakan data yang berguna melalui resources-nya.

Prompt: “apa saja topik arxiv populer”

Testing the Resources

Jika semuanya disiapkan dengan benar, model AI akan memahami permintaan Anda dan secara otomatis mengambil daftar topik dari endpoint resource server MCP Anda.

2. Menguji tools satu per satu

Selanjutnya, mari coba tools yang Anda ekspos melalui MCP. Kita akan terlebih dahulu menguji alat search_arxiv dengan meminta model AI untuk mencantumkan sepuluh makalah riset teratas tentang large language models.  

Prompt: “Tolong cari 10 makalah riset teratas tentang large language models.”

AI akan memanggil alat search_arxiv, dan Anda akan melihat daftar cepat dan akurat dari makalah yang relevan, diambil langsung dari arXiv.

Selanjutnya, kita akan menguji alat peringkas yang menerima URL makalah riset dan mengembalikan ringkasan laporannya.  

Prompt: “Tolong ringkas makalah berikut untuk saya: https://arxiv.org/abs/2402.06196”

Alat peringkas akan mengambil makalah tersebut dan mengembalikan ringkasan yang ringkas.

3. Menguji prompt

Sekarang kita akan memanggil prompt kustom dari MCP yang akan membantu kita membuat laporan.

Prompt: “Buat laporan tentang komputasi Kuantum menggunakan karya terbaru.”

Testing the Prompt

Jika Anda meninjau kode server, Anda akan melihat bahwa model AI memahami tugasnya dan menggunakan fungsi explore_topic_prompt.

@mcp.promptdef explore_topic_prompt(topic: str) -> str:    return (        f"I want to explore recent work on '{topic}'.\n"        f"1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n"        f"2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n"        f"3. Combine all summaries into an overview report."    )

Pertama, ia akan memanggil alat 'Search Arxiv' untuk menemukan tautan ke makalah.

Tool result output

Kemudian, ia akan memberikan tautan tersebut ke alat 'Summarize Paper' satu per satu untuk menghasilkan ringkasan. Terakhir, saya akan membuat laporannya.

Tool result output

Kesimpulan

FastMCP 2.0 menawarkan lebih dari sekadar cara sederhana untuk membuat server MCP. Ia menyediakan kerangka kerja tangguh untuk membangun integrasi AI yang aman, modular, dan skalabel. Dengan fitur seperti autentikasi, proxy canggih (memungkinkan satu server FastMCP bertindak sebagai frontend untuk server lainnya), dan kemampuan menggabungkan beberapa server FastMCP menjadi satu aplikasi menggunakan mounting dan importing, Anda dapat merancang sistem yang kompleks dan mudah dipelihara.

Dukungan middleware memungkinkan Anda menambahkan fungsionalitas lintas-lapisan, seperti logging atau modifikasi permintaan, ke semua permintaan dan respons MCP. Anda juga dapat mengirim pesan log dan pembaruan progres kembali ke klien melalui konteks MCP, sehingga mudah memantau dan mengelola operasi jangka panjang.

Dalam tutorial ini, kita telah mempelajari cara membangun server MCP yang sepenuhnya fungsional dan menguji fiturnya. Tools ini dan protokol MCP menjadi komponen penting dari aplikasi AI modern, memungkinkan LLM melakukan tugas yang lebih canggih dan mengotomatiskan alur kerja dengan lebih efektif. 

Untuk terus belajar tentang Server MCP, pastikan untuk melihat sumber daya kami yang lain: 


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

Sebagai data scientist tersertifikasi, saya bersemangat memanfaatkan teknologi mutakhir untuk menciptakan aplikasi machine learning yang inovatif. Dengan latar belakang kuat di pengenalan ucapan, analisis dan pelaporan data, MLOps, conversational AI, dan NLP, saya mengasah keterampilan dalam mengembangkan sistem cerdas yang berdampak nyata. Selain keahlian teknis, saya juga komunikator andal yang mampu menyederhanakan konsep kompleks menjadi bahasa yang jelas dan ringkas. Karena itu, saya menjadi blogger yang dicari di bidang data science, membagikan wawasan dan pengalaman kepada komunitas profesional data yang terus berkembang. Saat ini, saya berfokus pada pembuatan dan penyuntingan konten, bekerja dengan large language model untuk mengembangkan konten yang kuat dan menarik agar membantu bisnis dan individu memaksimalkan data mereka.

Topik
Kecerdasan Buatan
Large Language Models

Kursus Teratas DataCamp

Kursus

Sistem Multi-Agen dengan LangGraph

2 jam 45 menit
8.8K
Bangun sistem multi-agen yang kuat dengan menerapkan pola desain agen yang sedang berkembang dalam kerangka kerja LangGraph.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

Lihat SelengkapnyaLihat Selengkapnya