npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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

MCP Compatible npm version

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_fields projection 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:

  1. Carbon Voice API Key - Contact the Carbon Voice development team to request your API key:

  2. npx Installation - You must have npx installed 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:

  1. 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)

  1. Open Cursor
  2. Go to Cursor Settings > Features > Model Context Protocol
  3. Add a new MCP server configuration:
{
  "mcpServers": {
    "Carbon Voice": {
      "url": "https://mcp.carbonvoice.app"
    }
  }
}
  1. 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:

  1. Open Cursor
  2. Go to Cursor Settings > Features > Model Context Protocol
  3. 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"]
    }
  }
}
  1. Replace "your_api_key_here" with your actual Carbon Voice API key
  2. 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:

  1. Open Claude Desktop and navigate to Search and Tools

  2. Go to Manage Connectors and click "Add custom connector"

  3. Fill in the connector details:

    • Name: Give it a friendly name like "Carbon Voice"
    • Remote MCP Server URL: Enter https://mcp.carbonvoice.app
  4. Save your connector

  5. 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:

  1. Open your Claude Desktop configuration file:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json
  2. 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"]
    }
  }
}
  1. Replace "your_api_key_here" with your actual Carbon Voice API key
  2. 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.com

Naming 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 information
  • debug - Most verbose logging, shows detailed request/response data
  • warn - Only warning and error messages
  • error - 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 messages
  • error.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 language
  • get_message - Retrieve a specific message by ID
  • get_recent_messages - Get the 10 most recent messages with full context
  • create_conversation_message - Send a message to a conversation
  • create_direct_message - Send direct messages to users or groups
  • create_voicememo_message - Create a voice memo from text (spoken via TTS) or from audio at a URL
  • add_attachments_to_message - Add link attachments to existing messages
  • summarize_conversation - Summarise a conversation with an AI Action (needs a prompt_id from list_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 upstream audio_file multipart param is not exposed over MCP, because a JSON-RPC client cannot construct a File. Fetches are constrained: https only (plain http needs the host in AUDIO_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 — see AUDIO_FETCH_* under Audio fetch controls.

Users

  • get_current_user - Who you are acting as, plus your workspace IDs
  • get_user - Retrieve user information by ID
  • search_user - Find a user by phone number or email
  • search_users - Search multiple users by various identifiers

Conversations

  • list_conversations - Get all conversations from the last 6 months, with optional filtering by user_ids/match (applied by the API), plus types and name (case-insensitive substring), which this server applies to the response. A name-filtered response also carries unfiltered_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 match
  • get_conversation - Retrieve conversation details by ID
  • get_conversation_users - Get all users in a conversation

Folders

  • get_root_folders - List root folders for a workspace
  • create_folder - Create new folders
  • get_folder - Retrieve folder information
  • get_folder_with_messages - Get folder with its messages
  • update_folder_name - Rename folders
  • delete_folder - Delete folders (⚠️ destructive operation)
  • move_folder - Move folders between locations
  • move_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/actions
  • run_ai_action - Execute AI actions on messages
  • run_ai_action_for_shared_link - Run AI actions on shared content
  • get_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 counts
  • list_inbox_notifications - List inbox notifications (including the mentions category) 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. Check assigned_to before treating an item as someone's personal commitment
  • list_action_items - List action items in one conversation, folder, or home
  • get_action_item - Get a single action item by ID
  • create_action_item - Create an action item
  • update_action_item - Update title, notes, assignee, or due date
  • set_action_item_status - Move an item between suggested, todo, and done
  • delete_action_item - Permanently delete an action item
  • suggest_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 answered 202, so poll a listing tool with status: "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 build

Pointing 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 path

Claude 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.js

Claude 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 env block — CARBON_VOICE_PAT is shown because it expires and is self-service; CARBON_VOICE_API_KEY behaves the same way. Both grant full access. See the credential comparison further down.

The env block is mandatory — .env is NOT read here. env-cmd only wraps the npm scripts, and scripts/mcp-client.mjs parses .env itself; the server reads plain process.env. An MCP client spawns the process with a minimal environment, so a key that only exists in .env will not be seen.

A missing credential looks like success. Both CARBON_VOICE_PAT and CARBON_VOICE_API_KEY are optional in the config schema and tools/list never 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.log

Add "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_url

The 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:smoke

Walks ~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_PAT instead of CARBON_VOICE_API_KEY where you can — it is sent as Authorization: Bearer cv_pat_..., which is what cv-api's PatTokenStrategy reads:

| | 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:write scopes 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 a cv:read PAT 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-key is suppressed entirely. That matters: cv-api tries api-key before pat-token in 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_KEY is a personal API key, not an OAuth credential. The two transports authenticate differently, and setCarbonVoiceAuthHeader (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 ApiKeyStrategy looks the value up as a TYPE_API_KEY token, 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's env block, 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:http

HTTP transport

npm run dev:http                     # stateful (what production runs)
npm run dev:http:stateless           # fresh server per request

Unauthenticated endpoints for a quick check:

curl localhost:3005/health           # includes upstream API reachability
curl localhost:3005/info
curl localhost:3005/.well-known/oauth-protected-resource

POST / (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_id in 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 budget

Development

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 issues

API Generation

npm run generate:api   # Generate TypeScript types from Carbon Voice API

Running the Server

npm run dev:http       # Start HTTP server in development mode with hot reload
npm run start:http     # Start HTTP server in production mode

Testing 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 Inspector

For stdio transport testing:

  1. Open the generated URL with token (e.g., http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=46bfbd8938955be26da7f2089a8cccb7be57ed570e65d8d2d68e95561ed9b79e)
  2. Set Transport Type: STDIO
  3. Set Command: node
  4. Click Connect
  5. Should see Connected info.

For HTTP transport testing:

  1. Open the generated URL with token
  2. Set Transport Type: Streamable HTTP
  3. Set URL: http://localhost:3005
  4. Click Auth, then Quick Oauth Flow.
  5. Will be redirected to Carbon Voice Auth Page. After Login, Bearer token should be auto added to Authorization Request headers.
  6. Click Connect
  7. 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 develop

Release Bug Fix

# 1. Test your changes
npm run build
npm run mcp:inspector:http

# 2. Release patch version
npm run release:patch

Release 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:minor

Development Tips

  • Use auto:build during development for automatic rebuilding when files change
  • Test both transports with MCP Inspector before releasing
  • Run generate:api when 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

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.