# What is an MCP server?

> An MCP server gives an AI client tools and data through the Model Context Protocol. How MCP servers get their credentials, and how to keep keys out of configs.

URL: https://crunu.com/learn/mcp-server
Language: en
Updated: 2026-10-30

An MCP server is a program that exposes tools, data or prompts to an AI application through the Model Context Protocol, an open protocol that lets a client such as a coding agent call the server's functions, for example "search issues" or "query the staging database", in a standard way.

## How a client talks to a server

The protocol uses JSON-RPC messages over one of two standard transports ([MCP specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports)):

- **stdio.** "The client launches the MCP server as a subprocess." Messages go over the server's standard input and output, and the server "MUST NOT write anything to its `stdout` that is not a valid MCP message"; logs go to standard error.
- **Streamable HTTP.** The server runs as its own process, locally or remotely, and clients connect over HTTP.

## Where credentials come in

Most useful MCP servers call some other service, so they need its API key or token. The specification splits this by transport. For HTTP, it defines an OAuth-based authorization flow. For stdio, implementations "SHOULD NOT follow this specification, and instead retrieve credentials from the environment" ([MCP authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization)). In other words, a local MCP server usually expects its key in an [environment variable](https://crunu.com/learn/environment-variable), and the client's config file is where people put it.

That is the problem. Config files that list servers are often meant to be shared and committed, and a key typed into one becomes a [hardcoded secret](https://crunu.com/learn/hardcoded-secret) in the repository.

## Common mistakes

- **Literal keys in a committed config.** Use the client's variable references, such as `${API_KEY}`, if it supports them, and keep credentialed servers in a local, uncommitted scope.
- **Broad keys.** An MCP server's key is usable by whatever the model decides to do with the tool. Give it the narrowest permissions and a development or test account.
- **Forgetting the model reads untrusted text.** Tool results can carry instructions; see [prompt injection](https://crunu.com/learn/prompt-injection).
- **Remote servers without checks.** For HTTP servers, the specification requires validating the `Origin` header and recommends binding local servers to localhost only.

## Crunu and MCP

**Crunu has no MCP features.** It doesn't ship an MCP server, doesn't inspect agent traffic and doesn't know which process is an agent.

It can supply a stdio server's key at start time, so the value isn't in the config file. `crunu run` passes standard input and output straight through to the program it starts and writes its own messages to standard error, which is what the stdio transport needs. A client config can then start the server through it:

```json
{
  "mcpServers": {
    "issues": {
      "command": "crunu",
      "args": ["run", "--env", "web-app/development", "--", "node", "mcp/issues-server.js"]
    }
  }
}
```

Two honest limits. The server process still holds the key in its environment, as any process does. And `crunu run` needs your signed-in session with its keys in memory, which anything running as you can also use, including the agent's own shell. Use a development environment with narrow keys, and lock the session with `crunu lock` when an agent works unattended. We have checked how `crunu run` handles standard input and output, but not every MCP client; test with yours.

The layered setup for agents is in [keep secrets away from AI coding agents](https://crunu.com/guides/secrets-and-ai-coding-agents), and the config problem in detail in [API keys in MCP server configs](https://crunu.com/blog/api-keys-in-mcp-server-configs).

## Sources

- [Model Context Protocol specification: Transports](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports), checked October 30, 2026.
- [Model Context Protocol specification: Authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization), checked October 30, 2026.
