Skip to main content
CAMARA Connectivity Quality Management APIs

Tutorial: Dedicated Networks MCP Server

In this tutorial you install the CAMARA Dedicated Networks MCP server, give it to an AI assistant, and ask the assistant, in plain language, to find a service area, reserve a dedicated network, give a device access to it and dismantle both again.

Read the READMEs first

Read the README of rt-camara-examples and the MCP server's own README before you start. They list what the server needs and every setting.

RepositoryWhat it isUsed in
rt-camara-examplesThe MCP server (mcp-servers/dedicated-networks), the management portal and the Insomnia collectionsAll sections
You wantGo to
The server installed1. Install the server
A token for the sandbox2. Get a token
An AI assistant to use the server3. Give the server to an assistant
To book and release a network by asking4. Ask the assistant
To call the tools from a script, or use OpenCodeOther ways to use the server

You need: git; Python 3.10 or newer with pip; an AI assistant that can use MCP servers, such as Claude Code; and test credentials for a CAMARA sandbox. The sandbox addresses and the credentials are provided to 5G-MAG members on request.

1. Install the server​

git clone https://github.com/5G-MAG/rt-camara-examples.git
cd rt-camara-examples/mcp-servers/dedicated-networks
pip install -r requirements.txt

This installs mcp[cli] (the MCP framework), httpx (the HTTP client) and pydantic (input validation). To check that it starts, run it by hand:

python server.py

The server writes one line to standard error and then waits for a client:

[camara-mcp] Starting | API root: http://localhost:9091/ | Auth: NO TOKEN

Press Ctrl+C to stop it. An MCP client starts the server itself, from the configuration in section 3.

2. Get a token​

The server calls the sandbox with a bearer token. Request one with your client ID and secret from the token endpoint you were given (<TOKEN_URL>).:

curl -s -X POST <TOKEN_URL> -d grant_type=client_credentials -d client_id=<CLIENT_ID> -d client_secret=<CLIENT_SECRET>

The answer is a JSON document; copy the value of access_token. It is valid for one hour (expires_in is 3600), so request a new one when it expires.

Keep the token and the secret private

Do not put them in a repository, a screenshot or a chat. The configuration file you edit next holds the token; keep it on your own machine.

3. Give the server to an assistant​

An assistant starts the server from a configuration block. Save this as camara.mcp.json:

{
"mcpServers": {
"camara-dedicated-networks": {
"command": "python",
"args": [
"/path/to/rt-camara-examples/mcp-servers/dedicated-networks/server.py"
],
"env": {
"CAMARA_API_ROOT": "<CAMARA_API_ROOT>",
"CAMARA_ACCESS_TOKEN": "<the access_token you copied>"
}
}
}
}

Replace the path with the real path of server.py, <CAMARA_API_ROOT> with the base address of your sandbox, and the token with yours. Then start Claude Code with the server:

claude --mcp-config camara.mcp.json

The server's 12 tools are now available to the assistant, with the prefix mcp__camara-dedicated-networks__. Check it with the first question of the next section: the assistant calls camara_list_profiles and lists the profiles.

4. Ask the assistant​

Ask in plain language. The assistant chooses the tools; these are the questions that take you through a full cycle, with what to expect.

  1. "What network profiles are available?" The assistant lists the profiles with their id, device limit, throughput and QoS profiles (camara_list_profiles).
  2. "Find service areas at latitude 48.8467, longitude 2.2530." It lists the areas that cover the point, and a link for each to view it on a map (camara_retrieve_service_areas). Open a link to see the area on geojson.io.
  3. "Create a dedicated network using the profile called profile1 in the Roland Garros Tennis Courts area, from 2026-10-20T17:00:00Z to 2026-10-20T18:00:00Z." Give the window as start and end times with a time zone, starting now or later. The assistant reserves the network and answers with its id and status REQUESTED (camara_create_network).
  4. "What is the status of network <id>?" Within a few seconds the status moves to RESERVED or ACTIVATED; ask again if it still says REQUESTED (camara_get_network).
  5. "Grant phone number +1234567890 access to network <id>." It creates the access, with status REQUESTED, and gives its id (camara_create_access).
  6. "Is access <id> granted yet?" The status becomes GRANTED, or REJECTED with the reason (camara_get_access).
  7. "List all my dedicated networks and their status." (camara_list_networks)

Replace each <id> with the id from the earlier answer, or let the assistant carry it over in the conversation.

Dismantle​

Release what you booked, the accesses first:

  1. "Revoke access <id>." (camara_delete_access)
  2. "Delete network <id>." (camara_delete_network)

Then ask for the list of networks again: the answer is "No dedicated networks found."

An example conversation

This is a real conversation, held with Claude Code as the assistant against the sandbox, with the answers shortened. Your assistant will word its answers differently.

You: What network profiles are available?

The assistant calls camara_list_profiles and answers:

There are 6 network profiles available:

NameIDMax devicesUL / DLQoS profiles (default in bold)
profile17e54f738-9e58-4509-9069-7023f03b22b6100100 / 100 MbpsQOS_A, QOS_B, QOS_C
profile23016629c-9c76-4d2c-8069-b50a24f0f62e100,00010 / 10 MbpsQOS_D, QOS_E, QOS_F
broadband1e32608d-0e42-45e0-82a9-7c156972049c11 / 10 MbpseMBB
Medium OutsideBroadcast Production914BA5A4-B1DE-404F-B7BB-D5B89FFDBE081240 / 10 MbpsQoS_Ul20Mbps_Dl5Mbps, QoS_Ul10Mbps_Dl5Mbps, QoS_Bi1Mbps, QoS_RTC_64kbps
Small OutsideBroadcast Production5961C65A-290D-40FE-951F-902B909B5C38615 / 5 MbpsQoS_Ul10Mbps_Dl5Mbps, QoS_Bi5Mbps, QoS_Bi1Mbps, QoS_RTC_64kbps
MoJo/ENG Production629CD271-4DF2-47B8-B646-D2559D5C672615 / 5 MbpsQoS_Bi5Mbps, QoS_Bi1Mbps

You: Find service areas at latitude 48.8467, longitude 2.2530.

The assistant calls camara_retrieve_service_areas and answers:

Two service areas cover that point (48.8467, 2.2530).

1. Roland Garros Tennis Courts (625b2d4b-4da7-4f07-9169-e60ffdf76671)

  • Circle, centre (48.845867, 2.253156), radius 1000 m
  • Network profiles: profile1 (7e54f738-...), profile2 (3016629c-...)
  • QoS profiles: QOS_S, 58e104f7-7b61-4603-9d0a-4813583c27e9
  • GeoJSON map

2. Grand Paris (4161b722-fa41-4e1d-933d-ed0aabb0fa08)

  • Polygon covering the Paris metropolitan region
  • Network profiles: broadband (1e32608d-...)
  • QoS profiles: eMBB
  • GeoJSON map

You: Create a dedicated network using the profile called profile1 in the Roland Garros Tennis Courts area, from 2026-10-20T17:07:16Z to 2026-10-20T18:07:16Z.

The assistant calls camara_create_network and answers:

The network request was submitted and is in REQUESTED status, so it's waiting for the provider to approve it.

  • Network ID: e90cdef4-67ee-4e34-9a16-3d1f7ae01a3e
  • Profile: profile1 (100 devices, 100/100 Mbps, QoS_A, QOS_B and QOS_C, default QOS_A)
  • Area: Roland Garros Tennis Courts
  • Service time: 2026-10-20T17:07:16Z to 2026-10-20T18:07:16Z

You: What is the status of that network?

The assistant calls camara_get_network and answers:

The network e90cdef4-67ee-4e34-9a16-3d1f7ae01a3e is still REQUESTED. The provider hasn't approved it yet.

You: Grant phone number +1234567890 access to that network.

The assistant calls camara_create_access and answers:

The access request for +1234567890 was submitted. It's in REQUESTED status and waiting for the provider to approve it.

  • Access ID: 40ad271a-44ff-4198-9e22-f235e2b03398
  • Network: e90cdef4-67ee-4e34-9a16-3d1f7ae01a3e
  • QoS profiles: all profile1 options (QOS_A, QOS_B, QOS_C), default QOS_A, because you didn't restrict them

You: Is that access granted yet?

The assistant calls camara_get_access and answers:

Yes, the access 40ad271a-44ff-4198-9e22-f235e2b03398 is now GRANTED for +1234567890.

You: Revoke that access.

The assistant calls camara_delete_access and answers:

I revoked access 40ad271a-44ff-4198-9e22-f235e2b03398, so +1234567890 can no longer use network e90cdef4-67ee-4e34-9a16-3d1f7ae01a3e.

You: Delete that network.

The assistant calls camara_delete_network and answers:

I deleted network e90cdef4-67ee-4e34-9a16-3d1f7ae01a3e, which cancels the reservation. Its device access was already revoked, so nothing is left from this session.

You: List all my dedicated networks.

The assistant calls camara_list_networks and answers:

You have no dedicated networks. That fits with the one we created having been deleted.

The server also gives the assistant four workflow prompts, dedicated_network_workflow, discover_profiles_and_areas, manage_device_access and teardown_network, which guide it through these steps. The parameters of all 12 tools and the recommended order of calls are in the tool reference.

Other ways to use the server​

Call the tools from a script

Any MCP client can use the server, so you can try every tool without an assistant. Set CAMARA_API_ROOT and CAMARA_ACCESS_TOKEN in the environment, then, in the server's folder:

import asyncio, os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
server = StdioServerParameters(command="python", args=["server.py"], env=dict(os.environ))
async with stdio_client(server) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("camara_list_profiles", {"params": {}})
print("".join(c.text for c in result.content if hasattr(c, "text")))

asyncio.run(main())

Every tool takes its arguments in a single params object, for example {"params": {"atLocation": {"latitude": 48.8467, "longitude": 2.2530}}} for camara_retrieve_service_areas.

Use OpenCode

OpenCode reads MCP servers from an opencode.json in your project, or globally from ~/.config/opencode/opencode.json. Add:

{
"mcp": {
"camara-dedicated-networks": {
"type": "local",
"command": ["python", "/path/to/rt-camara-examples/mcp-servers/dedicated-networks/server.py"],
"enabled": true,
"environment": {
"CAMARA_API_ROOT": "<CAMARA_API_ROOT>",
"CAMARA_ACCESS_TOKEN": "<the access_token you copied>"
}
}
}
}

Restart OpenCode. The tools then have the prefix camara-dedicated-networks_, for example camara-dedicated-networks_camara_list_profiles.

Run the server's tests
pip install -r requirements-dev.txt
python -m pytest