diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index 484f046..45bf587 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [windows-2025, ubuntu-24.04] - python-version: ['3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] fail-fast: false env: PYTHON_VERSION: ${{ matrix.python-version }} @@ -24,10 +24,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} diff --git a/pyproject.toml b/pyproject.toml index 0c9356f..f68b66b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,8 +9,10 @@ readme = "README.md" requires-python = ">=3.10" dependencies = [ "httpx~=0.28.0", - "fastmcp~=2.11.0", + "fastmcp~=2.13.0", + "mcp~=1.23.0", "pyyaml~=6.0.0", + "werkzeug>=3.1.4" ] [project.scripts] diff --git a/requirements.txt b/requirements.txt index 4adbbdd..5cdecbe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ httpx~=0.28.0 -fastmcp~=2.11.0 +fastmcp~=2.13.0 +mcp~=1.23.0 pyyaml~=6.0.0 +werkzeug>=3.1.4 # not directly required, pinned by Snyk to avoid a vulnerability diff --git a/src/app.py b/src/app.py index 63eb7d6..6d8aae8 100644 --- a/src/app.py +++ b/src/app.py @@ -1,4 +1,8 @@ import asyncio +import os + +os.environ["FASTMCP_EXPERIMENTAL_ENABLE_NEW_OPENAPI_PARSER"] = "true" + from fastmcp import FastMCP from servers import create_bandwidth_mcp from config import load_config, get_enabled_tools, get_excluded_tools diff --git a/src/servers.py b/src/servers.py index 4a5a6a8..f2de360 100644 --- a/src/servers.py +++ b/src/servers.py @@ -16,7 +16,7 @@ "url": "https://dev.bandwidth.com/spec/multi-factor-auth.yml" }, "phone-number-lookup": { - "url": "https://dev.bandwidth.com/spec/phone-number-lookup.yml" + "url": "https://dev.bandwidth.com/spec/phone-number-lookup-v2.yml" }, "insights": {"url": "https://dev.bandwidth.com/spec/insights.yml"}, "end-user-management": { diff --git a/test/fixtures/phone-number-lookup-v2.yml b/test/fixtures/phone-number-lookup-v2.yml new file mode 100644 index 0000000..96ac2be --- /dev/null +++ b/test/fixtures/phone-number-lookup-v2.yml @@ -0,0 +1,724 @@ +openapi: 3.1.0 +info: + title: Phone Number Lookup V2 + version: 2.1.0 + contact: + name: Bandwidth Support + email: support@bandwidth.com + url: https://support.bandwidth.com + termsOfService: https://www.bandwidth.com/legal/terms-of-use-bandwidthcom-web-sites/ + description: >- + A Bandwidth API to provide carrier information for a telephone number or + batch of telephone numbers. + + + Currently supports lookups of telephone numbers in the mainland United + States, Alaska, Hawaii, the District of Columbia and Canada. Canadian + numbers will not provide voice and messaging providers. Telephone numbers + submitted must be in E.164 format to be processed. + + + **PLEASE NOTE**: The NPA-NXX associated with an LRN and/or any derived or + associated carrier information may only be used by non-NPAC users for the + purposes of Rating, Routing, Billing and Network Maintenance as defined in + [NPAC US Permitted Use + Clarifications](https://numberportability.com/about/permitted-use). Any + other uses are expressly restricted. + + + ## Base Path + + `https://api.bandwidth.com/v2` + + + ## DNI-Only + + Properties labeled *DNI-Only* in the Response Schema are only available to + accounts that have subscribed to the Dynamic Number Intelligence bundled + solution. Accounts not subscribed to DNI will not see these properties in + the responses. + + + ## Timestamps + + Properties in this endpoint with a datatype of `date-time-local` have no + time zone because these timestamps are sourced from a wide variety of + carriers. Not all carriers provide time zone information. +servers: + - url: https://api.bandwidth.com/v2 + description: Production +paths: + /accounts/{accountId}/phoneNumberLookup: + post: + summary: Create Synchronous Number Lookup + description: >- + Creates a synchronous phone number lookup request. Maximum of 100 + telephone numbers per request. + operationId: createSyncLookup + tags: + - Phone Number Lookup + parameters: + - $ref: '#/components/parameters/accountId' + requestBody: + $ref: '#/components/requestBodies/createSyncLookupRequest' + responses: + '200': + $ref: '#/components/responses/createSyncLookupResponse' + default: + $ref: '#/components/responses/tnLookupDefaultResponse' + /accounts/{accountId}/phoneNumberLookup/bulk: + post: + summary: Create Asynchronous Bulk Number Lookup + description: >- + Creates an asynchronous bulk phone number lookup request. Maximum of + 15,000 telephone numbers per request. Use the [Get Asynchronous Bulk + Number Lookup](#tag/Phone-Number-Lookup/operation/getAsyncBulkLookup) + endpoint to check the status of the request and view the results. + operationId: createAsyncBulkLookup + tags: + - Phone Number Lookup + parameters: + - $ref: '#/components/parameters/accountId' + requestBody: + $ref: '#/components/requestBodies/createAsyncBulkLookupRequest' + responses: + '202': + $ref: '#/components/responses/createAsyncBulkLookupResponse' + default: + $ref: '#/components/responses/tnLookupDefaultResponse' + /accounts/{accountId}/phoneNumberLookup/bulk/{requestId}: + get: + summary: Get Asynchronous Bulk Number Lookup + description: >- + Get an existing [Asynchronous Bulk Number + Lookup](#tag/Phone-Number-Lookup/operation/createAsyncBulkLookup). Use + this endpoint to check the status of the request and view the results. + operationId: getAsyncBulkLookup + tags: + - Phone Number Lookup + parameters: + - $ref: '#/components/parameters/accountId' + - $ref: '#/components/parameters/requestId' + responses: + '200': + $ref: '#/components/responses/getAsyncBulkLookupResponse' + default: + $ref: '#/components/responses/tnLookupDefaultResponse' +components: + schemas: + completedLookupStatusEnum: + type: string + enum: + - COMPLETE + - PARTIAL_COMPLETE + - FAILED + example: COMPLETE + inProgressLookupStatusEnum: + type: string + enum: + - IN_PROGRESS + - COMPLETE + - PARTIAL_COMPLETE + - FAILED + example: COMPLETE + deactivationEventEnum: + type: string + description: > + [DNI-Only](#section/DNI-Only). + + `DEACTIVATED` if the carrier reported a deactivation event for this + phone number. + enum: + - DEACTIVATED + latestMessageDeliveryStatusEnum: + type: string + description: >- + [DNI-Only](#section/DNI-Only). The current delivery status of the phone + number. + + - ACTIVE: A message was successfully sent to the number (delivery code + 0). + + - DEACTIVATED: A message was not delivered to a number (delivery code + 720) + + - UNKNOWN: Bandwidth cannot find an delivery status entry for the + number. + enum: + - ACTIVE + - DEACTIVATED + - UNKNOWN + lineTypeEnum: + type: string + enum: + - FIXED + - VOIP-FIXED + - MOBILE + - VOIP + example: MOBILE + requestId: + type: string + format: uuid + description: The phone number lookup request ID from Bandwidth. + example: 004223a0-8b17-41b1-bf81-20732adf5590 + linkSchema: + title: Link + type: object + properties: + href: + type: string + description: URI of the link. + example: /relative/uri + rel: + type: string + description: Specifies the relationship between this link and the resource. + example: aRelatedResource + method: + type: string + description: HTTP method to be used. + example: GET + lookupErrorSchema: + type: object + properties: + code: + type: string + description: Validation error code + example: NO-MATCH + description: + type: string + description: Description of validation error + example: Example error description + type: + type: string + description: Type of validation error + example: NumberInventory + meta: + type: object + properties: + phoneNumbers: + type: array + items: + type: string + description: Phone number experiencing the error. + example: + - '+13992077164' + - '+19196104424' + message: + type: string + description: Message describing the error + example: Invalid TNs + code: + type: integer + description: Error code associated with the message + example: 1001 + syncLookupRequest: + type: object + properties: + phoneNumbers: + description: Telephone numbers in E.164 format. + type: array + minimum: 1 + maximum: 100 + items: + type: string + pattern: ^\+[1-9]\d{1,14}$ + required: + - phoneNumbers + asyncLookupRequest: + type: object + properties: + phoneNumbers: + description: Telephone numbers in E.164 format. + type: array + minimum: 1 + maximum: 15000 + items: + type: string + pattern: ^\+[1-9]\d{1,14}$ + required: + - phoneNumbers + createSyncLookupResponse: + type: object + properties: + links: + type: array + items: + $ref: '#/components/schemas/linkSchema' + example: [] + data: + type: object + description: The phone number lookup response data + properties: + requestId: + $ref: '#/components/schemas/requestId' + status: + $ref: '#/components/schemas/completedLookupStatusEnum' + results: + type: array + description: >- + The carrier information results for the specified telephone + numbers. + items: + $ref: '#/components/schemas/lookupResult' + errors: + type: array + items: + $ref: '#/components/schemas/lookupErrorSchema' + createAsyncBulkLookupResponse: + type: object + properties: + links: + type: array + description: Links for pagination (if applicable) + items: + $ref: '#/components/schemas/linkSchema' + data: + type: object + description: The phone number lookup response data + properties: + requestId: + $ref: '#/components/schemas/requestId' + status: + $ref: '#/components/schemas/inProgressLookupStatusEnum' + errors: + type: array + items: + $ref: '#/components/schemas/lookupErrorSchema' + getAsyncBulkLookupResponse: + type: object + properties: + links: + type: array + items: + $ref: '#/components/schemas/linkSchema' + example: [] + data: + type: object + description: The phone number lookup response data + properties: + requestId: + $ref: '#/components/schemas/requestId' + status: + $ref: '#/components/schemas/inProgressLookupStatusEnum' + results: + type: array + description: >- + The carrier information results for the specified telephone + number. + items: + $ref: '#/components/schemas/lookupResult' + errors: + type: array + items: + $ref: '#/components/schemas/lookupErrorSchema' + lookupErrorResponse: + type: object + properties: + links: + type: array + items: + $ref: '#/components/schemas/linkSchema' + example: [] + data: + type: object + description: The phone number lookup response data + errors: + type: array + items: + $ref: '#/components/schemas/lookupErrorSchema' + lookupResult: + type: object + description: Carrier information results for the specified telephone number. + properties: + phoneNumber: + type: string + description: The telephone number in E.164 format. + example: '+10072904498' + lineType: + $ref: '#/components/schemas/lineTypeEnum' + messagingProvider: + type: string + description: The messaging service provider of the telephone number. + example: Verizon Wireless + voiceProvider: + type: string + description: The voice service provider of the telephone number. + example: Verizon Wireless + countryCodeA3: + type: string + description: >- + The country code of the telephone number in ISO 3166-1 alpha-3 + format. + example: USA + deactivationReporter: + type: string + description: > + [DNI-Only](#section/DNI-Only). + + The carrier that reported a deactivation event for this phone + number. + deactivationDate: + type: string + format: date-time-local + description: >- + [DNI-Only](#section/DNI-Only). The datetime the carrier reported a + deactivation event. + example: 2025-06-20 18:35 + deactivationEvent: + $ref: '#/components/schemas/deactivationEventEnum' + latestMessageDeliveryStatus: + $ref: '#/components/schemas/latestMessageDeliveryStatusEnum' + initialMessageDeliveryStatusDate: + type: string + format: date + description: >- + [DNI-Only](#section/DNI-Only). The date the phone number entered the + status described in `latestMessageDeliveryStatus`. + + Think of this as the "start time" for that status. + + Value resets every time the `latestMessageDeliveryStatus` changes. + example: '2025-06-20' + latestMessageDeliveryStatusDate: + type: string + format: date + description: >- + [DNI-Only](#section/DNI-Only). The date bandwidth last received + delivery status information for this phone number. + + Use this field to understand how up-to-date the + `latestMessageDeliveryStatus` is. + + Value resets every time the `latestMessageDeliveryStatus` changes. + example: '2025-06-21' + responses: + createSyncLookupResponse: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/createSyncLookupResponse' + examples: + lookupCompleteWithDniExample: + $ref: '#/components/examples/lookupCompleteWithDniExample' + lookupCompleteExample: + $ref: '#/components/examples/lookupCompleteExample' + lookupPartialExample: + $ref: '#/components/examples/lookupPartialExample' + lookupFailedExample: + $ref: '#/components/examples/lookupFailedExample' + createAsyncBulkLookupResponse: + description: Accepted + content: + application/json: + schema: + $ref: '#/components/schemas/createAsyncBulkLookupResponse' + examples: + lookupInProgressExample: + $ref: '#/components/examples/lookupInProgressExample' + getAsyncBulkLookupResponse: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/getAsyncBulkLookupResponse' + examples: + lookupCompleteWithDniExample: + $ref: '#/components/examples/lookupCompleteWithDniExample' + lookupCompleteExample: + $ref: '#/components/examples/lookupCompleteExample' + lookupInProgressExample: + $ref: '#/components/examples/lookupInProgressExample' + lookupPartialExample: + $ref: '#/components/examples/lookupPartialExample' + lookupFailedExample: + $ref: '#/components/examples/lookupFailedExample' + tnLookupDefaultResponse: + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/lookupErrorResponse' + examples: + badRequest: + $ref: '#/components/examples/badRequestExample' + unauthorized: + $ref: '#/components/examples/unauthorizedExample' + forbidden: + $ref: '#/components/examples/forbiddenExample' + mediaType: + $ref: '#/components/examples/unsupportedMediaTypeExample' + notFound: + $ref: '#/components/examples/notFoundExample' + tooManyRequests: + $ref: '#/components/examples/tooManyRequestsExample' + internalServer: + $ref: '#/components/examples/internalServerErrorExample' + parameters: + accountId: + in: path + name: accountId + required: true + schema: + type: string + description: Your Bandwidth Account ID. + example: '9900000' + requestId: + in: path + name: requestId + required: true + schema: + type: string + format: uuid + description: The phone number lookup request ID from Bandwidth. + example: 004223a0-8b17-41b1-bf81-20732adf5590 + examples: + singleNumberRequestExample: + summary: Number Lookup Request + value: + phoneNumbers: + - '+19196104423' + multipleNumberRequestExample: + summary: Number Lookup Request for Multiple Numbers + value: + phoneNumbers: + - '+19196104423' + - '+19196104424' + lookupInProgressExample: + summary: Numbers Lookup In Progress + value: + links: + - href: href + rel: rel + method: GET + data: + requestId: 004223a0-8b17-41b1-bf81-20732adf5590 + status: IN_PROGRESS + results: [] + errors: [] + lookupFailedExample: + summary: Numbers Lookup Failed + value: + links: + - href: href + rel: rel + method: GET + data: + requestId: 004223a0-8b17-41b1-bf81-20732adf5590 + status: FAILED + results: [] + errors: + - code: NO-MATCH + description: The following TNs could not be found in the Number Industry data + meta: + phoneNumbers: + - '+13992077164' + message: Invalid TNs + code: 1001 + type: NumberInventory + lookupPartialExample: + summary: Numbers Lookup Partial Complete + value: + links: + - href: href + rel: rel + method: GET + data: + requestId: 004223a0-8b17-41b1-bf81-20732adf5590 + status: PARTIAL_COMPLETE + results: + - phoneNumber: '+19196104423' + lineType: MOBILE + messagingProvider: Verizon Wireless + voiceProvider: Verizon Wireless + countryCodeA3: USA + - phoneNumber: '+19196104424' + lineType: MOBILE + messagingProvider: T-Mobile USA + voiceProvider: T-Mobile USA + countryCodeA3: USA + errors: + - code: NO-MATCH + description: The following TNs could not be found in the Number Industry data + meta: + phoneNumbers: + - '+13992077164' + message: Invalid TNs + code: 1001 + type: NumberInventory + lookupCompleteExample: + summary: Numbers Lookup Complete (without DNI) + value: + links: + - href: href + rel: rel + method: GET + data: + requestId: 004223a0-8b17-41b1-bf81-20732adf5590 + status: COMPLETE + results: + - phoneNumber: '+10072904497' + lineType: MOBILE + messagingProvider: Verizon Wireless + voiceProvider: Verizon Wireless + countryCodeA3: USA + - phoneNumber: '+10072904498' + lineType: MOBILE + messagingProvider: T-Mobile USA + voiceProvider: T-Mobile USA + countryCodeA3: USA + errors: [] + lookupCompleteWithDniExample: + summary: Numbers Lookup Complete (with DNI) + value: + links: + - href: href + rel: rel + method: GET + data: + requestId: 20732adf-bf81-8b17-41b1-004223a05590 + status: COMPLETE + results: + - phoneNumber: '+10072904497' + countryCodeA3: USA + lineType: MOBILE + messagingProvider: T-MOBILE USA INC + voiceProvider: T-MOBILE USA INC + latestMessageDeliveryStatus: ACTIVE + initialMessageDeliveryStatusDate: '2025-05-14' + latestMessageDeliveryStatusDate: '2025-05-18' + - phoneNumber: '+10072904498' + countryCodeA3: USA + lineType: FIXED + voiceProvider: VERIZON + latestMessageDeliveryStatus: DEACTIVATED + initialMessageDeliveryStatusDate: '2025-09-05' + latestMessageDeliveryStatusDate: '2025-09-05' + - phoneNumber: '+10072904499' + lineType: MOBILE + countryCodeA3: USA + messagingProvider: VERIZON + voiceProvider: VERIZON + deactivationReporter: Verizon Wireless + deactivationDate: '2025-09-29 01:23:00' + deactivationEvent: DEACTIVATED + latestMessageDeliveryStatus: UNKNOWN + errors: [] + badRequestExample: + summary: Example Bad Request Error + value: + links: [] + data: {} + errors: + - type: bad-request + description: >- + Bad Request. Ensure that you have set the requestId as a URL path + parameter. + unauthorizedExample: + summary: Unauthorized Error + value: + links: [] + data: {} + errors: + - type: Unauthorized + description: You are not authorized to access this resource. + code: '1' + page: null + forbiddenExample: + summary: Forbidden Error + value: + links: [] + data: {} + errors: + - type: Forbidden + description: You do not have permission to access this resource. + code: '2' + page: null + unsupportedMediaTypeExample: + summary: Unsupported Media Type Error + value: + links: [] + data: {} + errors: + - type: invalid-content-type + description: >- + Invalid content-type. Ensure that your content-type header is set + to application/json. + notFoundExample: + summary: Not Found Error + value: + links: [] + data: {} + errors: + - type: not-found + description: >- + RequestId not found. Ensure that the requestId used in the URL + path is valid and maps to a previous request that was submitted. + tooManyRequestsExample: + summary: Too Many Requests Error + value: + links: [] + data: {} + errors: + - type: rate-limiting + description: >- + Rate limit exceeded. Wait for the time specified in the + Retry-After header before sending another request. + internalServerErrorExample: + summary: Internal Server Error + value: + links: [] + data: {} + errors: + - code: '500' + type: unexpected-error + description: >- + Unexpected error. Please contact Bandwidth Support if your + requests are receiving this status code for an extended period of + time. + requestBodies: + createSyncLookupRequest: + description: Synchronous phone number lookup request. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/syncLookupRequest' + examples: + singleNumberRequestExample: + $ref: '#/components/examples/singleNumberRequestExample' + multipleNumberRequestExample: + $ref: '#/components/examples/multipleNumberRequestExample' + createAsyncBulkLookupRequest: + description: Asynchronous bulk phone number lookup request. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/asyncLookupRequest' + examples: + multipleNumberRequestExample: + $ref: '#/components/examples/multipleNumberRequestExample' + securitySchemes: + Basic: + type: http + scheme: basic + description: >- + Basic authentication is a simple authentication scheme built into the + HTTP protocol. To use it, send your HTTP requests with an + `Authorization` header that contains the word `Basic` followed by a + space and a Base64-encoded string `username:password`. + + + - Example: `Authorization: Basic ZGVtbZpwQDU1dzByZA==` + OAuth2: + type: oauth2 + flows: + clientCredentials: + tokenUrl: https://api.bandwidth.com/api/v1/oauth2/token + scopes: {} +security: + - Basic: [] + - OAuth2: [] +tags: + - name: Phone Number Lookup diff --git a/test/fixtures/phone-number-lookup.yml b/test/fixtures/phone-number-lookup.yml deleted file mode 100644 index 5a4018f..0000000 --- a/test/fixtures/phone-number-lookup.yml +++ /dev/null @@ -1,424 +0,0 @@ -openapi: 3.0.3 -info: - title: Phone Number Lookup - version: 1.1.0 - contact: - name: Bandwidth Support - email: support@bandwidth.com - url: https://support.bandwidth.com - termsOfService: https://www.bandwidth.com/legal/terms-of-use-bandwidthcom-web-sites/ - description: >- - A Bandwidth API to provide carrier information for a telephone number or - batch of telephone numbers. Currently supports lookups of telephone numbers - in the mainland United States, Alaska, Hawaii, and the District of Columbia. Telephone numbers submitted must be in E.164 format to - be processed. - NPAC Data and data derived from User Data is confidential information and is restricted in use as defined by the Master Services Agreement for Number Portability Administration Center/Service Management System) between iconectiv and the North American Portability Management LLC (NAPM). - https://numberportability.com/about/lrn-contacts - - - Deprecation Note: This endpoint is deprecated and will be decommissioned on Dec 1, 2025. It has been replaced with: /v2/accounts/{accountId}/phoneNumberLookup/bulk - - ## Base Path - - `https://numbers.bandwidth.com/api/v1` -servers: - - url: https://numbers.bandwidth.com/api/v1 - description: Production -paths: - /accounts/{accountId}/tnlookup: - post: - summary: Create Lookup - description: Create a Phone Number Lookup Request. - operationId: createLookup - tags: - - Phone Number Lookup - parameters: - - $ref: '#/components/parameters/accountId' - requestBody: - $ref: '#/components/requestBodies/createLookupRequest' - responses: - '202': - $ref: '#/components/responses/createLookupResponse' - '400': - $ref: '#/components/responses/tnLookupBadRequestError' - '401': - $ref: '#/components/responses/tnLookupUnauthorizedError' - '403': - $ref: '#/components/responses/tnLookupForbiddenError' - '415': - $ref: '#/components/responses/tnLookupMediaTypeError' - '429': - $ref: '#/components/responses/tnLookupTooManyRequestsError' - '500': - $ref: '#/components/responses/tnLookupInternalServerError' - /accounts/{accountId}/tnlookup/{requestId}: - get: - summary: Get Lookup Request Status - description: Get an existing Phone Number Lookup Request. - operationId: getLookupStatus - tags: - - Phone Number Lookup - parameters: - - $ref: '#/components/parameters/accountId' - - $ref: '#/components/parameters/requestId' - responses: - '200': - $ref: '#/components/responses/getLookupResponse' - '400': - $ref: '#/components/responses/tnLookupBadRequestError' - '401': - $ref: '#/components/responses/tnLookupUnauthorizedError' - '403': - $ref: '#/components/responses/tnLookupForbiddenError' - '404': - $ref: '#/components/responses/tnLookupNotFoundError' - '429': - $ref: '#/components/responses/tnLookupTooManyRequestsError' - '500': - $ref: '#/components/responses/tnLookupInternalServerError' -components: - schemas: - lookupStatusEnum: - type: string - description: >- - The status of the request (IN_PROGRESS, COMPLETE, PARTIAL_COMPLETE, or - FAILED). - enum: - - IN_PROGRESS - - COMPLETE - - PARTIAL_COMPLETE - - FAILED - example: COMPLETE - lookupRequest: - type: object - description: Create phone number lookup request. - properties: - tns: - type: array - items: - type: string - required: - - tns - createLookupResponse: - type: object - description: >- - The request has been accepted for processing but not yet finished and in - a terminal state (COMPLETE, PARTIAL_COMPLETE, or FAILED). - properties: - requestId: - type: string - description: The phone number lookup request ID from Bandwidth. - status: - $ref: '#/components/schemas/lookupStatusEnum' - lookupStatus: - type: object - description: >- - If requestId exists, the result for that request is returned. See the - Examples for details on the various responses that you can receive. - Generally, if you see a Response Code of 0 in a result for a TN, - information will be available for it. Any other Response Code will - indicate no information was available for the TN. - properties: - requestId: - type: string - description: The requestId. - example: 004223a0-8b17-41b1-bf81-20732adf5590 - status: - $ref: '#/components/schemas/lookupStatusEnum' - result: - type: array - description: The carrier information results for the specified telephone number. - items: - $ref: '#/components/schemas/lookupResult' - failedTelephoneNumbers: - type: array - description: The telephone numbers whose lookup failed. - items: - type: string - example: ['+191955512345'] - lookupResult: - type: object - description: Carrier information results for the specified telephone number. - properties: - Response Code: - type: integer - description: Our vendor's response code. - example: 0 - Message: - type: string - description: Message associated with the response code. - example: NOERROR - E.164 Format: - type: string - description: The telephone number in E.164 format. - example: '+19195551234' - Formatted: - type: string - description: The formatted version of the telephone number. - example: '(919) 555-1234' - Country: - type: string - description: The country of the telephone number. - example: US - Line Type: - type: string - description: The line type of the telephone number. - example: Mobile - Line Provider: - type: string - description: The messaging service provider of the telephone number. - example: Verizon Wireless - Mobile Country Code: - type: string - description: The first half of the Home Network Identity (HNI). - example: '310' - Mobile Network Code: - type: string - description: The second half of the HNI. - example: '010' - tnLookupRequestError: - type: object - properties: - message: - type: string - description: A description of what validation error occurred. - example: example error message - responses: - createLookupResponse: - description: Accepted - content: - application/json: - schema: - $ref: '#/components/schemas/createLookupResponse' - examples: - lookupResponseExample: - $ref: '#/components/examples/lookupInProgressExample' - getLookupResponse: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/lookupStatus' - examples: - lookupInProgressExample: - $ref: '#/components/examples/lookupInProgressExample' - lookupFailedExample: - $ref: '#/components/examples/lookupFailedExample' - lookupSingleNumberCompleteExample: - $ref: '#/components/examples/lookupSingleNumberCompleteExample' - lookupMultipleNumbersCompleteExample: - $ref: '#/components/examples/lookupMultipleNumbersCompleteExample' - lookupMultipleNumbersPartialCompleteExample: - $ref: '#/components/examples/lookupMultipleNumbersPartialCompleteExample' - lookupSingleNumberCompleteNoInfoExample: - $ref: '#/components/examples/lookupSingleNumberCompleteNoInfoExample' - tnLookupBadRequestError: - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/tnLookupRequestError' - examples: - badRequest: - summary: Example Bad Request Error - value: - message: 'Some tns do not match e164 format: 1234' - tnLookupUnauthorizedError: - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/tnLookupRequestError' - examples: - unauthorized: - summary: Example Unauthorized Error - value: - message: Unauthorized - tnLookupForbiddenError: - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/tnLookupRequestError' - examples: - forbidden: - summary: Example Forbidden Error - value: - message: >- - Authorization header requires 'Credential' parameter. - Authorization header requires 'Signature' parameter. - Authorization header requires 'SignedHeaders' parameter. - Authorization header requires existence of either a - 'X-Amz-Date' or a 'Date' header. Authorization=Basic - Y2tvZloPTGhHgywYIzGlcGVlcGvvcGovYTIGIt==' - tnLookupMediaTypeError: - description: Unsupported Media Type - content: - application/json: - schema: - $ref: '#/components/schemas/tnLookupRequestError' - examples: - mediaType: - summary: Example Unsupported Media Type Error - value: - message: Content-Type must be application/json. - tnLookupNotFoundError: - description: Not Found - tnLookupTooManyRequestsError: - description: Too Many Requests - content: - application/json: - schema: - $ref: '#/components/schemas/tnLookupRequestError' - examples: - mediaType: - summary: Example Too Many Requests Error - value: - message: Too many requests. - tnLookupInternalServerError: - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/tnLookupRequestError' - examples: - mediaType: - summary: Example Internal Server Error Error - value: - message: Request has not been passed further. - parameters: - accountId: - in: path - name: accountId - required: true - schema: - type: string - description: Your Bandwidth Account ID. - example: "9900000" - requestId: - name: requestId - in: path - required: true - schema: - type: string - description: The phone number lookup request ID from Bandwidth. - example: 004223a0-8b17-41b1-bf81-20732adf5590 - examples: - singleNumberRequestExample: - summary: Example Number Lookup Request for One Number - value: - tns: - - '+19195551234' - multipleNumberRequestExample: - summary: Example Number Lookup Request for Multiple Numbers - value: - tns: - - '+19195551234' - - '+19195554321' - lookupInProgressExample: - summary: Example Lookup In Progress Response - value: - requestId: 004223a0-8b17-41b1-bf81-20732adf5590 - status: IN_PROGRESS - lookupFailedExample: - summary: Example Lookup Failed Response - value: - requestId: 004223a0-8b17-41b1-bf81-20732adf5590 - status: FAILED - failedTelephoneNumbers: - - '+191955512345' - lookupSingleNumberCompleteExample: - summary: Example Single Number Lookup Complete Response - value: - requestId: 004223a0-8b17-41b1-bf81-20732adf5590 - status: COMPLETE - result: - - Response Code: 0 - Message: NOERROR - E.164 Format: '+19195551234' - Formatted: (919) 555-1234 - Country: US - Line Type: Mobile - Line Provider: Verizon Wireless - Mobile Country Code: '310' - Mobile Network Code: '010' - lookupMultipleNumbersCompleteExample: - summary: Example Multiple Numbers Lookup Complete Response - value: - requestId: 004223a0-8b17-41b1-bf81-20732adf5590 - status: COMPLETE - result: - - Response Code: 0 - Message: NOERROR - E.164 Format: '+19195551234' - Formatted: (919) 555-1234 - Country: US - Line Type: Mobile - Line Provider: Verizon Wireless - Mobile Country Code: '310' - Mobile Network Code: '010' - - Response Code: 0 - Message: NOERROR - E.164 Format: '+19195554321' - Formatted: (919) 555-4321 - Country: US - Line Type: Mobile - Line Provider: T-Mobile USA - Mobile Country Code: '310' - Mobile Network Code: '160' - lookupMultipleNumbersPartialCompleteExample: - summary: Example Multiple Numbers Lookup Partial Complete Response - value: - requestId: 004223a0-8b17-41b1-bf81-20732adf5590 - status: PARTIAL_COMPLETE - result: - - Response Code: 0 - Message: NOERROR - E.164 Format: '+19195551234' - Formatted: (919) 555-1234 - Country: US - Line Type: Mobile - Line Provider: Verizon Wireless - Mobile Country Code: '310' - Mobile Network Code: '010' - failedTelephoneNumbers: - - '+191955512345' - lookupSingleNumberCompleteNoInfoExample: - summary: Example Single Number Lookup Complete with No Information Response - value: - requestId: 004223a0-8b17-41b1-bf81-20732adf5590 - status: COMPLETE - result: - - Response Code: 3 - Message: NXDOMAIN - E.164 Format: '+19195550000' - Formatted: (919) 555-0000 - Country: US - requestBodies: - createLookupRequest: - description: Phone number lookup request. - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/lookupRequest' - examples: - singleNumberRequestExample: - $ref: '#/components/examples/singleNumberRequestExample' - multipleNumberRequestExample: - $ref: '#/components/examples/multipleNumberRequestExample' - securitySchemes: - Basic: - type: http - scheme: basic - description: >- - Basic authentication is a simple authentication scheme built into the - HTTP protocol. To use it, send your HTTP requests with an Authorization - header that contains the word Basic followed by a space and a - base64-encoded string `username:password`. - - Example: `Authorization: Basic ZGVtbZpwQDU1dzByZA==` -security: - - Basic: [] -tags: - - name: Phone Number Lookup diff --git a/test/test_openapi.py b/test/test_openapi.py index b1fe478..dfa50d7 100644 --- a/test/test_openapi.py +++ b/test/test_openapi.py @@ -37,4 +37,4 @@ async def test_fetch_openapi_spec_http_error(): async def test_fetch_openapi_spec_invalid_yaml(): """Test that fetching an invalid YAML file raises a YAMLError.""" with pytest.raises(RuntimeError): - await fetch_openapi_spec("https://example.com") + await fetch_openapi_spec("https://not-real-564987132489746sadfg.com") diff --git a/test/test_servers.py b/test/test_servers.py index b84b021..f7a6932 100644 --- a/test/test_servers.py +++ b/test/test_servers.py @@ -17,7 +17,7 @@ async def create_mcp_server(name=None, tools=None, excluded_tools=None): return mcp -def calculate_expected_tools(tools, excluded_tools, total_tools=46): +def calculate_expected_tools(tools, excluded_tools, total_tools=47): if tools and not excluded_tools: return len(tools) elif excluded_tools: @@ -46,7 +46,7 @@ async def test_full_mcp_server_creation(tools, excluded_tools, httpx_mock: HTTPX for name in [ "messaging", "multi-factor-auth", - "phone-number-lookup", + "phone-number-lookup-v2", "insights", "end-user-management", ]: @@ -84,10 +84,10 @@ async def test_full_mcp_server_creation(tools, excluded_tools, httpx_mock: HTTPX "Basic dGVzdF91c2VyX21mYTp0ZXN0X3Bhc3NfbWZh", ), ( - "https://dev.bandwidth.com/spec/phone-number-lookup.yml", + "https://dev.bandwidth.com/spec/phone-number-lookup-v2.yml", {"BW_USERNAME": "test_user_tnlookup", "BW_PASSWORD": "test_pass_tnlookup"}, - "https://numbers.bandwidth.com/api/v1/", - {"createLookup", "getLookupStatus"}, + "https://api.bandwidth.com/v2/", + {"createSyncLookup", "createAsyncBulkLookup", "getAsyncBulkLookup"}, "Basic dGVzdF91c2VyX3RubG9va3VwOnRlc3RfcGFzc190bmxvb2t1cA==", ), ]