Model Context Protocol (MCP) Explained for Beginners

MCP is an open standard for connecting AI applications to tools and data. Instead of writing a custom integration for every assistant, you write one server and any compatible application can use it. This guide explains the parts and runs a real server and client, so you can see exactly what passes between them.

GloryTecks Team

Training & Placement Faculty

9 May 2026 9 min read

Last updated: 3 October 2026

Share:

An AI assistant becomes far more useful when it can reach your files, your database or your ticketing system. The difficulty has been that every assistant connected to every system in its own way. Ten applications and ten data sources meant up to a hundred separate integrations.

The Model Context Protocol, MCP, is an attempt to end that. It is an open standard for connecting AI applications to external systems. Its documentation compares it to a USB-C port for AI: build a server for your system once, and any application that speaks MCP can use it (MCP: introduction).

The three participants

ParticipantWhat it isExample
HostThe AI application the user works inA chat assistant or a code editor with an assistant
ClientA connection the host keeps open to one serverOne for each server the host uses
ServerA program that offers tools and dataA server for your files, your database or a web service

A host creates one client for each server it connects to (MCP: architecture). The language model sits inside the host. Servers never talk to the model directly. They answer the client's requests, and the host decides what the model sees.

What a server can offer

PrimitiveWhat it isTypical use
ToolA function the model can ask to have runSearch, create a ticket, run a query
ResourceData the application can readA file's contents, a schema, a record
PromptA reusable templateA standard way to ask for a summary

Every primitive can be listed, so a host can discover what a server offers at run time instead of having it hard-coded. Messages use JSON-RPC 2.0, a simple format for requests and responses.

Two transports carry them. Stdio runs the server as a local process and talks through its standard input and output. Streamable HTTP reaches a remote server over the network, with OAuth recommended for authorisation.

A server and a client, running

The script is a complete MCP example in one file. Run with the argument serve, it is a server that exposes a small library of documents: a tool that searches section titles, a tool that reads a section, and a resource that lists what the library holds. Run without arguments, it is a client: it launches itself as a server, connects over stdio, and does what a host would do on a model's behalf. It uses the official Python SDK (MCP: Python SDK).

No language model appears anywhere. That is deliberate: MCP is the plumbing, and this shows the plumbing.

python
import json
import sys

import anyio
from mcp import Client, StdioServerParameters
from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError

# ---------- the server: exposes a small library of documents ----------
SECTIONS = json.load(open("pep_sections.json", encoding="utf-8"))
server = MCPServer("pep-library")


@server.tool()
def search_sections(query: str, limit: int = 3) -> list[str]:
    """Find sections of Python Enhancement Proposals whose title contains the query."""
    hits = [s for s in SECTIONS if query.lower() in s["title"].lower()]
    return [f"{s['id']}: {s['title']}" for s in hits[:limit]]


@server.tool()
def read_section(section_id: str) -> str:
    """Return the first 40 words of one section, given its id."""
    section = next((s for s in SECTIONS if s["id"] == section_id), None)
    if section is None:
        # an anticipated failure: the client receives this message, and the model can act on it
        raise ToolError(f"No section {section_id}. Use search_sections to find valid ids.")
    return " ".join(section["text"].split()[:40])


@server.resource("pep://index")
def index() -> str:
    """Which PEPs this server holds and how many sections of each."""
    counts = {}
    for s in SECTIONS:
        counts[s["pep"]] = counts.get(s["pep"], 0) + 1
    return ", ".join(f"PEP {pep}: {n} sections" for pep, n in counts.items())


# ---------- the client: what an AI application does on the model's behalf ----------
async def client():
    launch = StdioServerParameters(command=sys.executable, args=[__file__, "serve"])
    async with Client(launch) as session:
        print("connected to server:", session.server_info.name, "| protocol version:", session.protocol_version)

        tools = await session.list_tools()
        for tool in tools.tools:
            print(f"tool {tool.name}({', '.join(tool.input_schema['properties'])}): {tool.description}")
        resources = await session.list_resources()
        print("resource:", ", ".join(str(r.uri) for r in resources.resources))

        found = await session.call_tool("search_sections", {"query": "line length"})
        print("search_sections ->", [c.text for c in found.content])
        text = await session.call_tool("read_section", {"section_id": "pep8-5"})
        print("read_section ->", text.content[0].text)
        listing = await session.read_resource("pep://index")
        print("pep://index ->", listing.contents[0].text)

        missing = await session.call_tool("read_section", {"section_id": "pep8-999"})
        print("a bad argument -> is_error:", missing.is_error, "|", missing.content[0].text)


if __name__ == "__main__":
    if sys.argv[1:] == ["serve"]:
        server.run()                      # speak MCP over standard input and output
    else:
        anyio.run(client)
text
connected to server: pep-library | protocol version: 2026-07-28
tool search_sections(query, limit): Find sections of Python Enhancement Proposals whose title contains the query.
tool read_section(section_id): Return the first 40 words of one section, given its id.
resource: pep://index
search_sections -> ['pep8-5: Maximum Line Length']
read_section -> Limit all lines to a maximum of 79 characters. For flowing long blocks of text with fewer structural restrictions (docstrings or comments), the line length should be limited to 72 characters. Limiting the required editor window width makes it possible
pep://index -> PEP 8: 37 sections, PEP 20: 2 sections, PEP 257: 5 sections, PEP 484: 48 sections, PEP 498: 22 sections, PEP 572: 34 sections
a bad argument -> is_error: True | Error executing tool read_section: No section pep8-999. Use search_sections to find valid ids.
  • The server described itself. Its two tools arrived with their names, arguments and descriptions, taken from the Python function signatures and docstrings.
  • The descriptions are written for the model. In a real host, the model reads "Find sections of Python Enhancement Proposals whose title contains the query" and decides whether to call it. A vague description means a tool that is never used, or used wrongly.
  • Calls return structured results, which the host puts in front of the model.
  • The resource is read, not called. It is context, not an action.
  • A failure came back as a flagged result, not a crash, and with a message the model can act on: the section does not exist, and here is the tool that finds valid ids.

To connect a server like this to a real assistant, you register the command that launches it in the host's settings. From then on its tools appear alongside the assistant's own.

Three practical details

Never print in a stdio server. Standard output is the message channel, and MCP's own guide warns that writing to it corrupts the messages and breaks the server. Log to standard error instead (MCP: build a server).

Descriptions are part of the interface. Name tools for what they do, describe arguments precisely, and keep each tool to one job.

Return useful errors. "No section pep8-999" lets a model recover. A stack trace does not. In the Python SDK, raising ToolError puts your message in the result, where the model reads it. Any other exception reaches the model only as a failed call, with the traceback left in the server's log (MCP Python SDK: handling errors).

Versions: the protocol is still moving

MCP is versioned by date, and it changes. The current specification is the revision of 28 July 2026 (MCP: specification). That revision made the protocol stateless: every request carries its own protocol version and capabilities, and every server must answer a discovery request that says what it supports. It also deprecated two features that let servers ask the client for model completions and send log messages.

The example uses version 2 of the official Python SDK, which speaks this revision: the output reports protocol version 2026-07-28, reached with a single discovery request and no handshake. Version 2 also renamed parts of the SDK. The server class FastMCP became MCPServer, and one Client object replaced the separate session and initialize call of version 1. A version 2 server still answers older clients that open with the handshake (MCP Python SDK: what's new in v2). Many tutorials online still use the version 1 names, so check which version an example targets, and which revision your host supports, before you design around a feature.

Security

An MCP server can do whatever its code can do, and the model decides when to call it. That combination needs care.

  • Keep a person in the loop for actions. The specification says there should always be a human able to deny a tool call, with confirmation for operations (MCP: tools).
  • Treat server-supplied descriptions as untrusted unless the server is trusted. The specification requires clients to do so for tool annotations.
  • Install servers like software. A server from an unknown source runs with your permissions.
  • Watch for prompt injection. Text that comes back from a tool, such as a web page or an email, can contain instructions aimed at the model. See guardrails for LLMs.
  • Give servers the least access they need. A read-only database user for a reporting server, not an administrator.

MCP and tool calling

MCP does not replace the tool calling built into model APIs. It sits beneath it. A model still decides to call a tool and still receives the result as text. MCP standardises where the tools come from and how they are described and invoked, so that the same server works with many hosts. See function calling and tool use for the model side, and AI agents for what is built from many tool calls in a loop.

Anthropic's glossary sums it up as a unified way to connect AI models to data sources and tools (Anthropic: glossary).

Common mistakes

  • Writing to standard output in a stdio server.
  • One giant tool that does everything, which the model cannot use well.
  • Vague tool descriptions.
  • Running untrusted servers with full permissions.
  • No confirmation step for actions that change things.
  • Assuming every host supports every protocol revision.

What is MCP in simple terms?

An open standard for connecting AI applications to tools and data. A system is wrapped once in an MCP server, and any AI application that supports MCP can discover and use its tools and data.

What is the difference between an MCP server and an MCP client?

The server is the program that offers tools, resources and prompts. The client is the connection an AI application opens to one server. An application that uses three servers holds three clients.

Do I need a language model to build an MCP server?

No. A server is ordinary code that answers requests. The model lives in the host application, which decides when to call the server's tools and shows the model the results.

Is MCP safe to use?

It is as safe as the servers you connect and the permissions you give them. The specification says a person should be able to deny tool calls, and tool descriptions from untrusted servers should not be trusted. Treat servers like any software you install.

Building AI assistants that connect to tools and data is part of the Building Gen AI Applications module of the Generative AI course.

Sources

GloryTecks Team

Training & Placement Faculty

The GloryTecks faculty team mentors learners across Data Science, AI and Data Engineering, with a focus on real-time projects and placement readiness in Hyderabad.

Want to master Generative AI?

Join GloryTecks’ expert-led Agentic AI training in Hyderabad with real-time projects and 100% placement support.

Explore course