Signalwire Admin
FreeNot checkedA Model Context Protocol server that exposes SignalWire administration operations to AI clients through 15 tools backed by the official @signalwire/sdk REST cli
About
A Model Context Protocol server that exposes SignalWire administration operations to AI clients through 15 tools backed by the official @signalwire/sdk REST client
README
A Model Context Protocol server that exposes
SignalWire administration operations to AI clients over stdio. It lets an MCP-aware
assistant discover, configure, test, and diagnose SignalWire voice, messaging, and
knowledge (Datasphere) resources through 15 tools backed by the official
@signalwire/sdk REST client.
- Transport: stdio
- Runtime: Node.js ≥ 20.19.0 (ESM, TypeScript)
- SDK: pinned to
@signalwire/sdk2.0.5
Tools
The server registers exactly these 15 tools. Mutating tools are gated behind
SIGNALWIRE_MCP_ALLOW_WRITES; they return a blocked envelope when writes are off.
| Tool | Category | Hint | What it does |
|---|---|---|---|
signalwire_find_resources |
Discovery | read-only | Discover phone numbers, Fabric resources, and Datasphere documents |
signalwire_deploy_ai_agent |
Deployment | destructive/idempotent | Create or update a Fabric AI Agent, optionally bind a number |
signalwire_deploy_call_flow_version |
Deployment | destructive | Publish a known version of an existing Call Flow, optionally bind a number |
signalwire_deploy_swml_script |
Deployment | destructive/idempotent | Create or fully replace a managed SWML Script (Calling or Messaging) |
signalwire_connect_webhook |
Deployment | destructive/idempotent | Route a number to externally deployed SWML/cXML at an HTTPS URL |
signalwire_connect_relay_application |
Deployment | destructive/idempotent | Create/update a RELAY registration and connect a number |
signalwire_provision_test_number |
Deployment | — | Purchase one exact number previously returned by discovery |
signalwire_add_knowledge |
Knowledge | — | Add one URL-backed Datasphere document for RAG ingestion |
signalwire_search_knowledge |
Knowledge | read-only | Semantic search over Datasphere documents |
signalwire_run_call_test |
Testing | — | Start one bounded outbound development call that speaks text and hangs up |
signalwire_run_message_test |
Testing | — | Send one text-only development SMS via the Compatibility API |
signalwire_control_call |
Call control | destructive | High-level lifecycle action (end/transfer) on a live test call |
signalwire_exercise_call_feature |
Call control | — | Exercise one non-AI media feature on a live call |
signalwire_control_ai_call |
Call control | destructive | Interact with an AI session running on a live call |
signalwire_diagnose_interaction |
Diagnostics | read-only | Assemble read-only evidence about a past voice call or message |
Requirements
- Node.js ≥ 20.19.0
- pnpm 11 (the project pins
[email protected]) - A SignalWire account with a Space, Project ID, and a scoped API token with the permissions the tools you use require
Configure
All configuration is read from the environment via three required variables and one
optional write-gate flag. Copy .env.example and fill in your values:
SIGNALWIRE_SPACE=example.signalwire.com
SIGNALWIRE_PROJECT_ID=00000000-0000-0000-0000-000000000000
SIGNALWIRE_API_TOKEN=your-scoped-api-token
SIGNALWIRE_MCP_ALLOW_WRITES=false
| Variable | Required | Notes |
|---|---|---|
SIGNALWIRE_SPACE |
yes | Bare hostname (e.g. example.signalwire.com) or an https:// URL containing only that host. Paths, ports, query strings, fragments, and credentials are rejected. |
SIGNALWIRE_PROJECT_ID |
yes | Your SignalWire Project ID (UUID). |
SIGNALWIRE_API_TOKEN |
yes | A scoped API token. Its value is never echoed in output or errors. |
SIGNALWIRE_MCP_ALLOW_WRITES |
no | Literal "true" or "false". Defaults to "false", which blocks every mutating tool. |
At startup the server validates all variables and reports every problem in a single error; it exits nonzero on misconfiguration without printing anything to stdout (stdout is reserved for MCP JSON-RPC frames).
Connect from an MCP client
Point any stdio MCP client (Claude Desktop, Cursor, etc.) at the server. The server is
configured entirely through environment variables, so the two methods below differ only
in command/args.
{
"mcpServers": {
"signalwire-admin-mcp": {
"command": "npx",
"args": ["-y", "@bradsjm/signalwire-admin-mcp@latest"],
"env": {
"SIGNALWIRE_SPACE": "example.signalwire.com",
"SIGNALWIRE_PROJECT_ID": "00000000-0000-0000-0000-000000000000",
"SIGNALWIRE_API_TOKEN": "your-scoped-api-token",
"SIGNALWIRE_MCP_ALLOW_WRITES": "false"
}
}
}
}
From a local build
Clone the repo and build the TypeScript to dist/:
pnpm install
pnpm build
Then point the client at the built entry point:
{
"mcpServers": {
"signalwire-admin-mcp": {
"command": "node",
"args": ["/absolute/path/to/signalwire-admin-mcp/dist/index.js"],
"env": {
"SIGNALWIRE_SPACE": "example.signalwire.com",
"SIGNALWIRE_PROJECT_ID": "00000000-0000-0000-0000-000000000000",
"SIGNALWIRE_API_TOKEN": "your-scoped-api-token",
"SIGNALWIRE_MCP_ALLOW_WRITES": "false"
}
}
}
}
Result envelope
Every tool returns the same strict result envelope as structuredContent (and as
compact JSON in a single text block). The shape is enforced in Zod so it cannot drift
by convention:
{
status: "complete" | "unchanged" | "accepted" | "partial"
| "confirmation_required" | "blocked" | "not_found"
| "unsupported" | "error",
summary: string, // 1–1000 chars
resource_id?: string, // primary durable resource affected
call_id?: string, // voice test correlation
message_sid?: string, // SMS test correlation
control_id?: string, // for stopping a started media feature
platform_status?: string, // latest platform-reported status
safe_to_retry?: boolean, // may the caller repeat after a partial?
next_step?: string, // concrete next action when relevant
resources?: Resource[], // durable read-back (≤ 20)
items?: Item[], // discovery / search results (≤ 20)
operations?: Operation[], // per-invocation journal (≤ 20)
evidence?: Evidence[], // observed facts (≤ 20)
inferences?: Inference[], // reasoned conclusions + confidence (≤ 20)
unknowns?: string[], // gaps and uncertainties (≤ 20)
error?: Error, // sanitized failure detail (error status only)
}
Status-dependent invariants are enforced: error requires error, accepted
requires a correlation id, confirmation_required/blocked/not_found/unsupported
require next_step, and partial requires a non-empty operations journal and
safe_to_retry.
Safety model
- Write gate.
SIGNALWIRE_MCP_ALLOW_WRITES=false(the default) blocks every mutating tool; they returnblockedwith anext_steprather than touching state. - Version-locked capability registry.
src/signalwire/capabilities.tsis the sole, auditable mapping from each tool/action to the pinned SDK methods it uses. Operations absent from the registry are unsupported — there is no raw-HTTP escape hatch. - Bounded I/O. Each tool has a strict Zod input schema and only projects bounded, contract-defined fields into output.
- Secret redaction. Sensitive keys (
token,authorization,secret,api_key,signed_url, …) are recursively scrubbed to[redacted]before any value reaches output. The API token is never echoed. - Channel discipline. stdout carries only MCP frames; sanitized audit lines (tool name, elapsed ms, outcome status — no argument values) go to stderr.
Development
pnpm install # install dependencies
pnpm build # tsc -> dist/, makes dist/index.js executable
pnpm dev # run src/index.ts directly via tsx
pnpm start # run the built dist/index.js
pnpm typecheck # tsc --noEmit
pnpm test # build, then run the vitest suite
Project layout
src/
index.ts executable entry point (stdio bootstrap)
server.ts MCP server factory; registers all 15 tools
config.ts environment loading + validation
signalwire/
client.ts sole RestClient boundary (constructs the SDK client)
capabilities.ts version-locked capability registry
core/
output.ts strict result envelope + finalization/redaction
schemas.ts bounded string schemas
redaction.ts secret scrubbing + sanitized audit logging
errors.ts error classification/normalization
tools/
contracts.ts every tool input schema + result parser
runtime.ts shared orchestration (write gate, executeTool)
inventory.ts deployment.ts knowledge.ts
testing.ts call-control.ts diagnostics.ts
tests/
server-contract.test.ts stdio.test.ts
sdk-compositions.test.ts helpers.ts
License
MIT License. See LICENSE.
Installing Signalwire Admin
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/bradsjm/signalwire-admin-mcpFAQ
Is Signalwire Admin MCP free?
Yes, Signalwire Admin MCP is free — one-click install via Unyly at no cost.
Does Signalwire Admin need an API key?
No, Signalwire Admin runs without API keys or environment variables.
Is Signalwire Admin hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Signalwire Admin in Claude Desktop, Claude Code or Cursor?
Open Signalwire Admin on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
by modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
by xuzexin-hzCompare Signalwire Admin with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All ai MCPs
