MCP servers¶
You want a model to do something rather than only describe it - read a ticket, query a table, call an internal API. An MCP server is the component that offers those actions as tools, and holds the credentials they need.
The property that matters is what an MCP server does not hand over. The model asks for an action and receives a result. The database password, the API token and the network position stay on the server. A model that is manipulated can act only through the tools you wrote.
Prerequisites¶
- A project and CLI access - see Get started
- An MCP server image, or one from the marketplace
- The system the tools will talk to, reachable from the cluster
The step-by-step guide and the console walkthrough cover the operations. The rest of this page explains how it fits together.
Where the credential stops¶
flowchart LR
MODEL["model"] -->|"tool call - name and arguments"| SRV
SRV["MCP server<br/>holds the credential"] -->|"authenticated query"| DB[("internal system")]
DB -->|rows| SRV
SRV -->|"result only"| MODEL
SRV -.->|denied by NetworkPolicy| NET(["everything else"])
Two boundaries are doing work here, and they fail differently.
The credential boundary means a leaked conversation is not a leaked password. It holds as long as the server never returns the secret in a tool result.
The network boundary is what a NetworkPolicy gives you: the server can reach the one
system it needs and nothing else. Without it, a tool with an argument you did not validate
becomes a way to reach anything the cluster can reach.
Tool arguments are model output¶
This is the part that makes an MCP server unlike an ordinary internal service, and it is worth being blunt about.
The arguments arriving in a tool call were written by a model, and that model has been reading things - documents, web pages, ticket comments, the output of earlier tools. Any of that content can contain instructions aimed at the model. So a tool argument is not input from your application; it is input from whoever wrote the text the model last read.
Treat every argument as hostile input from an anonymous source, because that is what it is:
- Validate server-side against an allow-list of what the tool may act on. Do not rely on the tool description to constrain the model - it is a suggestion, not a control.
- Use parameterised queries. Never build SQL or a shell command by interpolation.
- Scope the credential to what the tool needs. A read-only tool gets a read-only role.
- Prefer specific tools over general ones.
get_order(id)is safe in a way thatrun_query(sql)cannot be.
A server offering both read and network access can chain the two
A tool that reads private data and a tool that reaches the network are each fine alone. A server offering both lets one instruction turn the first into the second. Split them across servers with different egress policies when you can.
Designing tools for a caller that guesses¶
A model picks tools from their names and descriptions, without your context and without certainty. A tool that is easy to confuse will be called wrongly.
| Works well | Causes trouble | |
|---|---|---|
| Naming | one obvious verb and object | near-synonyms across several tools |
| Arguments | few, typed, required | many optional flags |
| Errors | say what to do differently | a stack trace |
| Scope | one job per tool | one tool with a mode argument |
| Results | just what was asked for | whole records, including secrets |
Return the minimum that answers the call. Everything a tool returns enters the model's context, becomes billable tokens, and can be repeated back to whoever is talking to it.
What is fixed after creation¶
| Changeable | |
|---|---|
| The tools the server offers | yes - clients rediscover them |
| Its egress policy | yes |
| The credential it holds | yes - rotate in the Secret |
| A tool name clients have configured | not safely |
MCP authentication is still being settled
The model above and the security properties to design for are stable. How a client authenticates to a server is not yet fixed on the platform, so treat the exposure pattern in the step-by-step guide as the current answer rather than a settled one.
Related¶
- Step-by-step guide - deploy a server and constrain its egress
- Console walkthrough - the same thing in the console
- Run a sandboxed agent - isolating code the model writes
- MCP servers - what the platform provides
- Networking - the default-deny egress pattern