MCP server
The Nexafon MCP server (@nexafon/mcp) lets an AI coding agent read these docs and the example apps while it writes
your integration, and, with a test secret key, send a test message and look at your webhook deliveries and recent
errors. It speaks the Model Context Protocol over stdio, so it works in Claude Code
and any other MCP client that starts local servers.
It pairs with the Nexafon agent skill, which teaches the agent the integration steps and rules,
and the CLI, which scaffolds the integration and checks it with nexafon doctor.
| Tool | Needs | What it does |
|---|---|---|
search_docs(query, limit?) |
Searches these docs; each result has the page title, its URL and a snippet | |
get_page(path) |
Returns a page as Markdown, the same text as its .md twin (/v1/quickstart/ or /v1/quickstart.md) |
|
get_example(name, file?) |
Lists the files of an example app (react, next, partner, …) with its README, or returns one file |
|
send_test_message(to, text) |
test key | Sends a text to a customer through sendMessage in test mode |
list_webhook_deliveries(limit?, endpointId?, status?) |
test key | The latest delivery attempts across your webhook endpoints, the newest first |
recent_errors(limit?) |
test key | Failed webhook deliveries, failing or turned-off endpoints, and outbound messages WhatsApp did not accept |
The docs and the examples are bundled into the package when it is built, so the first three tools work offline and
match the version you installed. Links in their answers point at NEXAFON_DOCS_URL.
- There is no separate test-send operation.
send_test_messagecalls the documented send-message operation with your test key, so test mode applies: a real WhatsApp number answerstest_mode_liveunless the workspace has a WhatsApp test number. The customer must have written within the last 24 hours; a new conversation starts with a template. recent_errorsreports what the public API exposes. The API keeps no log of failed requests: those come back to your own code as Problem Details.get_exampleserves only the files committed underexamples/<name>, and never a.envfile (the.env.exampletemplates are included).
Settings
Section titled “Settings”The server reads its settings from its environment:
| Variable | |
|---|---|
NEXAFON_DOCS_URL |
Required. The docs site, https://docs.nexafone.so, for the links in results |
NEXAFON_API_URL |
The API, https://api.nexafone.so; needed by the test-key tools. https, or http only to localhost, 127.0.0.1 or a *.localhost name, since the key is sent there. Against a local Nexafon stack use its API_URL unchanged: the server sends *.localhost names to 127.0.0.1 itself (macOS does not resolve them for Node), with the Host header the stack routes by |
NEXAFON_SECRET_KEY |
A test secret key (sk_test_…) with the inbox:reply and developers:manage scopes; needed by the test-key tools |
NEXAFON_WORKSPACE_ID |
The key’s workspace id: the {workspaceId} in API paths, also sent as workspaceId in every webhook delivery |
NEXAFON_APP_URL, NEXAFON_EMBED_CDN_URL |
Optional: fill in the dashboard and SDK loader URLs in the pages the server returns |
Claude Code
Section titled “Claude Code”@nexafon/mcp is not on npm yet, so npx -y @nexafon/[email protected] fails for now. Until it is published, build it in a
checkout of the repo (pnpm install, then pnpm --filter @nexafon/mcp build) and start it with node. Add the server
to a project, so everyone working on it gets the tools, with the key and workspace id read from each developer’s own
environment:
claude mcp add nexafon --scope project \ --env NEXAFON_DOCS_URL=https://docs.nexafone.so \ --env NEXAFON_API_URL=https://api.nexafone.so \ --env 'NEXAFON_WORKSPACE_ID=${NEXAFON_WORKSPACE_ID:-}' \ --env 'NEXAFON_SECRET_KEY=${NEXAFON_SECRET_KEY:-}' \ -- node /path/to/nexafon/mcp/dist/bin.jsThat writes .mcp.json at the project root. Claude Code fills in ${…} from the environment it starts in; a variable
that is not set becomes empty (:-), which leaves the test-key tools off and the docs tools working:
{ "mcpServers": { "nexafon": { "command": "node", "args": ["/path/to/nexafon/mcp/dist/bin.js"], "env": { "NEXAFON_DOCS_URL": "https://docs.nexafone.so", "NEXAFON_API_URL": "https://api.nexafone.so", "NEXAFON_WORKSPACE_ID": "${NEXAFON_WORKSPACE_ID:-}", "NEXAFON_SECRET_KEY": "${NEXAFON_SECRET_KEY:-}" } } }}After the release, replace node /path/to/nexafon/mcp/dist/bin.js with npx -y @nexafon/[email protected] (in the JSON,
"command": "npx" and "args": ["-y", "@nexafon/[email protected]"]). Run /mcp in Claude Code to see the server and its
tools.
Other MCP clients
Section titled “Other MCP clients”Any client that starts stdio servers runs it the same way: the command node /path/to/nexafon/mcp/dist/bin.js (after
the release, npx -y @nexafon/[email protected]) with the variables above in its environment. Cursor reads the same
mcpServers object from .cursor/mcp.json, and Claude Desktop from its claude_desktop_config.json. Where a client
cannot read a variable from your environment, put the test key in its user-level config, never in a file you commit.