Skip to main content
Glama
MSPbotsAI

oitvoip-mcp

by MSPbotsAI

oitvoip-mcp

MCP server for Oitvoip (hosted VoIP/UCaaS reseller platform, built on NetSapiens — API host pattern is {tenant-pbx-host}/ns-api/). Exposes the NetSapiens ns-api's domain, reseller, device, subscriber, and CDR methods as MCP tools.

Naming note: MSPbots' own integration is registered as "Oitvoip" (subjectCode=NS — short for NetSapiens); the underlying API and all official documentation reference "NetSapiens" / "ns-api". This MCP covers exactly the 5 methods MSPbots itself has configured.

Overview

  • Stateless HTTP service. No credentials are ever persisted — each request supplies its own credentials via headers, used only for the lifetime of that single request.

  • Supports concurrent requests; per-request credential isolation is done via Python contextvars, not a global/shared client instance.

  • Entry points: POST /mcp (MCP protocol) and GET /health (health check).

  • Default port: 8080 (configurable via MCP_HTTP_PORT).

Authentication

NetSapiens uses a standard OAuth2 password grant:

POST https://{site}/ns-api/oauth2/token/
  grant_type=password&client_id=...&client_secret=...&username=...&password=...
-> {"access_token": "...", "expires_in": 3600, "token_type": "Bearer", ...}

The resulting access_token is valid for 1 hour, but this server re-authenticates fresh on every single tool call rather than caching it across MCP requests — nothing is cached or persisted. Every real ns-api call then sends Authorization: Bearer <access_token>.

HEADER 授权参数说明

Header

类型

是否必填

默认值

枚举值

字段描述

Example

X-Oitvoip-Site

string

租户 PBX 主机名(不含协议前缀)

pbx.example.com

X-Oitvoip-Client-Id

string

NetSapiens OAuth2 API Client ID

58900.mspbot

X-Oitvoip-Client-Secret

string

NetSapiens OAuth2 API Client Secret

a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6

X-Oitvoip-Username

string

Subscriber 登录名(含域名后缀)

1000@example

X-Oitvoip-Password

string

对应密码

••••••••

Missing any header returns 401:

{
  "error": "Missing credentials",
  "message": "This server requires the X-Oitvoip-Site, X-Oitvoip-Client-Id, X-Oitvoip-Client-Secret, X-Oitvoip-Username, X-Oitvoip-Password headers",
  "required_headers": ["X-Oitvoip-Site", "X-Oitvoip-Client-Id", "X-Oitvoip-Client-Secret", "X-Oitvoip-Username", "X-Oitvoip-Password"],
  "optional_headers": []
}

An invalid credential or an authenticated-but-under-scoped subscriber account surfaces as a tool-level unauthorized error envelope (message includes the vendor's own detail, e.g. Invalid Scope [APP001]), not an HTTP-level error from this server — see Known Gaps.

Environment Variables

Variable

类型

是否必填

默认值

说明

MCP_HTTP_PORT

int

8080

HTTP 监听端口

MCP_HTTP_HOST

string

0.0.0.0

HTTP 监听地址

MCP Endpoint

  • POST /mcp — MCP protocol (streamable HTTP transport)

  • GET /health — health check, returns {"status": "ok"} (pure local probe, does not call the vendor API)

Tool List

Tool

功能

参数

oitvoip_get_domains

列出该 reseller 账号下所有已开通的域名(租户)

oitvoip_get_resellers

获取指定域名的 reseller 级别详情

domain(必填)

oitvoip_get_devices

列出指定域名下已注册的 SIP 设备/终端

domain(必填)

oitvoip_get_subscribers

列出指定域名下的用户/分机

domain(必填)

oitvoip_get_cdr2

获取指定域名、指定日期范围内的通话详单(CDR)

domainstart_dateend_date(均必填)

Responses are the vendor's JSON (array or object depending on the method), serialized compactly (no indentation, ensure_ascii=False). If a response would exceed ~20,000 characters, the largest list field is truncated and the result includes truncated: true plus the original count, rather than returning an unbounded blob. All 5 tools are read-only (readOnlyHint) — there are no write/delete tools in this service.

On error, tools return a structured JSON error envelope instead of raising:

{"error": {"code": "unauthorized", "message": "...", "retryable": false}}

code is one of not_configured / unauthorized / not_found / invalid_argument / rate_limited / upstream_error; retryable indicates whether the Agent may safely retry (true for rate_limited and upstream_error).

测试示例

# Health check
curl -s http://localhost:8080/health

# Call a tool via the MCP protocol (streamable HTTP) — requires an
# initialize handshake first per the MCP spec; abbreviated example below
# shows the tool-call request body only:
curl -s -X POST http://localhost:8080/mcp \
  -H "X-Oitvoip-Site: pbx.example.com" \
  -H "X-Oitvoip-Client-Id: 58900.mspbot" \
  -H "X-Oitvoip-Client-Secret: <your-client-secret>" \
  -H "X-Oitvoip-Username: 1000@example" \
  -H "X-Oitvoip-Password: <your-password>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: <session-id-from-initialize>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "oitvoip_get_subscribers",
      "arguments": {"domain": "example.58900.service"}
    }
  }'

Live-verified (2026-07-30) against a real tenant, all 5 tools called end-to-end through this running server: oitvoip_get_subscribers returned real subscriber/extension records; oitvoip_get_devices returned real registered SIP devices (Polycom endpoints, live registration state); oitvoip_get_cdr2 returned real call detail records for the given date range. oitvoip_get_domains and oitvoip_get_resellers correctly reached the API and surfaced a clean, expected 401 Invalid Scope [APP001] tool-level error — the provided test credentials are a subscriber-level account (scope: "Office Manager"), which does not carry domain/reseller admin privileges on this particular NetSapiens deployment; see Known Gaps.

API Reference

Known Gaps

  • Scope is exactly MSPbots' 5 configured endpoints, not the vendor's full API surface — ns-api also covers Callqueue, Agent, Phonenumber, Dialplan, Contacts, Presence, Call Queue Report/Stat, real-time Call control, and more (per the public docs' own object list); those are out of scope here.

  • oitvoip_get_domains and oitvoip_get_resellers could not be fully live-verified with real data — the provided test account authenticates successfully (proving the OAuth2 flow and this implementation are correct) but is scoped as a subscriber-level "Office Manager" role, which NetSapiens rejects for these two admin-level objects with 401 Invalid Scope [APP001]. This is a credential-privilege limitation of the specific test account, not a bug in this server — oitvoip_get_ subscribers, oitvoip_get_devices, and oitvoip_get_cdr2 all succeeded with real data using the exact same access token from the exact same login.

  • CDR date range fields (start_date/end_date) are unvalidated strings — passed through to the vendor as-is in YYYY-MM-DD HH:MM:SS format, matching MSPbots' own stored usage; no client-side date parsing is performed.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MSPbotsAI/oitvoip-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server