PC 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 & 11Outdated 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 matchInstall the official mcp package, then choose the connection method that matches where the server runs: pass a server URL to Client for Streamable HTTP, use stdio parameters for a local server process, or pass a server object for in-process use. In every case, enter async with to open the connection before calling a tool. The current MCP Python SDK requires Python 3.10 or later.
Install the MCP Python SDK
The official package is mcp. The MCP project documents installation with either uv or pip; the [cli] extra is included in both commands:
uv add "mcp[cli]"
# or
pip install "mcp[cli]"
Use Python 3.10 or later. The Model Context Protocol (MCP) standardizes how applications provide context to language-model applications, separately from the model interaction itself. See the official MCP Python SDK documentation for the package and its client guides.
Choose the connection method
| Where the server runs | Connection method | When it fits |
|---|---|---|
| As a separate process on the same machine | stdio | You want the SDK to start the server subprocess and exchange protocol messages over stdin and stdout. |
| As a remote service | Streamable HTTP | You have a current Streamable HTTP endpoint, commonly ending in /mcp. |
| As a remote service with an older endpoint | Server-Sent Events (SSE) | You need to connect to an existing SSE server, often exposed at an /sse endpoint. |
| Inside the same Python process | Pass the server object | You are embedding a server or writing tests and want client calls to pass through the protocol layer without launching a separate process or making a network connection. |
For new HTTP deployments, prefer Streamable HTTP. The MCP SDK describes SSE as the HTTP transport that Streamable HTTP superseded; SSE remains useful for reaching servers that have not moved to the newer transport. A URL passed to Client selects Streamable HTTP. Use the endpoint the server actually provides rather than assuming every MCP service uses the same path.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
Connect to a remote Streamable HTTP server
For an HTTP MCP endpoint, pass its URL to Client and open the client with an asynchronous context manager. This runnable example connects to a server at localhost:8000, calls an add tool with two arguments, and prints structured output:
import asyncio
from mcp import Client
async def main() -> None:
async with Client("http://localhost:8000/mcp") as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
print(result.structured_content)
asyncio.run(main())
Replace the example URL with the MCP server’s actual Streamable HTTP endpoint, and replace add and its arguments with a tool name and input accepted by that server. The endpoint shown is HTTP on localhost; use the server’s configured URL and scheme for a deployed service.
Why async with matters
Creating Client(...) selects a transport; it does not connect. Entering async with opens the connection and manages its lifecycle. Keep tool calls inside that context so the client remains open while requests are made and is closed when the block exits. Calling call_tool on a client that has only been constructed is not a substitute for opening it.
Rank #2
Headers, authentication, proxies, and timeouts
For Streamable HTTP, configure headers, authentication, proxies, and timeouts on the HTTP client supplied to the transport. The SDK guide describes default timeouts of 30 seconds for connect, write, and pool operations, and 300 seconds for reads because a server may keep a response stream open. Adjust these settings to fit the server and workload rather than treating the defaults as a guarantee that every operation completes within a fixed total time.
Recommended Free Tools
If a redirect takes the request to a different origin, configure the final endpoint explicitly where necessary. Do not assume credentials or custom headers will be appropriate to forward across an origin change. Consult the SDK transport guide for the installed SDK’s current HTTP-client configuration interface.
Connect to a local server over stdio
Use stdio when the Python client should launch an MCP server process on the same machine. The SDK starts that subprocess and exchanges protocol messages through its stdin and stdout. Provide the server command and arguments through StdioServerParameters, then wrap those parameters with stdio_client(...) and pass that transport to Client.
import asyncio
from mcp import Client
from mcp.client.stdio import StdioServerParameters, stdio_client
async def main() -> None:
server = StdioServerParameters(
command="python",
args=["server.py"],
)
async with Client(stdio_client(server)) as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
print(result.structured_content)
asyncio.run(main())
Run this from an environment where python resolves to the intended interpreter and server.py is available from the process’s working directory. Set the command and arguments to match how that server is launched. If the server writes diagnostic output to stderr, use the stdio transport configuration to redirect stderr; keep stdout reserved for protocol communication, since unrelated output there can interfere with the exchange.
Connect to an existing SSE server
Use sse_client(url) when the server you need to reach already supports Server-Sent Events. This is a compatibility path, not the preferred choice for a new HTTP deployment. Check the server’s documented endpoint: an SSE endpoint such as /sse is not interchangeable with a Streamable HTTP endpoint such as /mcp.
import asyncio
from mcp import Client
from mcp.client.sse import sse_client
async def main() -> None:
async with Client(sse_client("http://localhost:8000/sse")) as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
print(result.structured_content)
asyncio.run(main())
Use the import and client-transport interface documented for the version of mcp you installed. If the server offers Streamable HTTP, connect to its Streamable HTTP endpoint instead of selecting SSE merely because both use HTTP.
Use a server object in the same process
If your Python application already has the server object, pass it directly to Client. This is useful for tests and embedding a server in the application that created it. The calls still pass through the MCP protocol layer, while avoiding a separately launched subprocess or remote HTTP connection.
async with Client(server) as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
Here, server represents the server object created by your application; it is not a URL or a command string. Use the server’s actual tool name and input schema.
Call a tool and handle its result
The examples use await client.call_tool(name, arguments). The first argument is the server’s tool name; the second is a mapping of the tool’s input fields to values. Tool names and accepted arguments are determined by the server, so check its available tools and schemas rather than assuming that every server implements add.
Best Value
The example prints result.structured_content, which is useful when the server returns structured data. If that field is not populated for a particular tool response, inspect the result using the response structure documented by the SDK and server; do not assume every tool returns the same content shape.
Troubleshoot common connection failures
- The client is constructed but tool calls do not work: construction selects a transport but does not open it. Put the client in
async withand make calls inside that block. - Connection refused or endpoint not found: verify that the server is running, reachable, and serving MCP at the exact URL and path. Confirm whether it expects Streamable HTTP at a path such as
/mcpor legacy SSE at a path such as/sse. - A local process exits or never starts: check that the command exists in the Python client’s environment, that the server script path is correct, and that its arguments match its launch requirements. Read stderr for process diagnostics.
- Protocol messages appear corrupted over stdio: ensure the server does not print logs or other text to stdout. Protocol traffic uses stdin and stdout; route diagnostics to stderr.
- Authentication or proxy requests fail: configure the HTTP client supplied to the Streamable HTTP transport with the required headers, authentication, or proxy settings. Check that redirects do not move requests to an origin where the configured credentials or headers do not apply.
- A request times out: distinguish connection, write, pool, and read timeouts. The documented defaults are 30 seconds for connect/write/pool and 300 seconds for reads; configure the HTTP client for the server’s behavior if those limits do not fit.
- A tool call fails despite a successful connection: verify the tool name, required arguments, and value types against that server’s tool schema. A transport connection does not establish that a particular tool or input is valid.
Performance and reliability considerations
Choose the transport based on deployment, not on an assumed speed ranking. stdio keeps communication local but couples the client lifecycle to a subprocess. Streamable HTTP reaches a separately deployed service and requires network and authentication configuration where applicable. In-process use avoids a separate transport endpoint but requires the server object to live in the same application process. The available SDK documentation does not establish comparative throughput or latency figures, so measure the behavior of your own server and workload if performance is a deciding factor.
Use context managers so transport resources are released when work finishes. For HTTP, set timeouts with long-running responses in mind; the documented read timeout is longer than the connect/write/pool defaults because responses can remain open. For stdio, make the launched command reproducible in the environment that runs the client and keep diagnostic output off stdout.
Or skip the browser setup
If the task behind your MCP workflow is capturing web pages, ScreenshotNeo offers a screenshot API and MCP server. Its MCP tools include take_screenshot, get_page_info, and capture_pdf. This is a separate integration from the Python MCP connection examples above. For a direct API capture instead, the following Python request saves an image response:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
See the ScreenshotNeo API documentation for request options and setup. Cookie banners, newsletter popups, and chat widgets are removed before a shot; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. AI agents can use its MCP server, and the Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free.
Frequently Asked Questions
Can I use the MCP Python SDK with Python 3.9?
No. The current SDK documentation requires Python 3.10 or later.
Can I connect to a local MCP server without HTTP?
Yes. Use stdio when the SDK should start a local server process and communicate over stdin and stdout.
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.
Free tools Windows power users keep installed
One-click scans. No signup required.

