@carbonvoice/cv-mcp-server
v2.12.0
Published
Server implementation for integrating with Carbon Voice's API, providing tools and endpoints for voice messaging, conversations, and workspace management through MCP (Model Context Protocol)
Readme
Carbon Voice MCP Server
A Model Context Protocol (MCP) server implementation for integrating with Carbon Voice's API, providing AI assistants with comprehensive tools for voice messaging, conversations, and workspace management.
Carbon Voice: https://getcarbon.app
API: https://api.carbonvoice.app/docs
Features
- Message Management: Create, list, and retrieve voice messages, conversation messages, and direct messages
- User Operations: Search and retrieve user information
- Conversation Management: Access and manage conversations and their participants
- Folder Operations: Create, organize, move, and manage folders and their contents
- Workspace Administration: Get workspace information
- AI Actions: Run AI prompts and retrieve AI-generated responses
- Action Items: Create, assign, and track action items, including AI extraction from messages
- Search & Notifications: Find messages by notified or heard state, and read the inbox with its unread count
- Message Share Links: Create and look up shareable links to messages
- Attachment Support: Add link attachments to messages
- Response Narrowing: An optional
response_fieldsprojection on most read tools, to keep unwanted payload out of the agent's context
Security & Compliance
This server fully complies with MCP Security Best Practices:
- OAuth 2.1 Authentication: Secure authorization flow with proper token handling
- HTTPS Enforcement: All remote endpoints served over HTTPS
- Session Security: Cryptographically secure session management
- Input Validation: Comprehensive validation of all user inputs
- Rate Limiting: Built-in protection against abuse
For security concerns, please contact: [email protected]
Prerequisites
For Stdio Transport (Local Installation)
Required:
Carbon Voice API Key - Contact the Carbon Voice development team to request your API key:
- 📧 Contact: [email protected]
- 📧 Subject: "Request API key for MCP Server"
npx Installation - You must have
npxinstalled on your system. npx comes bundled with Node.js (version 14.8.0 or later). If you don't have Node.js installed, you can download it from nodejs.org.To verify your installation, run:
npx --version
For HTTP Transport (Remote)
Required:
- Nothing! - No additional prerequisites are required. The HTTP transport version runs entirely in the cloud and uses OAuth2 authentication, so you don't need an API key or npx installed.
Configuration
Quick Overview
| Client | HTTP Transport (Remote) | Stdio Transport (Local) | | ------------------ | ----------------------- | ----------------------- | | Cursor | ✅ Recommended | ✅ Available | | Claude Desktop | ✅ Recommended | ✅ Available |
HTTP Transport is recommended for easier setup and enhanced security.
For Cursor
HTTP Transport (Remote)
- Open Cursor
- Go to Cursor Settings > Features > Model Context Protocol
- Add a new MCP server configuration:
{
"mcpServers": {
"Carbon Voice": {
"url": "https://mcp.carbonvoice.app"
}
}
}- Save and restart Cursor
The first time you use it, Cursor will guide you through the OAuth2 authentication process.
Stdio Transport (Local Installation)
If you prefer to run the MCP server locally with API key authentication:
- Open Cursor
- Go to Cursor Settings > Features > Model Context Protocol
- Add a new MCP server configuration:
{
"mcpServers": {
"Carbon Voice": {
"command": "npx",
"env": {
"CARBON_VOICE_API_KEY": "your_api_key_here"
},
"args": ["-y", "@carbonvoice/cv-mcp-server"]
}
}
}- Replace
"your_api_key_here"with your actual Carbon Voice API key - Save and restart Cursor
For Claude Desktop
HTTP Transport (Remote)
Setting up Carbon Voice in Claude Desktop is straightforward! Here's how to do it:
Open Claude Desktop and navigate to Search and Tools
Go to Manage Connectors and click "Add custom connector"
Fill in the connector details:
- Name: Give it a friendly name like "Carbon Voice"
- Remote MCP Server URL: Enter
https://mcp.carbonvoice.app
Save your connector
Click Connect:
The first time you use it, Claude will guide you through the OAuth2 authentication process. You'll just need to sign in with your Carbon Voice account and grant permissions. After that, you're all set!
Stdio Transport (Local Installation)
If you prefer to run the MCP server locally with API key authentication:
Open your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
Add the Carbon Voice MCP server configuration:
{
"mcpServers": {
"Carbon-Voice": {
"command": "npx",
"env": {
"CARBON_VOICE_API_KEY": "your_api_key_here"
},
"args": ["-y", "@carbonvoice/cv-mcp-server"]
}
}
}- Replace
"your_api_key_here"with your actual Carbon Voice API key - Save the file and restart Claude Desktop
Audio fetch controls (all transports)
These govern create_voicememo_message's audio_url — the one place the server
fetches a URL a caller supplied. They apply to every transport, stdio and
HTTP alike; they are not part of the stdio-only set below.
AUDIO_FETCH_ALLOWED_HOSTS
Comma-separated hostname allowlist. When set, only these hosts (and their
subdomains) may be fetched. Set this in production — it is the strongest
control against the server being used as an SSRF proxy, and the only one that
also narrows the DNS-rebinding window described in src/utils/fetch-audio-file.ts.
When unset, any public host is allowed over https, while private, loopback,
link-local and site-local address space is still refused.
Entries may be hostnames or IP literals; an IPv6 literal works written bare or bracketed.
AUDIO_FETCH_ALLOWED_HOSTS=cdn.example.com,uploads.example.comNaming a host here is also what permits plain http for it. With no allowlist,
only https URLs are accepted.
AUDIO_FETCH_MAX_BYTES
Maximum size of a fetched audio file, in bytes. Defaults to 26214400 (25 MB).
Enforced against both content-length and the bytes actually received, while
streaming — an oversized body is cancelled rather than buffered.
AUDIO_FETCH_TIMEOUT_MS
Timeout for the whole audio_url fetch, in milliseconds. Defaults to 30000.
Bounds DNS resolution as well as the request itself.
AUDIO_FETCH_MAX_CONCURRENT
How many audio_url fetches may be in flight across the whole process.
Defaults to 4; callers beyond it are refused immediately rather than queued.
AUDIO_FETCH_MAX_BYTES caps a single fetch, this caps their sum. The tool-call
queue serializes per session, so without a process-wide budget one caller
using several sessions could hold gigabytes of transient memory — each in-flight
fetch keeps its chunks, the concatenated buffer, and the resulting file alive
until the upstream upload finishes.
Environment Variables (Only available for Stdio Version)
When using the stdio version of the MCP server, you can configure additional environment variables:
LOG_LEVEL
Controls the verbosity of logging output. Available options:
info(default) - Standard logging informationdebug- Most verbose logging, shows detailed request/response datawarn- Only warning and error messageserror- Only error messages
Example:
{
"mcpServers": {
"Carbon-Voice": {
"command": "npx",
"env": {
"CARBON_VOICE_API_KEY": "your_api_key_here",
"LOG_LEVEL": "debug"
},
"args": ["-y", "@carbonvoice/cv-mcp-server"]
}
}
}LOG_DIR
Specifies the directory where log files will be stored. Defaults to: /tmp/cv-mcp-server/logs
The server will create two log files in this directory:
combined.log- Contains all log messageserror.log- Contains only error messages
Example:
{
"mcpServers": {
"Carbon-Voice": {
"command": "npx",
"env": {
"CARBON_VOICE_API_KEY": "your_api_key_here",
"LOG_DIR": "/Users/USER_NAME/Documents/cv-mcp-server/logs"
},
"args": ["-y", "@carbonvoice/cv-mcp-server"]
}
}
}Complete Example with Both Variables:
{
"mcpServers": {
"Carbon-Voice": {
"command": "npx",
"env": {
"CARBON_VOICE_API_KEY": "your_api_key_here",
"LOG_LEVEL": "debug",
"LOG_DIR": "/Users/USER_NAME/Documents/cv-mcp-server/logs"
},
"args": ["-y", "@carbonvoice/cv-mcp-server"]
}
}
}Available Tools
Messages
list_messages- List messages, filtered by date (max 183-day span), conversation, folder, workspace, creator, or languageget_message- Retrieve a specific message by IDget_recent_messages- Get the 10 most recent messages with full contextcreate_conversation_message- Send a message to a conversationcreate_direct_message- Send direct messages to users or groupscreate_voicememo_message- Create a voice memo from text (spoken via TTS) or from audio at a URLadd_attachments_to_message- Add link attachments to existing messagessummarize_conversation- Summarise a conversation with an AI Action (needs aprompt_idfromlist_ai_actions)
Voice memo audio. Pass
audio_url(a public https URL) to upload existing audio; the server fetches it and forwards the bytes. The upstreamaudio_filemultipart param is not exposed over MCP, because a JSON-RPC client cannot construct aFile. Fetches are constrained: https only (plain http needs the host inAUDIO_FETCH_ALLOWED_HOSTS), private/loopback/ link-local/site-local addresses refused, URLs embedding credentials refused, redirects re-validated per hop, plus a size cap and timeout — seeAUDIO_FETCH_*under Audio fetch controls.
Users
get_current_user- Who you are acting as, plus your workspace IDsget_user- Retrieve user information by IDsearch_user- Find a user by phone number or emailsearch_users- Search multiple users by various identifiers
Conversations
list_conversations- Get all conversations from the last 6 months, with optional filtering byuser_ids/match(applied by the API), plustypesandname(case-insensitive substring), which this server applies to the response. Aname-filtered response also carriesunfiltered_count— how many conversations the name was matched against, after the other filters — so an empty result can be told apart from a name that simply did not matchget_conversation- Retrieve conversation details by IDget_conversation_users- Get all users in a conversation
Folders
get_root_folders- List root folders for a workspacecreate_folder- Create new foldersget_folder- Retrieve folder informationget_folder_with_messages- Get folder with its messagesupdate_folder_name- Rename foldersdelete_folder- Delete folders (⚠️ destructive operation)move_folder- Move folders between locationsmove_message_to_folder- Organize messages into folders
Workspace
get_workspaces_basic_info- Get basic workspace information
AI Actions
list_ai_actions- List available AI prompts/actionsrun_ai_action- Execute AI actions on messagesrun_ai_action_for_shared_link- Run AI actions on shared contentget_ai_action_responses- Retrieve AI-generated responses
Search & Notifications
search_message_ids- Find message IDs by notified state, mentions, labels, creator, conversation, or workspace (cursor-paginated, IDs only)search_messages_by_heard_status- Find unheard/heard messages, with per-conversation unheard countslist_inbox_notifications- List inbox notifications (including thementionscategory) with a total unread count
These three call the full Carbon Voice API rather than the simplified surface, since notified state, listened state, and notification records have no simplified-API equivalent.
Action Items
list_my_action_items- Your action items across every conversation and folder: those assigned to you, plus unassigned ones you created. Checkassigned_tobefore treating an item as someone's personal commitmentlist_action_items- List action items in one conversation, folder, or homeget_action_item- Get a single action item by IDcreate_action_item- Create an action itemupdate_action_item- Update title, notes, assignee, or due dateset_action_item_status- Move an item betweensuggested,todo, anddonedelete_action_item- Permanently delete an action itemsuggest_action_items_from_message- Extract action items from ONE message and return them immediately (no polling)suggest_action_items_from_messages- Extract candidate action items from SEVERAL messages using AI. Enqueued and answered202, so poll a listing tool withstatus: "suggested"for the results. Reasons over the whole set at once, so it can catch commitments that span messages
Message Share Links
create_message_share_link- Create a shareable link to a message (returns the URL)get_message_share_link- Look up an existing share link, including its access settings
Narrowing Responses (response_fields)
Most read tools accept an optional response_fields array — a dot-path allowlist
that shrinks the response before it reaches the agent's context. Paths traverse
arrays element-wise, and pagination fields (total, has_next_page, has_more,
next_cursor, …) are always kept so the "is there more?" signal survives. So is
list_conversations's unfiltered_count, for the same reason: a projection that
stripped it would leave an empty result looking like a conversation that does not
exist.
{ "response_fields": ["total", "has_next_page", "results.id", "results.transcript"] }Omitting it returns the full payload unchanged, so existing integrations are
unaffected. Measured on recorded fixtures (npm run measure:payloads):
| Tool | Full | Narrowed |
| --- | --- | --- |
| get_current_user | 8,447 bytes | 2,050 bytes (75.7% smaller) |
| list_messages (20 results) | 21,947 bytes | 4,629 bytes (78.9% smaller) |
Each tool's description suggests a sensible starting set for the common case.
Usage Examples
Getting Started
After configuration, you can interact with Carbon Voice through your AI assistant. Here are some example requests:
"Show me my recent messages"
"Create a voice memo about today's meeting"
"Search for user [email protected]"
"Show me my workspace information"
"List my conversations from this week"Working with Folders
"Create a folder called 'Project Updates'"
"Move message ID 12345 to the Project Updates folder"
"Show me all messages in the Marketing folder"AI Actions
"Run a summary AI action on message ID 67890"
"List all available AI prompts"
"Get AI responses for conversation ID 123"Error Handling
The server includes comprehensive error handling and logging. Errors are returned in a structured format that includes:
- Error messages
- HTTP status codes
- Request context
- Debugging information
Local Testing
cp .env.sample .env # credentials only needed for real tool calls
npm run buildPointing a real client at your local build
To use your branch in Claude Desktop / Cursor / Claude Code instead of the published package, build it and point the client at the built entrypoint by absolute path.
npm run build # produces dist/transports/stdio/stdio.js
pwd # note the absolute pathClaude Code (CLI) — easiest, and scoped to one project:
claude mcp add carbon-voice-dev \
--env CARBON_VOICE_PAT=cv_pat_your_token_here \
-- node /absolute/path/to/cv-mcp-server/dist/transports/stdio/stdio.jsClaude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows).
Cursor — Settings → Features → Model Context Protocol. Same JSON:
{
"mcpServers": {
"carbon-voice-dev": {
"command": "node",
"args": ["/absolute/path/to/cv-mcp-server/dist/transports/stdio/stdio.js"],
"env": {
"CARBON_VOICE_PAT": "cv_pat_your_token_here"
}
}
}
}Restart the client after editing. Name it carbon-voice-dev so it can sit
alongside the published Carbon Voice entry and you can compare the two.
Either credential works in the
envblock —CARBON_VOICE_PATis shown because it expires and is self-service;CARBON_VOICE_API_KEYbehaves the same way. Both grant full access. See the credential comparison further down.
The
envblock is mandatory —.envis NOT read here.env-cmdonly wraps the npm scripts, andscripts/mcp-client.mjsparses.envitself; the server reads plainprocess.env. An MCP client spawns the process with a minimal environment, so a key that only exists in.envwill not be seen.
A missing credential looks like success. Both
CARBON_VOICE_PATandCARBON_VOICE_API_KEYare optional in the config schema andtools/listnever calls the API, so the server connects and shows all 42 tools with no key at all. The failure surfaces only on the first tool call. "It connected" does not mean auth works — make a real call to confirm.
After any code change: npm run build, then restart the client. Clients cache
the tool list per connection, so a reconnect is what picks up new or renamed
tools.
Debugging. Logs default to the file transport at
/tmp/cv-mcp-server/logs/ (combined.log, error.log) — the place to look
when a client reports a server that won't start:
tail -f /tmp/cv-mcp-server/logs/combined.logAdd "LOG_LEVEL": "debug" to the env block for request/response tracing.
Logs go to stderr and files, never stdout, so they cannot corrupt the JSON-RPC
stream.
Driving the server from the terminal
scripts/mcp-client.mjs is a minimal stdio MCP client — the MCP Inspector is a
browser UI, which is no help in a terminal or CI.
npm run mcp:list # every tool with its wire cost
npm run mcp:schema -- get_message # description + input JSON Schema an agent sees
npm run mcp:size # tools/list payload budget
npm run mcp:call -- get_current_user '{"response_fields":["user.user_guid"]}'MCP_DEBUG=1 shows server logs (they go to stderr, so they never corrupt the
JSON-RPC stream on stdout).
list, schema and size need no credentials — the server builds its tool
list without calling out. So does anything the tool's own schema rejects, which
never reaches a handler:
npm run mcp:call -- create_voicememo_message '{"audio_url":"not-a-url"}'
# -> JSON-RPC -32602, "Invalid url" on path audio_urlThe SSRF guard is a different matter. audio_url is only fetched after the
caller is authenticated against cv-api, so a URL like
http://169.254.169.254/ returns 401 before the guard is consulted unless
credentials are configured — with them, it returns INVALID_AUDIO_URL. That
ordering is deliberate: an unauthenticated caller should not be able to make
this server fetch anything at all.
Calls that reach the API need stdio credentials: CARBON_VOICE_PAT
(preferred) or CARBON_VOICE_API_KEY.
Smoke-testing against a real account
cp .env.sample .env # set CARBON_VOICE_PAT (preferred) or CARBON_VOICE_API_KEY
npm run build
npm run mcp:smokeWalks ~19 read-only steps against your live account, chaining IDs the way the
tool descriptions tell an agent to — workspace id, then conversation id, then
message id — so a broken prerequisite shows up as a failed step instead of an
agent quietly guessing. Add --verbose to dump each payload.
Read-only is a property of the script, which calls no create, update or delete
tool — not of the credential. Whatever you put in .env can write; see the
credential comparison above.
Every read is called twice: bare, and with the response_fields set its own
description recommends. The report shows the byte delta per tool and in total,
so the projection claim is measured on your data rather than on a fixture.
It cannot change your account — no tool that creates, updates, moves or deletes is invoked. Write paths are listed at the end with copy-paste commands to run deliberately, one at a time.
Exit code is non-zero if any step fails. When every step fails it prints a diagnosis, because that pattern is nearly always configuration rather than code:
| Note | Cause |
| --- | --- |
| 401 UNAUTHORIZED | no valid CARBON_VOICE_PAT or CARBON_VOICE_API_KEY (see the note below — neither may be an OAuth token) |
| 403 FORBIDDEN | key is valid, but workspace access is refused on SSO grounds |
| NETWORK_ERROR | no route to the API from this machine |
| 405 UNKNOWN_ERROR | an HTTP proxy is intercepting — axios needs a CONNECT tunnel, check HTTPS_PROXY |
Two credential options for stdio, and a PAT is the better one. Set
CARBON_VOICE_PATinstead ofCARBON_VOICE_API_KEYwhere you can — it is sent asAuthorization: Bearer cv_pat_..., which is what cv-api'sPatTokenStrategyreads:| | API key | PAT | | --- | --- | --- | | Access | full user identity | full user identity | | Expiry | long-lived | max 2 years, revocable | | Getting one | email [email protected] | self-service:
POST /pats|A PAT is not a least-privilege credential. It carries
cv:read/cv:writescopes and is issued with both by default, but cv-api enforces them in exactly one place — the app subscribe/unsubscribe endpoints (user-app.service.ts). Nothing in/simplified/*reads them, so acv:readPAT can send messages and delete folders like any other credential. Do not hand one to an untrusted client expecting read-only access. The PAT is better because you can expire and revoke it, not because it is narrower.When both are set the PAT wins and
x-api-keyis suppressed entirely. That matters: cv-api triesapi-keybeforepat-tokenin its strategy chain, so sending both would authenticate the request as the long-lived key rather than the PAT you configured — losing its expiry, its revocability and its identity in the audit trail.Neither is used by the HTTP transport, which authenticates with OAuth.
CARBON_VOICE_API_KEYis a personal API key, not an OAuth credential. The two transports authenticate differently, andsetCarbonVoiceAuthHeader(src/auth/auth.service.ts) sends one or the other, never both:| | API key (stdio) | OAuth (HTTP) | | --- | --- | --- | | Header |
x-api-key: <key>|Authorization: Bearer <access_token>| | Identity | one user, fixed when the key is issued | whoever authorizes your app | | Credential | one long-lived token |client_id+client_secret→ access token |An OAuth access token will not work here: cv-api's
ApiKeyStrategylooks the value up as aTYPE_API_KEYtoken, and an access token is not in that table. (The reverse does work — an API key is accepted in either header, via a documented backward-compatibility fallback.)The key carries your identity with no scoping, so treat it like a password:
.env(gitignored) or a client'senvblock, never a commit.
MCP Inspector
npm run mcp:inspector:stdio # browser UI against the stdio server
npm run dev:http # then: npm run mcp:inspector:httpHTTP transport
npm run dev:http # stateful (what production runs)
npm run dev:http:stateless # fresh server per requestUnauthenticated endpoints for a quick check:
curl localhost:3005/health # includes upstream API reachability
curl localhost:3005/info
curl localhost:3005/.well-known/oauth-protected-resourcePOST / (the MCP endpoint) needs a bearer token carrying the mcp:read and
mcp:write scopes — without one it returns 401, with the wrong scopes
insufficient_scope.
You do not need an OAuth round trip to test the protocol layer. The dev CLI
mints a local token and targets a running HTTP server with --http:
npm run dev:http # in one terminal
npm run mcp:list -- --http # defaults to localhost:3005
npm run mcp:size -- --http http://localhost:3005/
npm run mcp:schema -- --http get_message
npm run mcp:call -- --http get_current_user '{}'This works because createOAuthTokenVerifier (src/auth/auth.service.ts) uses
jwt.decode, not jwt.verify — it requires a decodable JWT with sub,
client_id and the two scopes, and the SDK middleware enforces exp. The
signature is not checked, so the signing secret is irrelevant.
What that covers, and what it does not. Enough for the transport, session
handling, tools/list, schema shape and error envelopes. Not enough for
calls that touch data: the token is forwarded verbatim to cv-api as
Authorization: Bearer <token>, and cv-api does validate it, so a minted token
gets a 401 there. For real data over HTTP, pass a genuine access token:
npm run mcp:call -- --http --token <access_token> get_current_user '{}'For tool-level work against real data, stdio with an API key is simpler — no OAuth flow at all.
Not verifying the signature locally is not an auth bypass: cv-api is the authority, session ids are random UUIDs rather than derived from token claims, and rate limiting is IP-based. A forged token buys only a forged
sub/client_idin this server's logs and session context — worth knowing if you rely on those for attribution.
Tests
npm run test:unit # fast, no network
npm run test:e2e # HTTP transport
npm run test:coverage
npm run measure:payloads # response projection + tools/list budgetDevelopment
This section is for developers who want to contribute, implement new features, or fix issues.
Development Commands
Building and Development
npm run build # Build the project
npm run auto:build # Watch mode with auto-rebuild (recommended for development)
npm run lint:fix # Fix linting issuesAPI Generation
npm run generate:api # Generate TypeScript types from Carbon Voice APIRunning the Server
npm run dev:http # Start HTTP server in development mode with hot reload
npm run start:http # Start HTTP server in production modeTesting with MCP Inspector
Setup: Copy .env.sample to .env and configure your development environment variables.
npm run mcp:inspector:stdio # Test stdio transport with MCP Inspector
npm run mcp:inspector:http # Test HTTP transport with MCP InspectorFor stdio transport testing:
- Open the generated URL with token (e.g.,
http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=46bfbd8938955be26da7f2089a8cccb7be57ed570e65d8d2d68e95561ed9b79e) - Set Transport Type:
STDIO - Set Command:
node - Click Connect
- Should see Connected info.
For HTTP transport testing:
- Open the generated URL with token
- Set Transport Type:
Streamable HTTP - Set URL:
http://localhost:3005 - Click Auth, then Quick Oauth Flow.
- Will be redirected to Carbon Voice Auth Page. After Login, Bearer token should be auto added to Authorization Request headers.
- Click Connect
- Should see Connected info.
Version Management
Note: Only code merged to main branch with a different version from the current one will create a new Git tag and trigger a new npm package release. The CI/CD pipeline automatically checks if the version in package.json has changed before deploying and publishing.
Version Commands
npm run version:patch # Bump patch version (1.0.0 → 1.0.1)
npm run version:minor # Bump minor version (1.0.0 → 1.1.0)
npm run version:major # Bump major version (1.0.0 → 2.0.0)Release Commands
npm run release:patch # Build, test, version patch, and merge to main
npm run release:minor # Build, test, version minor, and merge to main
npm run release:major # Build, test, version major, and merge to main
npm run deploy:release # Build, test, and merge to main (no version bump)Development Workflow Examples
Commit to Develop
# 1. Make your changes and test locally
npm run build
npm run lint:fix
# 2. Commit and push to develop
git add .
git commit -m "feat: add new message filtering feature"
git push origin developRelease Bug Fix
# 1. Test your changes
npm run build
npm run mcp:inspector:http
# 2. Release patch version
npm run release:patchRelease New Feature
# 1. Test your changes
npm run build
npm run mcp:inspector:stdio
npm run mcp:inspector:http
# 2. Release minor version
npm run release:minorDevelopment Tips
- Use
auto:buildduring development for automatic rebuilding when files change - Test both transports with MCP Inspector before releasing
- Run
generate:apiwhen Carbon Voice API changes - Use semantic versioning: patch for fixes, minor for features, major for breaking changes
- Always test with both stdio and HTTP transports before releasing
MCP Compliance
This server is fully compliant with the Model Context Protocol specification and follows all security best practices outlined in the official documentation. The implementation supports both stdio and HTTP transports as defined in the MCP specification.
Support
- Issues: GitHub Issues
- API Key Requests: [email protected]
- Carbon Voice Platform: https://getcarbon.app
- API Documentation: https://api.carbonvoice.app/docs
License
ISC License - See LICENSE file for details.
Note: This MCP server requires a valid Carbon Voice API key to function with stdio transport. For HTTP transport, OAuth2 authentication is handled automatically through the web interface. Please ensure you have the appropriate credentials before attempting to use the server.
