MCP Integration
The Monogoto API exposes a full Model Context Protocol (MCP) server, allowing AI assistants and MCP-compatible clients to interact with your SIM fleet, reports, campaigns, orders, and more — all through natural language or structured tool calls.
Overview
MCP is an open protocol that lets AI models call external tools and read resources over a standardised JSON-RPC 2.0 interface. The Monogoto MCP server runs at:
https://api.monogoto.io/v1/mcp
Once connected, an AI client can:
- Query and filter your SIM inventory
- Check connectivity, location, and data session status in real time
- Run usage and NetFlow reports with date/group/network filters
- Browse orders, campaigns, audit logs, and tags No custom code is needed — just point your MCP client at the endpoint and authenticate.
Transports
Two transports are available. Use Streamable HTTP unless your client only supports SSE.
| Transport | Endpoint | Best for |
|---|---|---|
| Streamable HTTP | POST /v1/mcp |
All modern clients — stateless, single endpoint |
| SSE (legacy) | GET /v1/mcp/sse + POST /v1/mcp/messages |
Older clients that only support Server-Sent Events |
Streamable HTTP
Send a single POST request with a JSON-RPC body:
curl -X POST https://api.monogoto.io/v1/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
SSE Transport
- Open an SSE connection — you receive an
endpointevent with the messages URL - POST JSON-RPC messages to that URL, passing
?session_id=<id>from the event
# Step 1 — open SSE stream
curl -N https://api.monogoto.io/v1/mcp/sse \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# → data: {"type":"endpoint","uri":"/v1/mcp/messages?session_id=abc123"}
# Step 2 — send JSON-RPC message
curl -X POST "https://api.monogoto.io/v1/mcp/messages?session_id=abc123" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
Authentication
Two authentication methods are supported. The right choice depends on your client type.
Option 1 — Bearer Token
Pass a standard Monogoto JWT in the Authorization header on every request. Best for programmatic clients, backend services, and clients where you can configure custom headers.
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Obtain a token from POST /v1/auth/token as described in the Authentication guide.
Option 2 — access_token Tool (Recommended for AI clients)
For clients that cannot set custom HTTP headers (e.g. Claude Desktop via stdio bridge), authenticate inside MCP itself. Call the built-in access_token tool — no Authorization header needed.
Step 1 — Initialize
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": { "name": "my-client", "version": "1.0.0" }
}
}
Step 2 — Call the access_token tool
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "access_token",
"arguments": {
"username": "your@email.com",
"password": "your-password"
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [{
"type": "text",
"text": "{\"success\":true,\"message\":\"Login successful\",\"session_token\":\"a3f9c2...\"}"
}]
}
}
Step 3 — Pass the session token in all subsequent requests
x-mcp-session-token: a3f9c2...
The session token is stored server-side in Redis (AES-256-GCM encrypted) with a 4-hour TTL. Before it expires, call the refresh-token tool to silently extend the session.
Session vs Bearer — summary
| Bearer Token | access_token Tool | |
|---|---|---|
| Header used | Authorization: Bearer ... |
x-mcp-session-token: ... |
| Auth happens | Before MCP session starts | Inside MCP via access_token tool |
| Best for | Programmatic / backend clients | AI desktop clients (Claude Desktop, Cursor) |
| Token lifetime | 4 hours (standard JWT) | 4 hours (Redis session) |
Public vs Authenticated Tools
Without any authentication, only two tools are visible on tools/list:
| Tool | Description |
|---|---|
access_token |
Authenticate with email and password |
refresh-token |
Refresh an active session before it expires |
Once authenticated (either method), all 109 tools become available.
Connecting Clients
Claude Desktop
Claude Desktop uses a stdio bridge (mcp-remote) to connect to HTTP MCP servers.
1. Install Node.js if not already installed.
2. Edit claude_desktop_config.json:
| Platform | Config file location |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"monogoto": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.monogoto.io/v1/mcp"
]
}
}
}
3. Restart Claude Desktop.
4. Authenticate — Claude Desktop cannot set custom HTTP headers, so authentication happens via the access_token tool. When you start a conversation, ask Claude:
"Connect to Monogoto using my credentials: user@example.com"
Claude will call the access_token tool, obtain a session token, and use it automatically for the rest of the session.
Cursor
Cursor supports HTTP MCP servers natively via project-level or global config.
Project-level — create .cursor/mcp.json in your project root:
{
"mcpServers": {
"monogoto": {
"url": "https://api.monogoto.io/v1/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
}
}
}
Global — add to ~/.cursor/mcp.json to make it available in all projects.
Tip: Use a Cursor secret instead of embedding the token directly in the file.
After saving, open Cursor Settings → MCP and confirm monogoto appears with a green status indicator.
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"monogoto": {
"serverUrl": "https://api.monogoto.io/v1/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
}
}
}
Restart Windsurf. The Monogoto tools will appear in the Cascade tool panel.
MCP Inspector (Testing & Debugging)
The official MCP Inspector lets you browse tools and make test calls directly from a browser UI — useful for exploring the API before integrating it into a client.
npx -y @modelcontextprotocol/inspector https://api.monogoto.io/v1/mcp
In the Inspector UI:
- Add a request header:
Authorization: Bearer YOUR_ACCESS_TOKEN - Click Connect
- Browse the Tools tab and run test calls
Programmatic / Custom Client
For backend services or custom integrations, call POST /v1/mcp directly.
BASE_URL = "https://api.monogoto.io/v1/mcp"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"
def mcp_call(method: str, params: dict, request_id: int = 1) -> dict:
resp = requests.post(BASE_URL, json={
"jsonrpc": "2.0",
"id": request_id,
"method": method,
"params": params,
}, headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {ACCESS_TOKEN}",
})
resp.raise_for_status()
return resp.json()
# Initialize session
mcp_call("initialize", {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {"name": "my-service", "version": "1.0.0"},
})
# List active SIMs
result = mcp_call("tools/call", {
"name": "list-things",
"arguments": {"status": "ACTIVATED", "limit": 20},
})
print(result)const BASE_URL = 'https://api.monogoto.io/v1/mcp';
async function mcpCall(method, params, headers = {}) {
const res = await fetch(BASE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MONOGOTO_TOKEN}`,
...headers,
},
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
});
return res.json();
}
// Get a specific SIM
const result = await mcpCall('tools/call', {
name: 'get-thing',
arguments: { id: '8937010000000000000' },
});
console.log(result);Available Tools
All 109 tools are listed below. Authenticate first to access them — only access_token and refresh-token are visible to unauthenticated sessions.
Authentication
| Tool | Description |
|---|---|
access_token |
Authenticate with email and password. Returns a session_token for use in x-mcp-session-token header. Rate limited to 5 attempts per 5 minutes. |
refresh-token |
Refresh the active session before the 4-hour TTL expires. Uses the session stored server-side — no parameters required. |
Things (SIMs & Devices)
| Tool | Description |
|---|---|
list-things |
Paginated list of SIMs. Filter by status (ACTIVATED/SUSPENDED), group, network, tags, iccid, imei, active_identity. |
get-thing |
Full details for a single SIM by ICCID. |
search-things |
Search across the fleet by ICCID, IMEI, or active identity. |
get-thing-configuration |
SIM profile and configuration details. |
get-thing-location |
Last known geographic location of a SIM. |
get-thing-connectivity |
Real-time signal strength and network registration status. |
get-data-session-status |
Current data session information (APN, IP, start time). |
get-lifetime-usage |
Cumulative data usage over the SIM's lifetime. |
get-thing-identity |
Active identity including IMSI slots and PLMN settings. |
get-thing-events |
Signaling and network events for a SIM — useful for troubleshooting. |
get-thing-network-usage |
Data usage breakdown by carrier network (MNO) for a SIM. |
get-thing-tags |
All tags assigned to a specific SIM. |
update-thing |
Update a SIM's name, description, and tags. |
change-thing-status |
Activate or suspend a SIM. |
refresh-thing-connection |
Trigger a network reconnection attempt for a SIM. |
move-thing-group |
Move a SIM to a different group. |
send-thing-sms |
Send an SMS message to a specific SIM. |
send-bulk-sms |
Send an SMS message to multiple SIMs at once (up to 100). |
assign-thing-tag |
Assign a tag to a specific SIM. |
unassign-thing-tag |
Remove a tag from a specific SIM. |
start-qos-test |
Start a Quality of Service (QoS) test for a SIM. |
get-qos-test |
Get the status and results of a QoS test. |
Orders & Procurement
| Tool | Description |
|---|---|
list-orders |
Order history with filters: status, start_time, end_time, sort_by, sort_order (asc/desc). Status values: Draft, Submitted, Awaiting Payment, Pending Verification, Awaiting Fulfillment, Shipping in Process, Completed, Cancelled. |
get-order |
Full invoice and item details for a specific order. |
get-plans |
Available SIM plans and product deals for new orders. |
get-order-tracking |
Shipment tracking and delivery status for an order. |
create-order |
Create a new SIM order. Shipping address fields are required for physical SIMs. |
export-orders |
Export orders data with the same filters as list-orders. |
Campaigns
| Tool | Description |
|---|---|
list-campaigns |
List campaigns with filtering by type (sms/state), status (active/completed/cancelled/draft/scheduled), search, sort_by, and sort_order (asc/desc). |
get-campaign |
Detailed view of a specific campaign including rules and targets. |
get-campaign-progress |
Execution progress and completion percentage. |
get-campaign-things |
Paginated list of SIMs assigned to a campaign. Filter by status (Completed/In Progress). Supports sort_by and sort_order. |
export-campaigns |
Export campaigns asynchronously. Returns a job ID to track export progress. |
Tags
| Tool | Description |
|---|---|
list-tags |
All tags defined in the organisation. |
get-tag |
Details for a specific tag by ID (must begin with TagId_). |
create-tag |
Create a new tag. |
update-tag |
Update an existing tag. |
delete-tag |
Delete a tag by its ID. |
Users
| Tool | Description |
|---|---|
get-current-user |
The authenticated user's profile: ID, email, user type, organisation, and brand. |
list-users |
List users with optional filtering by email. |
get-user |
Get a specific user by their ID. |
get-user-profiles |
Available user profiles/roles. |
create-user |
Create a new user and send them an invitation. |
update-user |
Update an existing user's details. |
activate-user |
Activate a deactivated user account. |
deactivate-user |
Deactivate a user account. |
delete-user |
Delete a user account. |
resend-user-invite |
Resend an invitation email to a user. |
Audit Logs
| Tool | Description |
|---|---|
list-audit-logs |
Audit history with filters: email, url, request_id, status_code, ip_address, start_time, end_time, sort_by (created_at/status_code/duration/method/url), sort_order (asc/desc). Community users see only their own logs. |
Reports
| Tool | Description |
|---|---|
get-data-usage-report |
Historical data usage with optional filters: start_time, end_time, period (today/last_24_hours/yesterday/this_month/last_month/last_30_days/this_quarter/last_quarter), group, profile, network. |
get-insights-report |
Network insights, anomaly detection, and usage trends. |
get-top-groups-report |
Top data-consuming groups in the organisation. |
get-top-identities-report |
Top data-consuming identities (SIM subscriptions). |
get-top-networks-report |
Top networks ranked by traffic volume. |
get-top-consumers-report |
Top data-consuming SIM devices. |
get-active-things-report |
Active device count and activity trends over time. |
get-data-usage-by-thing |
Data usage report for a specific SIM by ICCID. |
get-data-usage-by-group |
Data usage report for a specific group. |
get-data-usage-by-tag |
Data usage report for a specific tag. |
get-payment-reports |
Payment reports with optional filtering. |
download-payment-report |
Download a specific payment report by its ID. |
create-billing-report |
Create a new billing report. |
get-dashboard-groups-filter |
Available group names for use as report filters. |
get-dashboard-networks-filter |
Available network names for use as report filters. |
get-dashboard-profiles-filter |
Available SIM profiles for use as report filters. |
NetFlow Reports
Deep traffic analysis — requires NetFlow data to be enabled on your account.
| Tool | Description |
|---|---|
get-netflow-summary |
Aggregated traffic statistics for a time period. |
get-netflow-top-destinations |
Top destination IPs/hostnames by traffic volume. Filter by iccid, profile, mno_name, group_name, country, breakout. |
get-netflow-data-transfer |
Data transfer volume as a time series. |
get-netflow-services |
Traffic breakdown by application/service (HTTP, DNS, streaming, etc.). |
get-netflow-protocols |
Protocol distribution (TCP, UDP, ICMP, etc.). |
get-netflow-top-things |
Top SIM devices ranked by traffic volume. |
get-netflow-breakout |
Traffic breakdown by breakout type (local, central, roaming). |
get-netflow-tcp-flags |
TCP flag distribution (SYN, ACK, RST, FIN) for connection-level analysis. |
get-netflow-mno-filter |
Available MNO names for use as NetFlow filters. |
get-netflow-country-filter |
Available countries for use as NetFlow filters. |
get-netflow-group-filter |
Available group names for use as NetFlow filters. |
get-netflow-profile-filter |
Available SIM profiles for use as NetFlow filters. |
get-netflow-breakout-filter |
Available breakout types for use as NetFlow filters. |
get-netflow-enriched |
Enriched NetFlow records with cursor-based pagination. Filter by ICCID, Thing ID, IMEI, IMSI, IPs, ports, protocols, direction, classification, country, MNO, APN, SIM group, and TAC. |
get-netflow-networkdiagram-summary |
Aggregated NetFlow summary for network diagram visualisation — shows host-to-host communication patterns with traffic volumes. |
Integrations
| Tool | Description |
|---|---|
list-integrations |
List integrations with optional filtering by type and search term. |
get-integration-event-types |
Available event types for integrations. |
create-integration |
Create a new integration (Email, Webhook, or Zapier). |
update-integration |
Update an existing integration by its ID. |
activate-integration |
Activate an integration by its name. |
deactivate-integration |
Deactivate an integration by its name. |
delete-integration |
Delete an integration by its ID. |
Groups
| Tool | Description |
|---|---|
list-groups |
All groups for the current account. |
Inbox
| Tool | Description |
|---|---|
list-inbox-messages |
List inbox messages with optional filtering by date range and event type. |
get-inbox-event-types |
Available event types for inbox messages. |
Payments
| Tool | Description |
|---|---|
list-payments |
List payments with optional filtering by status, vendor, date, and type. |
get-payment |
Detailed information about a specific payment by its ID. |
get-payment-invoice |
Invoice for a specific payment. |
export-payments |
Export payments data with the same filters as list-payments. |
Packet Capture
| Tool | Description |
|---|---|
create-capture |
Create a new packet capture session for a given IP address and time range. |
get-capture-status |
Status of a specific packet capture by its ID. |
list-captures |
List packet captures with optional filtering by status. |
get-capture |
Detailed information about a specific packet capture. |
delete-capture |
Delete a packet capture by its ID. |
download-capture |
Download the packet capture file. |
Rate Plans
| Tool | Description |
|---|---|
list-rate-plans |
Available rate plans with pagination. |
SIM Profiles
| Tool | Description |
|---|---|
generate-sim-profile |
Generate a SoftSIM profile for a SIM via the Nordic provider. |
get-sim-profile-task |
Status of a SIM profile generation task. |
download-sim-profile |
Download a generated SIM profile. |
get-esim-profile |
eSIM profile for a SIM by its ICCID. |
cancel-esim |
Cancel an eSIM profile for a SIM. Requires the matching ID from the eSIM profile. |
download-esim |
Download eSIM profile information for a SIM by its ICCID. |
Rate Limits
| Scope | Limit | Key |
|---|---|---|
| General MCP requests | 60 requests / 60 seconds | Per client IP |
access_token tool |
5 attempts / 5 minutes | Per account (email) |
Rate limit headers are returned on every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
When exceeded, the server returns HTTP 429 with a JSON-RPC error body:
{
"jsonrpc": "2.0",
"id": null,
"error": {
"code": -32000,
"message": "Too many requests. Please try again later.",
"data": { "retry_after": 45 }
}
}
Read the data.retry_after value and wait that many seconds before retrying.
Error Reference
HTTP-level errors
| Status | Meaning |
|---|---|
429 |
Rate limit exceeded — read Retry-After header |
503 |
Redis unavailable — MCP server cannot accept requests |
JSON-RPC errors
These appear in the error field of the response:
| Code | Meaning |
|---|---|
-32700 |
Parse error — request body is not valid JSON |
-32600 |
Invalid request — missing jsonrpc or method |
-32601 |
Method not found |
-32602 |
Invalid params — arguments failed schema validation |
-32603 |
Internal error |
-32000 |
Application error (rate limit, Redis failure) |
Tool-level errors
When a tool fails (e.g. auth error, not found), the response uses isError: true in the result rather than the error field. The content array contains the error detail as JSON text:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [{
"type": "text",
"text": "{\"error\":true,\"status_code\":401,\"message\":\"Authentication required. Please call the access_token tool first.\"}"
}],
"isError": true
}
}
This distinction matters: JSON-RPC errors (error field) are protocol failures; tool errors (isError: true in result) are application-level failures from the tool itself.
Related Guides
- Authentication — Obtain a Bearer token for pre-authenticated MCP clients
- Rate Limits — General rate limiting behaviour and retry strategies
- Error Reference — REST API error format (separate from MCP JSON-RPC errors)