5GC MCP Server — Client Integration Guide
The MCP server exposes 74 tools (codecs, NF discovery, UE contexts, traces, metrics, QoS,
status, analysis, core control and runtime configuration) over two transports that run concurrently.
Tools are classified by risk, and a client’s access depends on the server’s access_mode and its
bearer token; see docs/mcp-tools.md:
| Transport | When to use |
|---|---|
| stdio | Client spawns the binary as a subprocess (Claude Code, Claude Desktop, LM Studio, Cursor, Continue) |
| HTTP SSE | Client connects over the network to :9300 (curl, remote agents, Postman, generic MCP clients) |
Both transports serve the identical tool registry — pick based on what your client supports.
Prerequisites
Section titled “Prerequisites”# 1. Build the binary (from repo root)make -C mcp build # produces mcp/bin/mcp
# 2. Start the 5GC stack (tools that query AMF/NRF need it running)make up # core NFs on published host ports
# 3. Generate dev PKI (once — needed for NRF mTLS)make pki # produces pki/ca.crt + pki/mcp.{crt,key}Quick liveness check:
curl -s http://localhost:9300/mcp/health # {"status":"ok","tools":77} (74 tools + 3 deprecated aliases)1. Claude Code
Section titled “1. Claude Code”Claude Code runs in WSL (Linux) and launches the binary directly over stdio.
The repo ships a pre-wired .mcp.json at the repo root — nothing to configure.
// .mcp.json (already committed){ "mcpServers": { "5gc": { "command": "/path/to/claudia-5gc/mcp/bin/mcp", "env": { "CONFIG_PATH": "/path/to/claudia-5gc/mcp/config/local.yaml", "MCP_TRANSPORT": "stdio" } } }}local.yaml points to the stack’s published host ports
(https://localhost:8000 for NRF, http://localhost:9002 for AMF).
Make sure the stack is up (make up) before using tools that query NFs.
Verify inside a Claude Code session:
claude mcp list # shows "5gc connected"Then ask naturally: “list registered NFs”, “decode NAS PDU 7e004111000100”,
“get UE context for imsi-001010000000001”. Tool names are
nas_decode, nf_list, ue_list, etc.; Claude Code may show them as 5gc:nas_decode.
Add via CLI (alternative to .mcp.json)
Section titled “Add via CLI (alternative to .mcp.json)”claude mcp add 5gc \ --env CONFIG_PATH=$(pwd)/mcp/config/local.yaml \ --env MCP_TRANSPORT=stdio \ -- $(pwd)/mcp/bin/mcp2. Claude Desktop — macOS / Linux
Section titled “2. Claude Desktop — macOS / Linux”Edit claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{ "mcpServers": { "5gc": { "command": "/absolute/path/to/claudia-5gc/mcp/bin/mcp", "args": ["-config", "/absolute/path/to/claudia-5gc/mcp/config/local.yaml"] } }}Restart Claude Desktop after editing. The server name 5gc appears in the
tool picker when tools are available.
3. Claude Desktop — Windows (WSL2 + Docker)
Section titled “3. Claude Desktop — Windows (WSL2 + Docker)”This setup has two moving parts: the MCP binary runs inside WSL2 and the 5GC
stack runs in Docker Desktop (which publishes ports to Windows localhost
automatically).
Why "url" does not work here
Section titled “Why "url" does not work here”The "url" field in mcpServers is only supported by the Claude Messages API,
not by the Claude Desktop application. Claude Desktop always needs a subprocess
(command + args).
Why mcp-remote is not needed
Section titled “Why mcp-remote is not needed”mcp-remote (npm bridge) was historically used to forward stdio→HTTP. It is
unreliable here because newer versions of Claude Desktop (2025+) interpret the
outputSchema field in tool manifests as a 2025-03-26 spec indicator and then
require structuredContent in every tool result — which mcp-remote cannot
provide. This server deliberately omits outputSchema from manifests (see
Protocol notes) and uses the binary directly.
Step 1 — Ensure Docker Desktop is running and the 5GC stack is up:
# In WSL terminalmake upcurl -s http://localhost:9300/mcp/health # verify port 9300 is reachablePort 9300 is published to Windows localhost:9300 automatically by Docker
Desktop — no manual port-forwarding needed.
Step 2 — Build the binary (in WSL):
make -C mcp buildStep 3 — Create the bridge script at mcp/bin/mcp-desktop.sh (untracked: mcp/bin/ is gitignored, so you create it locally):
#!/bin/bash# Claude Desktop on Windows spawns this via wsl.exe -e.exec /path/to/claudia-5gc/mcp/bin/mcp \ -config /path/to/claudia-5gc/mcp/config/local.yamlUpdate the absolute paths to match your WSL home directory if needed, then make it executable:
chmod +x mcp/bin/mcp-desktop.shStep 4 — Edit Claude Desktop config on Windows:
File: %APPDATA%\Claude\claude_desktop_config.json
(open with: notepad %APPDATA%\Claude\claude_desktop_config.json)
{ "mcpServers": { "5gc": { "command": "C:\\Windows\\System32\\wsl.exe", "args": ["-e", "/path/to/claudia-5gc/mcp/bin/mcp-desktop.sh"] } }}Replace <user> with your WSL username. The rest of your preferences block
stays unchanged — only add the mcpServers key.
Step 5 — Restart Claude Desktop (close fully, reopen).
Troubleshooting (Windows)
Section titled “Troubleshooting (Windows)”Check the MCP log in PowerShell:
Get-Content "$env:APPDATA\Claude\logs\mcp-server-5gc.log" -Tail 50| Symptom | Cause | Fix |
|---|---|---|
| Server never appears | wsl.exe path wrong or WSL not installed |
Run wsl.exe --version in CMD |
tools/list works but every tool call fails |
outputSchema in manifest triggers 2025-spec validation |
Already fixed in this server — ensure binary is rebuilt |
connection refused on tool call |
Docker stack not running | make up in WSL |
| Script not found | Path in args incorrect |
Check path with wsl.exe -e ls /home/<user>/... from CMD |
4. LM Studio
Section titled “4. LM Studio”LM Studio 0.3.5+ supports MCP servers via the Developers tab in Settings.
stdio (recommended)
Section titled “stdio (recommended)”In LM Studio → Settings → Developers → MCP Servers → Add Server:
{ "name": "5gc", "command": "/absolute/path/to/claudia-5gc/mcp/bin/mcp", "args": ["-config", "/absolute/path/to/claudia-5gc/mcp/config/local.yaml"], "env": { "MCP_TRANSPORT": "stdio" }}On Windows with WSL, use the same wsl.exe wrapper as Claude Desktop:
{ "name": "5gc", "command": "C:\\Windows\\System32\\wsl.exe", "args": ["-e", "/path/to/claudia-5gc/mcp/bin/mcp-desktop.sh"]}HTTP SSE (if LM Studio supports it)
Section titled “HTTP SSE (if LM Studio supports it)”Some LM Studio versions support SSE-transport MCP servers. Point it at:
http://localhost:9300/mcp/sseThe server must be running first (make up or make mcp-up).
5. Cursor
Section titled “5. Cursor”Cursor reads MCP configuration from .cursor/mcp.json in the project root or
from ~/.cursor/mcp.json globally.
macOS / Linux
Section titled “macOS / Linux”{ "mcpServers": { "5gc": { "command": "/absolute/path/to/claudia-5gc/mcp/bin/mcp", "args": ["-config", "/absolute/path/to/claudia-5gc/mcp/config/local.yaml"] } }}Windows (WSL)
Section titled “Windows (WSL)”{ "mcpServers": { "5gc": { "command": "C:\\Windows\\System32\\wsl.exe", "args": ["-e", "/path/to/claudia-5gc/mcp/bin/mcp-desktop.sh"] } }}Reload the window after editing (Ctrl+Shift+P → Developer: Reload Window).
6. Continue (VS Code / JetBrains)
Section titled “6. Continue (VS Code / JetBrains)”Continue reads MCP configuration from ~/.continue/config.json.
Add to the mcpServers array:
{ "mcpServers": [ { "name": "5gc", "command": "/absolute/path/to/claudia-5gc/mcp/bin/mcp", "args": ["-config", "/absolute/path/to/claudia-5gc/mcp/config/local.yaml"], "env": { "MCP_TRANSPORT": "stdio" } } ]}Windows (WSL) — use the same wsl.exe wrapper:
{ "mcpServers": [ { "name": "5gc", "command": "C:\\Windows\\System32\\wsl.exe", "args": ["-e", "/path/to/claudia-5gc/mcp/bin/mcp-desktop.sh"] } ]}Reload the Continue extension after editing.
7. Generic HTTP/SSE client (curl, Postman, custom agents)
Section titled “7. Generic HTTP/SSE client (curl, Postman, custom agents)”The HTTP SSE transport follows MCP 2024-11-05 conventions. Bring the server up first:
make up # 5GC stack (needed for NF/UE tools)# The mcp container starts automatically as part of the stack.Stateless (inline response, no session needed)
Section titled “Stateless (inline response, no session needed)”# Health checkcurl -s http://localhost:9300/mcp/health
# List every tool visible to this callercurl -s http://localhost:9300/mcp -X POST \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | jq '.result.tools[].name'
# Decode a NAS RegistrationRequestcurl -s http://localhost:9300/mcp -X POST \ -H "Content-Type: application/json" \ -d '{ "jsonrpc":"2.0","id":2,"method":"tools/call", "params":{"name":"nas_decode","arguments":{"hex":"7e004111000100"}} }' | jq -r '.result.content[0].text' | jq .
# List registered UEscurl -s http://localhost:9300/mcp -X POST \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"ue_list","arguments":{}}}' \ | jq -r '.result.content[0].text'Session-based (SSE stream, responses via stream)
Section titled “Session-based (SSE stream, responses via stream)”# Terminal 1: open the SSE stream; note the session ID in the endpoint eventcurl -sN http://localhost:9300/mcp/sse# → event: endpoint# → data: http://localhost:9300/mcp?session=<uuid>
# Terminal 2: post using the session — response comes back on Terminal 1's streamSESSION_ID=<uuid-from-above>curl -s "http://localhost:9300/mcp?session=$SESSION_ID" -X POST \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"nf_list","arguments":{}}}'# POST returns 202 Accepted; the JSON-RPC result arrives on the SSE stream.Authentication (optional)
Section titled “Authentication (optional)”Set auth.bearer_token in the config (or MCP_BEARER_TOKEN env var):
curl -s http://localhost:9300/mcp -X POST \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '...'/mcp/health is always open (no auth) for liveness probes.
Protocol notes
Section titled “Protocol notes”This server negotiates MCP 2024-11-05. A few implementation decisions that affect clients:
outputSchema is omitted from tool manifests.
outputSchema was introduced in MCP 2025-03-26. When present in a 2024-11-05
negotiation, newer Claude Desktop versions interpret it as a 2025-spec indicator
and require a structuredContent field in every tool result. Since this server
targets 2024-11-05 and does not produce structuredContent, the field is omitted
to avoid false failures.
isError is omitted from successful results.
The MCP spec makes isError optional; absent = false. Some Claude Desktop
versions (2025+) treat the presence of isError: false as an error indicator.
The field is included only when the tool actually fails (isError: true).
Logs go to stderr, never stdout. The stdio protocol channel is stdout only. All slog output goes to stderr, which Claude Desktop and other clients typically capture in their MCP log files — not in the protocol stream.
TLS / mTLS
Section titled “TLS / mTLS”The NRF SBI always uses mTLS; the MCP server presents pki/mcp.crt /
pki/mcp.key. Generate the dev PKI once with make pki.
For the SSE transport in production, enable HTTPS:
sse: tls: cert_file: "/path/to/mcp.crt" key_file: "/path/to/mcp.key" ca_file: "/path/to/ca.crt" # adds mTLS client verificationWith TLS, the endpoint URL becomes https://localhost:9300/mcp/sse.
Made and developed by Francisco Javier Curieses Sanz · Docs mirrored from claudia-5gc @ v2.6.0 · Privacy · Legal