# What Actually Changes When an MCP Server Leaves Your Laptop

> Moving an MCP server behind a gateway: per-request auth, tenant isolation, request-bound approvals and structured logs, plus a lab with 13 runtime tests.

- URL: https://www.kielltampubolon.id/writing/mcp-server-leaves-your-laptop/
- Author: Kiell Tampubolon
- Published: 2026-09-11
- Last updated: 2026-10-24
- Language: en
- Tags: MCP Security, Deployment

## Key takeaways

- Behind a gateway an MCP server faces multiple clients with different tokens, multiple tenants, and write tools that need approval.
- Every request carries a bearer token that the gateway validates before the tool registry is consulted, so a wrong token returns 401 and a wrong path returns 404.
- Tenant scoping belongs at the gateway, so a tool physically cannot return another tenant's data.
- Write tool approvals are bound to a specific request ID and tool name and expire, so an approval for documents.archive does not authorize documents.delete.
- The lab has 13 runtime tests covering authentication, tenant boundary, approval binding, and every failure status, including 401, 404, 408 and 503.

An MCP server that works locally is not the same as an MCP server that runs behind a gateway other people can reach. Every tutorial shows the local case because the local case is easy. The interesting problems only appear the moment another client, another tenant, or another team needs to talk to it.

I built a small local lab to make those problems visible. This post is what I learned building it.

## The local-to-hosted gap

On a laptop, an MCP server talks to one client. There is one user, one workspace, and one trust boundary: your own machine.

Behind a gateway, that changes fast:

- Multiple clients, each with a different token.
- Multiple tenants, each with data that must not leak.
- Write tools that need approval before they run.
- Failure modes that a single-user local demo never exercises.

None of this is exotic. It is just the ordinary shape of anything that gets handed to a team.

## Four controls that make the difference

### 1. Per-request authentication

A gateway cannot trust a long-lived session. Every request carries a bearer token, and the gateway validates it before the tool registry is even consulted. Wrong token means 401. Wrong path means 404. That sounds obvious. A surprising number of demos skip both.

### 2. Tenant isolation at the gateway

Tenant scoping belongs at the edge, not inside each tool. If every tool has to remember to check the tenant, one tool will forget. When the gateway enforces it before the tool is called, a tool physically cannot return another tenant's data.

The pattern is simple: the token carries the tenant, the gateway attaches the tenant to the request, the tool only reads from that tenant's fixtures. The tool never sees the raw tenant ID from the caller.

### 3. Write tools require a request-bound approval

Read tools can run without ceremony. Write tools cannot. The approval is bound to a specific request ID and tool name, and it expires. A stale approval does not work. An approval for `documents.archive` does not authorize `documents.delete`.

This is what turns a demo into something a team can actually ship.

### 4. Structured logs with a request ID per call

Every call gets a request ID. Every log line carries it. Secrets are redacted before the line is written. When something goes wrong, the log shows the sequence of decisions that led to the failure, not just that the failure happened.

## What the lab does

A streamable HTTP gateway sits in front of a two-tool registry: `documents.list` (read) and `documents.archive` (write, requires approval). A target smoke client talks to the gateway the same way a real MCP client would.

Deterministic failure injection lets a reviewer trigger each failure class on demand:

- 401 for a bad token.
- 404 for a wrong path.
- 408 for a slow tool.
- 503 for an unavailable tool.

The test suite is small: 13 runtime tests. They cover authentication, tenant boundary, approval binding, and every failure status. No production dependencies, no external services, no deployment.

## What this pattern gives you

If you are moving MCP from a proof-of-concept to something a team can use, this is the checklist:

- Auth per request, not per session.
- Tenant at the edge, not inside tools.
- Approvals that expire and are bound to a request.
- Logs that answer "what did the agent try to do and why was it allowed".
- Failure classes tested, not just discovered.

None of this is a framework. It is four decisions and a runbook.

The code is at [github.com/glatinone/mcp-local-to-hosted-deployment-fix](https://github.com/glatinone/mcp-local-to-hosted-deployment-fix). If your team is stuck on this exact transition, I take short implementation sprints on it. [kielltampubolon.id](https://www.kielltampubolon.id/)

*Originally published on [DEV](https://dev.to/kielltampubolon/what-actually-changes-when-an-mcp-server-leaves-your-laptop-3fhh). Discussion happens there.*

## FAQ

### What changes when an MCP server moves from your laptop to a gateway?

A single user and single trust boundary becomes multiple clients, tenants and approval-gated write tools. The post lists four controls: per-request authentication, tenant isolation at the gateway, request-bound approvals for write tools, and structured logs with a request ID per call.

### Where should tenant isolation live in a hosted MCP server?

At the gateway, not inside each tool. If every tool has to remember the tenant check, one will forget, whereas gateway enforcement means a tool cannot return another tenant's data.

### How do you secure write tools on an MCP gateway?

Bind each approval to a specific request ID and tool name, and make it expire. A stale approval does not work, and an approval for documents.archive does not authorize documents.delete.
