Skip to content

Secure a support-escalation MCP server

You start with an MCP server that already works, and already leaks. Over the next couple of hours you'll close every leak with Keycard: real authentication, per-user delegation, vaulted secrets, and a policy that blocks an over-reaching agent live.

Most security tutorials build up from nothing, so you never quite feel the problem you’re solving. In this workshop, you’ll clone a small but functional custom MCP server. After prompting it, you’ll see several security problems. The workshop walks you through solving these problems, which are commonly found in most custom MCP servers today.

The MCP server is a support tool called support-escalation. A support engineer connects their agent to the MCP server and uses it to triage customer support requests, escalating tickets to engineering as Linear issues when appropriate. The MCP server works, but is insecure and dangerous.

User-submitted support tickets are full of personally identifiable information (PII): names, emails, and even the occasional pasted password or social security number. Support is allowed to hold that. Engineering’s issue tracker should never hold customer PII. An escalation has to cross a compliance boundary, carrying the technical problem and a ticket UUID, but obfuscating the customer’s identity.

The MCP server has three tools and each demonstrates a security challenge that you might recognize from scenarios you’ve personally experienced:

ToolWhat it doesSecurity gap
get_support_ticketsReads the support queue/mcp can be accessed freely by any caller. No authentication at all.
escalate_ticketFiles a Linear issue from a ticketOne shared, full-access Linear API key. No delegation, no least privilege, no user attribution. It also creates issues verbatim from customer-provided text, PII and all.
delete_issueTrashes a Linear issueThe API key (and thus the agent acting on a human’s behalf) can decide to delete any issue in the workspace.

Each security problem can be followed to the same root cause: the server has no idea who is calling it, and it holds long-lived credentials that are far too powerful. You’ll use Keycard to implement the following flow:

  1. A person signs in. Anything the agent does is on behalf of an identified human user (not using a shared API key).

  2. Their agent calls your MCP server with a token that proves who they are, and nothing else.

  3. For each downstream resource the MCP server touches, it exchanges that user token for a least-privilege credential, scoped to one action and tied to the user.

  4. A policy evaluates every exchange at issuance. If an agent asks for access it shouldn’t have, the credential is never created, leaving nothing to leak or be misused.

  5. Every hop is audit-logged and declares the delegation chain: “this agent, acting for this person, received this access.”

By the end, the shared API key is gone and the MCP server does not contain any credentials worth stealing. When an agent requests a permission it shouldn’t have, a policy blocks it before the action, not after.

  • Put real authentication in front of an MCP server, so every call carries a verifiable identity.
  • Exchange a caller’s token for scoped, short-lived credentials, instead of storing static keys.
  • Keep secrets in a vault, off disk and out of your codebase.
  • Delegate access per user, so a third party resource attributes actions to the human who authorized them.
  • Mask PII server-side so sensitive data never crosses a compliance boundary.
  • Write a policy that blocks overreach at credential issuance, so dangerous credentials are never minted in the first place.
  • Read an audit log that proves who did what, through which agent, with what access.

Each chapter, you’ll learn why this chapter matters, steps to follow, a prompt to give to your coding agent, and a checkpoint to clear. One chapter identifies one problem and implements one solution so cause and effect is clear.

Example prompt:

Prompt your coding agent

Connect to the MCP server at http://localhost:8000/mcp. List the open support tickets, then escalate the critical payment one to engineering.

Example checkpoint:

Ready? Make sure you’ve got the prerequisites, then clone the insecure v1.