@@ -17,11 +17,10 @@ cd mcp-server
1717### Prerequisites
1818
1919In order to use the Bandwidth MCP Server, you'll need the following things, set as environment variables.
20- - Valid Bandwidth API Credentials
21- - This will be the username and password of your Bandwidth API user
20+ - Valid Bandwidth OAuth2 Client Credentials
21+ - You will need a client ID and client secret for your Bandwidth API application
2222 - For more info on creating API credentials, see our [ Credentials] ( https://dev.bandwidth.com/docs/credentials ) page
23- - Bandwidth Account ID
24- - The ID of the account you'd like to make API calls on behalf of
23+ - Your account ID is auto-discovered from JWT claims after authentication — you do not need to provide it
2524
2625### Configuration
2726
@@ -33,19 +32,24 @@ The server will respect both system environment variables and those configured v
3332The following variables will be required to use the server:
3433
3534``` sh
36- BW_USERNAME # Your Bandwidth API User Username
37- BW_PASSWORD # Your Bandwidth API User Password
35+ BW_CLIENT_ID # Your Bandwidth OAuth2 client ID
36+ BW_CLIENT_SECRET # Your Bandwidth OAuth2 client secret
3837```
3938
4039The following variables are optional or conditionally required:
4140
4241``` sh
43- BW_ACCOUNT_ID # Your Bandwidth Account ID. Required for most API operations.
44- BW_NUMBER # A valid phone number on your Bandwidth account. Used with our Messaging and MFA APIs. Must be in E164 format.
45- BW_MESSAGING_APPLICATION_ID # A Bandwidth Messaging Application ID. Used with our Messaging and MFA APIs.
46- BW_VOICE_APPLICATION_ID # A Bandwidth Voice Application ID. Used with our MFA API.
47- BW_MCP_TOOLS # The list of MCP tools you'd like to enable. If not set, all tools are enabled.
48- BW_MCP_EXCLUDE_TOOLS # The list of MCP tools you'd like to exclude. Takes priority over BW_MCP_TOOLS.
42+ BW_ACCOUNT_ID # Your Bandwidth Account ID. Optional — auto-discovered from JWT claims after authentication.
43+ BW_NUMBER # A valid phone number on your Bandwidth account. Used with our Messaging API. Must be in E164 format.
44+ BW_MESSAGING_APPLICATION_ID # A Bandwidth Messaging Application ID. Used with our Messaging API.
45+ BW_VOICE_APPLICATION_ID # A Bandwidth Voice Application ID. Used to auto-configure voice callbacks in hosted mode.
46+ BW_MCP_PROFILE # Named tool preset (voice, messaging, lookup, onboarding, recordings, full). Comma-separated to combine.
47+ BW_MCP_TOOLS # Explicit tool allowlist (comma-separated operationIds). Overrides BW_MCP_PROFILE.
48+ BW_MCP_EXCLUDE_TOOLS # Explicit tool denylist (comma-separated). Takes priority over BW_MCP_TOOLS and profiles.
49+ BW_ENVIRONMENT # `test` or `uat` to target Bandwidth's test environment. Defaults to prod.
50+ BW_API_URL # API gateway override. Also serves the Dashboard XML API under /api/v2.
51+ BW_VOICE_URL # Voice API base override.
52+ BW_MESSAGING_URL # Messaging API base override.
4953```
5054
5155#### Including or Excluding Tools
@@ -85,6 +89,14 @@ BW_MCP_EXCLUDE_TOOLS=createLookup,getLookupStatus
8589--exclude-tools createLookup,getLookupStatus
8690```
8791
92+ ** Account Creation Flow (Build Registration)**
93+
94+ Bandwidth Build is the free voice-first trial. Use this profile when the user has no credentials yet. The MCP only exposes ` createRegistration ` to kick things off — SMS verification, password set, and API credential generation all happen in pages Bandwidth links the user to. The agent shouldn't try to consume the SMS code over the API; it belongs to the user's browser flow.
95+
96+ ``` sh
97+ BW_MCP_TOOLS=createRegistration
98+ ```
99+
88100## Using the Server
89101
90102Below you'll find instructions for using our MCP server with different common AI agents, as well as instructions for running the server locally. For usage with AI agents, it is recommended to use a combination of [ uv] ( https://github.com/astral-sh/uv?tab=readme-ov-file#uv ) and environment variables to start and configure the server respectively.
@@ -131,8 +143,8 @@ Then follow the prompts like the example below.
131143 "command" :" uvx" ,
132144 "args" : [" --from" , " /path/to/mcp-server" , " start" ],
133145 "env" : {
134- "BW_USERNAME " : " <insert-bw-username >" ,
135- "BW_PASSWORD " : " <insert-bw-password >" ,
146+ "BW_CLIENT_ID " : " <insert-bw-client-id >" ,
147+ "BW_CLIENT_SECRET " : " <insert-bw-client-secret >" ,
136148 "BW_MCP_TOOLS" : " tools,to,enable" ,
137149 "BW_MCP_EXCLUDE_TOOLS" : " tools,to,exclude" ,
138150 }
@@ -161,8 +173,8 @@ uvx --from /path/to/mcp-server start
161173 "command" : " uvx" ,
162174 "args" : [" --from" , " /path/to/mcp-server" , " start" ],
163175 "env" : {
164- "BW_USERNAME " : " <insert-bw-username >" ,
165- "BW_PASSWORD " : " <insert-bw-password >" ,
176+ "BW_CLIENT_ID " : " <insert-bw-client-id >" ,
177+ "BW_CLIENT_SECRET " : " <insert-bw-client-secret >" ,
166178 "BW_MCP_TOOLS" : " tools,to,enable" ,
167179 "BW_MCP_EXCLUDE_TOOLS" : " tools,to,exclude" ,
168180 }
@@ -186,8 +198,8 @@ uvx --from /path/to/mcp-server start
186198 "command" : " uvx" ,
187199 "args" : [" --from" , " /path/to/mcp-server" , " start" ],
188200 "env" : {
189- "BW_USERNAME " : " <insert-bw-username >" ,
190- "BW_PASSWORD " : " <insert-bw-password >" ,
201+ "BW_CLIENT_ID " : " <insert-bw-client-id >" ,
202+ "BW_CLIENT_SECRET " : " <insert-bw-client-secret >" ,
191203 "BW_MCP_TOOLS" : " tools,to,enable" ,
192204 "BW_MCP_EXCLUDE_TOOLS" : " tools,to,exclude" ,
193205 }
@@ -212,11 +224,11 @@ Once these are installed, create a virtual environment using:
212224python -m venv .venv
213225```
214226
215- Then activate and install the required packaged from the ` requirements.txt ` file .
227+ Then activate and install the project with its dependencies .
216228
217229``` sh
218230source .venv/bin/activate
219- pip install -r requirements.txt
231+ pip install .
220232```
221233
222234After all packages are installed in the virtual environment, you can run the server locally using:
@@ -234,68 +246,104 @@ then you can start the server by running the following command from the root dir
234246uvx --from ./ start
235247```
236248
249+ ## Hosted Mode
250+
251+ Run the server over HTTP to enable remote access and webhook callbacks:
252+
253+ ``` bash
254+ BW_MCP_TRANSPORT=streamable-http \
255+ BW_MCP_PORT=8080 \
256+ BW_MCP_BASE_URL=https://your-server.example.com \
257+ BW_CLIENT_ID=your_client_id \
258+ BW_CLIENT_SECRET=your_client_secret \
259+ python src/app.py
260+ ```
261+
262+ ### Local Callback Tunnel (dev only)
263+
264+ Voice and messaging callbacks need Bandwidth to reach your server over a public
265+ URL. In production you set ` BW_MCP_BASE_URL ` . For local development, set
266+ ` BW_MCP_DEV_TUNNEL=1 ` and the server will open an ephemeral
267+ [ ` cloudflared ` ] ( https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/ )
268+ tunnel, use the resulting ` *.trycloudflare.com ` URL as ` BW_MCP_BASE_URL ` , and
269+ auto-wire your voice app's callbacks to it — no ngrok needed.
270+
271+ ``` bash
272+ BW_MCP_TRANSPORT=streamable-http \
273+ BW_MCP_DEV_TUNNEL=1 \
274+ BW_CLIENT_ID=your_client_id \
275+ BW_CLIENT_SECRET=your_client_secret \
276+ python src/app.py
277+ ```
278+
279+ Requires ` cloudflared ` on your PATH (` brew install cloudflared ` on macOS). If
280+ it's missing, the server logs a warning and starts without a tunnel. This is
281+ for ** development and testing only** — production deployments should use a real
282+ host via ` BW_MCP_BASE_URL ` . The tunnel never starts unless ` BW_MCP_DEV_TUNNEL `
283+ is set.
284+
285+ ### Tool Profiles
286+
287+ Reduce context window pressure with named presets:
288+
289+ ``` bash
290+ BW_MCP_PROFILE=messaging # SMS/MMS tools only
291+ BW_MCP_PROFILE=voice # Voice + BXML tools
292+ BW_MCP_PROFILE=onboarding # Account creation
293+ BW_MCP_PROFILE=lookup # Number intelligence
294+ BW_MCP_PROFILE=messaging,voice # Combine profiles
295+ ```
296+
297+ Profiles set via ` BW_MCP_PROFILE ` env var or ` --profile ` CLI flag. Use ` BW_MCP_TOOLS ` to override with specific tool names.
298+
237299## Tools List
238300
239- ## ** Multi-Factor Authentication (MFA)**
240- - ` generateMessagingCode ` - Send MFA code via SMS
241- - ` generateVoiceCode ` - Send MFA code via voice call
242- - ` verifyCode ` - Verify a previously sent MFA code
243-
244- ## ** Phone Number Lookup**
245- - ` createLookup ` - Create a phone number lookup request
246- - ` getLookupStatus ` - Get status of an existing lookup request
247-
248- ## ** Voice & Call Management**
249- - ` listCalls ` - Returns a list of call events with filtering options
250- - ` listCall ` - Returns details for a single call event
251-
252- ## ** Reporting & Analytics**
253- - ` getReports ` - Get history of created reports
254- - ` createReport ` - Create a new report instance
255- - ` getReportStatus ` - Get status of a report
256- - ` getReportFile ` - Download report file
257- - ` getReportDefinitions ` - Get available report definitions
258-
259- ## ** Media Management**
260- - ` listMedia ` - List your media files
261- - ` getMedia ` - Download a specific media file
262- - ` uploadMedia ` - Upload a media file
263- - ` deleteMedia ` - Delete a media file
264-
265- ## ** Messaging**
266- - ` listMessages ` - List messages with filtering options
267- - ` createMessage ` - Send SMS/MMS messages
268- - ` createMultiChannelMessage ` - Send multi-channel messages (RBM, SMS, MMS)
269-
270- ## ** Address Management**
271- - ` getAddressFields ` - Get supported address fields by country
272- - ` validateAddress ` - Validate an address and get excluded features
273- - ` listAddresses ` - List all addresses
274- - ` createAddress ` - Create an address
275- - ` getAddress ` - Get an address by ID
276- - ` updateAddress ` - Update an address
277- - ` listCityInfo ` - List city info search results
278-
279- ## ** Compliance**
280- - ` listDocumentTypes ` - List all accepted document types and metadata requirements
281- - ` listEndUserTypes ` - List all End user types and accepted metadata
282- - ` listEndUserActivationRequirements ` - List requirements for End user activation
283- - ` getComplianceDocumentMetadata ` - Get metadata of uploaded documents
284- - ` updateComplianceDocument ` - Modify document data and file
285- - ` downloadComplianceDocuments ` - Download document using document ID
286- - ` createComplianceDocument ` - Upload a document with metadata
287- - ` listComplianceEndUsers ` - List all End users of an account
288- - ` createComplianceEndUser ` - Create an End user
289- - ` getComplianceEndUser ` - Retrieve an End User by ID
290- - ` updateComplianceEndUser ` - Update End user details
291-
292- ## ** Requirements Packages**
293- - ` listRequirementsPackages ` - List all requirements packages
294- - ` createRequirementsPackage ` - Create a requirements package
295- - ` getRequirementsPackage ` - Retrieve a requirements package
296- - ` patchRequirementsPackage ` - Update Requirements package
297- - ` getRequirementsPackageAssets ` - Get assets attached to requirements package
298- - ` attachRequirementsPackageAsset ` - Attach an asset to requirements package
299- - ` detachRequirementsPackageAsset ` - Detach an asset from requirements package
300- - ` validateNumberActivation ` - Validate number activation requirements
301- - ` getRequirementsPackageHistory ` - Get history of a requirements package
301+ Tools are grouped into profiles that mirror the workflows you'd use the server for.
302+ Loading a single profile keeps your agent's context small. The full agent reference
303+ — including auth model, error codes, and the "trust nothing" guidance for async
304+ calls — lives in [ ` src/specs/AGENTS.md ` ] ( src/specs/AGENTS.md ) .
305+
306+ The default tool set is ` voice ` + ` messaging ` + ` lookup ` (plus
307+ ` setCredentials ` / ` clearCredentials ` , always loaded). Override with
308+ ` BW_MCP_PROFILE ` , ` BW_MCP_TOOLS ` , or ` BW_MCP_EXCLUDE_TOOLS ` .
309+
310+ ### Session management (always loaded)
311+ - ` setCredentials ` — authenticate the session (stdio transport only)
312+ - ` clearCredentials ` — log out of the session
313+
314+ ### Profile: ` onboarding ` (no auth required)
315+ Kicks off a new Bandwidth Build account. Only one tool is exposed — SMS verification, password set, and API credential generation all happen in the user's browser. The agent hands off after the kickoff.
316+ - ` createRegistration ` — submit contact details; Bandwidth then SMSes an OTP and emails a password-set link
317+
318+ ### Profile: ` voice `
319+ - ` listApplications ` / ` createApplication ` — find or create a voice app
320+ - ` listPhoneNumbers ` — find numbers on the account
321+ - ` createCall ` — place an outbound call
322+ - ` getCallState ` — read current call state (always poll after ` createCall ` )
323+ - ` listCalls ` — list call events with filtering
324+ - ` updateCall ` / ` updateCallBxml ` — redirect, hang up, or replace BXML
325+ - ` generateBXML ` — build valid BXML from a verb list
326+ - ` respondToCallback ` — queue a BXML response for an active callback (first-write-wins)
327+ - ` getCallbackEvents ` — read recent voice / messaging callback events
328+ - ` configureCallbacks ` — point an application's webhook URLs at this server
329+
330+ ### Profile: ` messaging `
331+ - ` createMessage ` — send SMS / MMS
332+ - ` listMessages ` — query message history
333+ - ` getInboundMessages ` — read inbound messages captured by this server
334+ - ` listMedia ` / ` getMedia ` / ` uploadMedia ` / ` deleteMedia ` — manage MMS media
335+ - ` configureCallbacks ` — point an application's callbacks at this server
336+
337+ ### Profile: ` lookup `
338+ - ` createSyncLookup ` — one-shot lookup for a small input set
339+ - ` createAsyncBulkLookup ` — kick off a bulk lookup
340+ - ` getAsyncBulkLookup ` — poll a bulk lookup
341+
342+ ### Profile: ` recordings `
343+ - ` listCallRecordings ` / ` getCallRecording ` — list / inspect recordings
344+ - ` downloadCallRecording ` — download the media
345+ - ` deleteRecording ` — remove a recording
346+ - ` transcribeCallRecording ` / ` getRecordingTranscription ` — request and read transcription
347+
348+ See [ ` src/specs/AGENTS.md ` ] ( src/specs/AGENTS.md ) for argument-level guidance, polling
349+ patterns, and the structured error shape the server returns on failure.
0 commit comments