## Definition
An **MCP server** is a process the agent launches and converses with using the [[Model Context Protocol]]. Each external system the agent needs to reach is wrapped by a server that exposes tools, resources, and optionally prompts.
## Configuration (Claude Code)
```jsonc
{
"mcpServers": {
"postgres-staging": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres",
"postgresql://readonly:***@staging-db.internal/app?sslmode=require"],
"type": "stdio"
},
"internal-api": {
"url": "https://mcp.internal.company.com",
"type": "http",
"headers": { "Authorization": "Bearer ${INTERNAL_MCP_TOKEN}" }
}
}
}
```
## What to Put Behind MCP
**Yes:**
- Read-only access to production-shaped data (staging DB, logs, metrics).
- Ticketing systems for filing / updating issues.
- Internal APIs the agent calls during code-gen.
- Documentation systems (Confluence, Notion).
**No, or carefully:**
- Anything that mutates production. Default read-only; add write surgically.
- Long-lived secrets. The server itself becomes an attack surface.
- Capabilities the filesystem already provides — the agent can read your repo.
## Security
The server runs with whatever credentials you give it. Apply least privilege — read-only, single-database, single-project where possible. Use `${ENV_VAR}` references in `mcp.json`, never inline secrets.
## Writing Your Own
A minimal Python server using the official SDK:
```python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("feature-flags")
@mcp.tool()
async def get_flag(name: str, env: str = "staging") -> dict:
"""Return the current value of a feature flag."""
...
if __name__ == "__main__":
mcp.run()
```
## Related
- [[Model Context Protocol]]
- [[Extension Trifecta]]
- [[Hook]]