RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /How-to
  5. /How to Connect MCP Client to Remote MCP Server
HOW-TO · RAG

How to Connect MCP Client to Remote MCP Server

advanced·20 min·By Fredoline Eruo
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

MCP server deployed with network access, Python 3.10+

What this does

MCP clients connect to remote servers over SSE (Server-Sent Events) or WebSocket transports, enabling LLMs to call tools hosted on different machines or services.

Steps

  • Run an MCP server with SSE transport. Expose tools over HTTP.
from mcp.server import Server
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.routing import Route

server = Server("remote-tools")

@server.tool("hello")
async def hello(name: str) -> str:
    return f"Hello, {name}!"

sse = SseServerTransport("/messages")

async def handle_sse(request):
    async with sse.connect_sse(request.scope, request.receive, request._send) as (read, write):
        await server.run(read, write)

app = Starlette(routes=[
    Route("/sse", endpoint=handle_sse),
    Route("/messages", endpoint=sse.handle_post_message, methods=["POST"]),
])
  • Run the server with Uvicorn.
pip install uvicorn
uvicorn app:app --host 0.0.0.0 --port 8000
  • Connect a client to the remote server. Use SseClient for SSE transport.
from mcp.client import sse_client
from mcp import Client

async def connect_remote():
    async with sse_client("http://localhost:8000/sse") as (read, write):
        client = Client(read, write)
        tools = await client.list_tools()
        for t in tools:
            print(f"Remote tool: {t.name}: {t.description}")

        result = await client.call_tool("hello", {"name": "Remote"})
        print(result.content[0].text)
  • Handle authentication. Pass tokens via headers or query parameters.
async def connect_with_auth():
    headers = {"Authorization": "Bearer sk-my-token"}
    async with sse_client(
        "http://localhost:8000/sse",
        headers=headers
    ) as (read, write):
        client = Client(read, write)
        tools = await client.list_tools()
        print(f"Authenticated. Found {len(tools)} tools.")
  • Reconnection on disconnection. Wrap the client in a retry loop.
import asyncio

async def persistent_client(url: str, max_retries=3):
    for attempt in range(max_retries):
        try:
            async with sse_client(url) as (read, write):
                client = Client(read, write)
                yield client
            break
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            await asyncio.sleep(2 ** attempt)

Verification

curl -N http://localhost:8000/sse
# Expected: SSE stream with endpoint event

Common failures

  • CORS errors with browser clients. If the client runs in a browser, the server must include CORS headers. Use Starlette middleware.
  • SSE endpoint not found. The client URL must point to the exact SSE route (e.g., /sse). A trailing slash mismatch causes 404.
  • Connection timeout. Remote servers behind firewalls or NAT may drop idle SSE connections. Configure keepalive or use WebSocket transport instead.
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Set Up MCP Server with Standard Tools
  • How to Create Custom MCP Tools for Your Application
← All how-to guidesCourses →