What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
The fastest way to write a useful Model Context Protocol (MCP) server is to start with one deterministic tool, an explicit input schema, and the simplest transport that matches your client. This guide builds a complete Python server first, tests it without a subprocess or network port, then shows the equivalent TypeScript setup, Inspector workflow, transport choices, and production hardening steps.
What an MCP server exposes
MCP standardizes how applications provide context to large language model applications. The server surface has three primitives:
- Tools are callable functions, such as adding numbers, querying an API, or creating a ticket.
- Resources expose readable context, such as a document, configuration value, or generated report.
- Prompts are reusable message templates that help a client assemble a task consistently.
The official Python SDK supports stdio, Streamable HTTP, and SSE transports. The TypeScript SDK supports stdio and Streamable HTTP, while HTTP+SSE remains available for backward compatibility. Begin with stdio for a local client that launches your process; move to Streamable HTTP when a remote client must reach a running service.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11The examples below use a small add tool because deterministic behavior makes schema and testing mistakes easy to see. The Python SDK requires Python 3.10 or newer.
#1 Best Overall
Python: build a complete minimal server
Install the SDK
Create a project with Python 3.10+ and install the official package, including its command-line tools:
uv add "mcp[cli]"
If you use pip instead:
pip install "mcp[cli]"
Create server.py
This is a complete file. The decorator registers a tool and its type annotations become the input contract.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("calculator")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two integers and return the sum."""
return a + b
if __name__ == "__main__":
mcp.run()
The server has a descriptive name, a single deterministic operation, and no hidden global state. A client can discover the tool, see its description and parameters, and call it through MCP rather than depending on an ad-hoc function name.
Add a resource and prompt when your server needs them
Tools are not the only MCP primitive. This expanded example keeps the tool and adds a static resource plus a prompt template:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("calculator")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two integers and return the sum."""
return a + b
@mcp.resource("config://calculator")
def calculator_config() -> str:
"""Describe the calculator service."""
return "This calculator currently exposes integer addition."
@mcp.prompt()
def explain_sum(a: int, b: int) -> str:
"""Create a concise explanation request for a sum."""
return f"Explain why {a} + {b} equals {a + b}."
if __name__ == "__main__":
mcp.run()
Keep resources read-oriented and prompts focused on message construction. Put side effects, authorization checks, and external calls behind tools.
Rank #2
Run and inspect the Python server
Use the documented development command
- Save the file as
server.py. - From the project directory, run
uv run mcp dev server.py. - Open the server in MCP Inspector when prompted by the development workflow.
- Use Inspector to list tools, inspect the generated schema, call
add, and read the resource or prompt if you included them.
The Python getting-started guide describes its code blocks as complete, working files and uses MCP Inspector for interactive inspection. Inspector is especially useful for catching a misspelled tool name, an unexpected parameter type, or output that does not match the declared contract before connecting an LLM application.
Run directly over stdio
For a client that starts your process, execute:
python server.py
Do not print diagnostic text to standard output: stdio clients use that stream for the MCP protocol. Send logs to standard error instead.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Test behavior without a subprocess or port
The Python SDK supports an in-memory client connection. This tests the server object directly: no subprocess, no port, and no transport.
import anyio
from mcp import ClientSession
from mcp.shared.memory import create_connected_server_and_client_session
from server import mcp
async def main() -> None:
async with create_connected_server_and_client_session(mcp._mcp_server) as session:
result = await session.call_tool("add", {"a": 1, "b": 2})
assert result.structured_content == {"result": 3}
if __name__ == "__main__":
anyio.run(main)
Run the test with your project environment, for example uv run python test_server.py. The assertion checks the structured result rather than scraping display text. Add tests for invalid types, boundary values, and failures from every external dependency before you add deployment complexity.
TypeScript alternative
Install and create the project
The official TypeScript SDK uses Zod for schemas:
npm install @modelcontextprotocol/sdk zod
The SDK repository includes runnable examples under src/examples. A minimal stdio server can be written as follows:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "calculator", version: "1.0.0" });
server.registerTool(
"add",
{
title: "Add integers",
description: "Add two integers and return the sum.",
inputSchema: { a: z.number().int(), b: z.number().int() },
outputSchema: { result: z.number().int() }
},
async ({ a, b }) => {
const result = a + b;
return {
content: [{ type: "text", text: String(result) }],
structuredContent: { result }
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
This pattern gives the tool a stable name, human-readable title and description, explicit Zod input and output schemas, text content for clients that display prose, and structured content for clients that consume data programmatically. The connection sequence is the official minimal pattern: construct McpServer, create StdioServerTransport, then await server.connect(transport).
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →TypeScript run and test approach
Compile or run the file with the package manager and runtime you selected for your project. Then launch it from an MCP client or Inspector using its stdio command. For automated tests, use the SDK’s client examples as a model: connect a client to the server, list tools, call add, and assert both the text and structured result. Keep the test independent of an LLM so a model’s wording cannot hide a protocol or schema regression.
Choosing an MCP transport
| Transport | Best fit | What to plan for |
|---|---|---|
| stdio | Local integrations where the client spawns the server | Process lifecycle, stderr logging, local credentials, and one client-to-process connection |
| Streamable HTTP | Remote servers reached over HTTP | HTTP deployment, request authentication, concurrency, sessions or state, and operational monitoring |
| HTTP+SSE | Clients that still require the older transport | Backward compatibility; prefer the current remote-oriented option for new deployments when your clients support it |
Use stdio while designing and testing a local server. Streamable HTTP is the documented choice for a remote server. A transport change does not replace input validation or authorization: those belong in your application code and deployment boundary.
Make the sample reliable before adding features
Validate every boundary
- Use integer, string, enum, range, and format constraints in schemas instead of accepting an untyped dictionary.
- Reject missing or contradictory fields with an actionable error.
- Return a predictable structured shape; do not make clients parse numbers out of prose.
Separate protocol errors from application failures
Catch expected failures from files, databases, and HTTP calls, then return a safe explanation that tells the caller what can be corrected. Log stack traces to a protected sink, not to stdio. Do not expose access tokens, filesystem paths, or upstream response bodies unnecessarily.
Control side effects
Read-only tools are easier to test and authorize. For tools that send mail, modify records, execute commands, or spend money, require narrowly scoped credentials and an explicit confirmation policy in the calling application. The SDK gives you the protocol surface; your service still owns identity, authorization, rate limits, and secret management.
Keep output and versioning stable
Set a server name and version, document each tool, and treat schema changes as API changes. Add a new field compatibly where possible. If a client depends on structuredContent, preserve its shape or publish a deliberate migration.
Troubleshooting common failures
Inspector cannot start the server
Check the working directory, Python version, virtual environment, and file name. Run the exact command manually. If dependencies are missing, reinstall mcp[cli] in the environment used by Inspector.
The client reports invalid JSON or a protocol error
Your server may be writing logs to stdout. Move all print calls and framework diagnostics to stderr. Also verify that the process is running the MCP transport rather than exiting after importing the module.
A tool is not listed
Confirm that the decorator or registerTool call executes during startup, the tool name is spelled exactly, and the process stays alive. In TypeScript, check that the module containing registration is imported before server.connect.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsThe call fails schema validation
Inspect the schema in Inspector and compare it with the arguments sent by the client. Python annotations and TypeScript Zod definitions are contracts, not comments: send integers where an integer is declared and include every required property.
Best Value
Structured output is missing
In TypeScript, return both content and structuredContent when your client needs machine-readable data, and ensure the object matches outputSchema. In Python, inspect the returned result object in the in-memory test rather than assuming the displayed text is the structured value.
Or skip the browser setup
If your MCP tool needs a clean website image, ScreenshotNeo provides a website screenshot API and MCP server for developers. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—work with Claude, Cursor, and other MCP clients.
One request returns an image or PDF:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for all options, including full-page and element captures, device presets, custom CSS and JavaScript, waits, request blocking, cookies and headers, geolocation, PDF settings, caching, signed links, asynchronous jobs, bulk capture, and usage reporting. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Free tools Windows power users keep installed
One-click scans. No signup required.
FAQ
Should I start with Python or TypeScript?
Choose Python if your existing service and tests are Python-based; choose TypeScript if you want Zod schemas and a JavaScript/Node deployment. Both official SDKs expose the same MCP concepts.
Do I need HTTP for a local MCP server?
No. stdio is designed for local clients that spawn the server. Use Streamable HTTP when a remote client must reach a running service.
Can I test an MCP server without starting a port?
Yes. The Python SDK’s in-memory client connects directly to the server object, so a test needs no subprocess, port, or transport.
Are resources and prompts required?
No. A server can begin with one tool. Add resources for readable context and prompts for reusable message templates when your client workflow needs them.
Frequently Asked Questions
What is the smallest useful MCP server?
A process that registers one documented tool with an explicit input schema and serves it over stdio is enough for a useful local sample.
When should I move from stdio to Streamable HTTP?
Move when the server must be reached remotely or shared by clients that cannot spawn a local process; keep stdio for local development and inspection.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

