Skip to content

Deploy an MCP server

By the end of this tutorial you will have an MCP server running in your project, exposing tools to an AI client, with a NetworkPolicy that constrains exactly what those tools can reach.

Prefer clicking through the console instead? See the console walkthrough.

Scaffold status

The step structure below is agreed and stable. Exact commands, manifests and captured output are added as this flow is verified end to end on the live platform — this page deliberately shows no invented output.

Prerequisites

  • A project and CLI access — see Get started
  • An MCP server image, or one from the marketplace
  • The internal system your tools will talk to — a database, an API — reachable from the cluster

Overview

flowchart LR
    AGENT["Agent / LLM client"] -->|MCP| SRV["MCP server"]
    SRV --> DB[("Internal database")]
    SRV -.->|denied| NET(["Everything else"])

The MCP server is the component holding the credential. The model gets tool results; it never gets the secret.

Steps

1. Create a project for the server

Its own namespace, so its credentials and its network policy are scoped to it alone.

2. Store the tool credentials as Secrets

Database passwords, API tokens — mounted or injected at runtime.

3. Deploy the server

A Deployment and a Service. Nothing platform-specific: it is an ordinary workload.

4. Apply a default-deny egress policy

Then allow exactly the systems the tools need, plus DNS. See Networking for the pattern.

5. Expose it to your clients

Internal-only via a Service if the agent runs in-cluster; a TLS route if it does not.

6. Connect a client

Point your MCP-capable client at the server and confirm it discovers the tool list.

Verify

  • The client lists the tools you expect
  • A tool call returns real data from the backing system
  • An egress attempt to something outside the allow-list is refused:
oc exec deploy/<mcp-server> -n <project> -- \
  curl -sS --max-time 5 https://example.com || echo "blocked as expected"

Tool arguments are model output

Arguments arriving in a tool call are steered by whatever the model has read, including content from untrusted sources. Validate them server-side, use parameterised queries, and never interpolate them into a shell command.

Clean up

Remove everything this tutorial created, in reverse order:

oc delete -k . -n <project>          # or delete the project outright
oc delete project <project>

Next

Run a sandboxed agent →