mcpField
T
telnyx

telnyx

本地服务
github.com/team-telnyx通信协作198今天更新

关于 telnyx

Telnyx TypeScript 库是 Telnyx REST API 的官方 SDK,用于在服务端 TypeScript 或 JavaScript 中调用短信、语音和号码等接口。该库由 Stainless 生成,并附带一个 MCP 服务,供 AI 助手探索接口和发起测试请求。

主要功能

  1. 01封装 Telnyx REST API 的类型化调用
  2. 02提供分页遍历与 Webhook 签名验证
  3. 03内置自动重试与超时配置
  4. 04支持自定义 fetch 与代理设置
  5. 05附带可供 AI 助手使用的 MCP 服务

适用场景

  1. 01在 Node.js 服务中发送短信或发起呼叫控制通话
  2. 02验证入站 Telnyx Webhook 的签名
  3. 03让 AI 助手查阅接口文档并发起测试请求

MCP 相关

该库附带一个 MCP 服务,使 AI 助手能够探索 Telnyx API 的端点、发起测试请求并查阅文档。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"team-telnyx-telnyx": {
"command": "npx",
"args": [
"-y",
"telnyx"
],
"env": {
"TELNYX_API_KEY": "<TELNYX_API_KEY>"
}
}
}
}
启动命令npx -y telnyx
需要配置的环境变量
TELNYX_API_KEY密钥Your Telnyx API key for authentication

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmtelnyx6.29.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Telnyx TypeScript API Library

NPM version npm bundle size

此库可在服务端 TypeScript 或 JavaScript 中便捷地访问 Telnyx REST API。

此库的完整 API 可在 api.md 中查看。

此库由 Stainless 生成。

MCP 服务

使用 Telnyx MCP 服务,让 AI 助手与此 API 交互,以探索端点、发送测试请求,并使用文档帮助将此 SDK 集成到应用中。

添加到 Cursor 在 VS Code 中安装

注意:你可能需要在 MCP 客户端中设置环境变量。

安装

npm install telnyx

使用

此库的完整 API 可在 api.md 中查看。

import Telnyx from 'telnyx';

const client = new Telnyx({
  apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted
});

const response = await client.calls.dial({
  connection_id: 'conn12345',
  from: '+15557654321',
  to: '+15551234567',
  webhook_url: 'https://your-webhook.url/events',
});

console.log(response.data);

示例

以下示例均可运行:

搜索并订购电话号码
const { data: availableNumbers } = await client.availablePhoneNumbers.list({
  filter: {
    country_code: 'US',
    national_destination_code: '312',
    limit: 1,
  },
});

const phoneNumber = availableNumbers?.[0]?.phone_number;
if (!phoneNumber) throw new Error('No phone numbers found');

const { data: order } = await client.numberOrders.create({
  phone_numbers: [{ phone_number: phoneNumber }],
});
发送 SMS
const { data: message } = await client.messages.send({
  from: '+15551234567',
  to: '+15557654321',
  text: 'Hello from Telnyx!',
});
发起呼叫控制通话
const { data: call } = await client.calls.dial({
  connection_id: 'your-connection-id',
  from: '+15551234567',
  to: '+15557654321',
  webhook_url: 'https://example.com/webhooks',
});
验证入站 Webhook

使用 Telnyx 公钥配置客户端,并将未经修改的原始请求正文传递给 unwrap。在验证前解析或重新序列化正文会导致签名失效。

const webhookClient = new Telnyx({
  apiKey: process.env['TELNYX_API_KEY'],
  publicKey: process.env['TELNYX_PUBLIC_KEY'],
});

const event = webhookClient.webhooks.unwrap(rawBody, {
  headers: requestHeaders,
});

有关原始正文处理和错误响应,请参阅完整的 Express Webhook 验证示例。

配置重试

默认情况下,连接失败和可重试的 HTTP 响应会重试两次。为客户端设置 maxRetries,或为单个请求覆盖该值:

const retryingClient = new Telnyx({
  apiKey: process.env['TELNYX_API_KEY'],
  maxRetries: 4,
});

await retryingClient.messages.send(
  {
    from: '+15551234567',
    to: '+15557654321',
    text: 'Hello from Telnyx!',
  },
  { maxRetries: 0 },
);

详情请参阅处理错误和重试。

请求和响应类型

此库包含所有请求参数和响应字段的 TypeScript 定义。你可以按如下方式导入并使用:

import Telnyx from 'telnyx';

const client = new Telnyx({
  apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted
});

const params: Telnyx.NumberOrderCreateParams = {
  phone_numbers: [{ phone_number: '+15558675309' }],
};
const numberOrder: Telnyx.NumberOrderCreateResponse = await client.numberOrders.create(params);

每种方法、请求参数和响应字段的文档均可在文档字符串中查看,并会在大多数现代编辑器中通过悬停显示。

文件上传

与文件上传对应的请求参数可以通过多种形式传递:

  • File(或结构相同的对象)
  • fetch Response(或结构相同的对象)
  • fs.ReadStream
  • 我们的 toFile 辅助函数的返回值
import fs from 'fs';
import Telnyx, { toFile } from 'telnyx';

const client = new Telnyx();

// If you have access to Node `fs` we recommend using `fs.createReadStream()`:
await client.ai.audio.transcribe({
  model: 'distil-whisper/distil-large-v2',
  file: fs.createReadStream('/path/to/file'),
});

// Or if you have the web `File` API you can pass a `File` instance:
await client.ai.audio.transcribe({
  model: 'distil-whisper/distil-large-v2',
  file: new File(['my bytes'], 'file'),
});

// You can also pass a `fetch` `Response`:
await client.ai.audio.transcribe({
  model: 'distil-whisper/distil-large-v2',
  file: await fetch('https://somesite/file'),
});

// Finally, if none of the above are convenient, you can use our `toFile` helper:
await client.ai.audio.transcribe({
  model: 'distil-whisper/distil-large-v2',
  file: await toFile(Buffer.from('my bytes'), 'file'),
});
await client.ai.audio.transcribe({
  model: 'distil-whisper/distil-large-v2',
  file: await toFile(new Uint8Array([0, 1, 2]), 'file'),
});

错误处理

当库无法连接到 API, 或 API 返回非成功状态码(即 4xx 或 5xx 响应)时, 将抛出 APIError 的子类:

const numberOrder = await client.numberOrders
  .create({ phone_numbers: [{ phone_number: '+15558675309' }] })
  .catch(async (err) => {
    if (err instanceof Telnyx.APIError) {
      console.log(err.status); // 400
      console.log(err.name); // BadRequestError
      console.log(err.headers); // {server: 'nginx', ...}
    } else {
      throw err;
    }
  });

错误代码如下:

状态码错误类型
400BadRequestError
401AuthenticationError
403PermissionDeniedError
404NotFoundError
422UnprocessableEntityError
429RateLimitError
>=500InternalServerError
N/AAPIConnectionError
重试

某些错误默认会自动重试 2 次,并采用较短的指数退避。 默认会重试连接错误(例如由网络连接问题导致的错误)、408 请求超时、409 冲突、 429 速率限制以及 >=500 内部错误。

你可以使用 maxRetries 选项进行配置或禁用重试:

// Configure the default for all requests:
const client = new Telnyx({
  maxRetries: 0, // default is 2
});

// Or, configure per-request:
await client.numberOrders.create({ phone_numbers: [{ phone_number: '+15558675309' }] }, {
  maxRetries: 5,
});
超时

请求默认会在 1 分钟后超时。你可以使用 timeout 选项进行配置:

// Configure the default for all requests:
const client = new Telnyx({
  timeout: 20 * 1000, // 20 seconds (default is 1 minute)
});

// Override per-request:
await client.numberOrders.create({ phone_numbers: [{ phone_number: '+15558675309' }] }, {
  timeout: 5 * 1000,
});

超时时会抛出 APIConnectionTimeoutError。

请注意,超时的请求默认会重试两次。

自动分页

Telnyx API 中的列表方法采用分页。 你可以使用 for await … of 语法遍历所有页面中的条目:

async function fetchAllAccessIPAddressResponses(params) {
  const allAccessIPAddressResponses = [];
  // Automatically fetches more pages as needed.
  for await (const accessIPAddressResponse of client.accessIPAddress.list({
    'page[number]': 1,
    'page[size]': 50,
  })) {
    allAccessIPAddressResponses.push(accessIPAddressResponse);
  }
  return allAccessIPAddressResponses;
}

或者,你也可以一次请求一页:

let page = await client.accessIPAddress.list({ 'page[number]': 1, 'page[size]': 50 });
for (const accessIPAddressResponse of page.data) {
  console.log(accessIPAddressResponse);
}

// Convenience methods are provided for manually paginating:
while (page.hasNextPage()) {
  page = await page.getNextPage();
  // ...
}

高级用法

访问原始 Response 数据(例如,标头)

所有方法返回的 APIPromise 类型都提供 .asResponse() 方法,可通过该方法访问 fetch() 返回的原始 Response。 成功响应的标头一旦收到,此方法就会立即返回,且不会读取响应正文,因此你可以自由编写自定义解析或流处理逻辑。

你也可以使用 .withResponse() 方法,同时获取原始 Response 和解析后的数据。 与 .asResponse() 不同,此方法会读取正文,并在解析完成后返回。

const client = new Telnyx();

const response = await client.numberOrders
  .create({ phone_numbers: [{ phone_number: '+15558675309' }] })
  .asResponse();
console.log(response.headers.get('X-My-Header'));
console.log(response.statusText); // access the underlying Response object

const { data: numberOrder, response: raw } = await client.numberOrders
  .create({ phone_numbers: [{ phone_number: '+15558675309' }] })
  .withResponse();
console.log(raw.headers.get('X-My-Header'));
console.log(numberOrder.data);
日志记录

重要

所有日志消息仅用于调试。日志消息的格式和内容 可能会在不同版本之间发生变化。

日志级别

可以通过以下两种方式配置日志级别:

  1. 通过 TELNYX_LOG 环境变量
  2. 使用客户端选项 logLevel(如果已设置,则会覆盖环境变量)
import Telnyx from 'telnyx';

const client = new Telnyx({
  logLevel: 'debug', // Show all log messages
});

可用的日志级别,从最详细到最简略依次为:

  • 'debug' - 显示调试消息、信息、警告和错误
  • 'info' - 显示信息、警告和错误
  • 'warn' - 显示警告和错误(默认)
  • 'error' - 仅显示错误
  • 'off' - 禁用所有日志记录

在 'debug' 级别下,会记录所有 HTTP 请求和响应,包括标头和正文。 某些与身份验证相关的标头会被隐藏,但请求和响应正文中的敏感数据 仍可能可见。

自定义日志记录器

默认情况下,此库会将日志记录到 globalThis.console。你也可以提供自定义日志记录器。 我们支持大多数日志记录库,包括 pino、winston、bunyan、consola、signale 和 @std/log。如果你的日志记录器无法正常工作,请提交 issue。

提供自定义日志记录器时,logLevel 选项仍会控制要输出哪些消息,低于所配置级别的消息不会发送到你的日志记录器。

import Telnyx from 'telnyx';
import pino from 'pino';

const logger = pino();

const client = new Telnyx({
  logger: logger.child({ name: 'Telnyx' }),
  logLevel: 'debug', // Send all messages to pino, allowing it to filter
});
发起自定义/未记录的请求

此库提供类型定义,便于访问已记录的 API。如果你需要访问未记录的端点、参数或响应属性,仍然可以使用此库。

未记录的端点

若要向未记录的端点发起请求,可以使用 client.get、client.post 和其他 HTTP 动词。 发起这些请求时,客户端上的选项(例如重试)仍会生效。

await client.post('/some/path', {
  body: { some_prop: 'foo' },
  query: { some_query_arg: 'bar' },
});
未记录的请求参数

若要使用未记录的参数发起请求,可以对该参数使用 // @ts-expect-error。此库不会在运行时验证请求是否符合类型定义,因此你发送的任何额外值都会原样发送。

client.calls.dial({
  // ...
  // @ts-expect-error baz is not yet public
  baz: 'undocumented option',
});

对于使用 GET 动词的请求,任何额外参数都会放在查询中;其他所有请求都会将额外参数放在请求正文中。

如果要显式发送额外参数,可以使用请求选项 query、body 和 headers。

未记录的响应属性

若要访问未记录的响应属性,可以对响应对象使用 // @ts-expect-error,也可以将响应对象转换为所需类型。与请求参数一样,我们不会验证或剔除 API 响应中的额外属性。

自定义 fetch 客户端

默认情况下,此库要求定义全局 fetch 函数。

如果要使用其他 fetch 函数,可以为全局函数添加 polyfill:

import fetch from 'my-fetch';

globalThis.fetch = fetch;

或者将其传递给客户端:

import Telnyx from 'telnyx';
import fetch from 'my-fetch';

const client = new Telnyx({ fetch });
Fetch 选项

如果要设置自定义 fetch 选项,但不覆盖 fetch 函数,可以在实例化客户端或发起请求时提供 fetchOptions 对象。(请求专属选项会覆盖客户端选项。)

import Telnyx from 'telnyx';

const client = new Telnyx({
  fetchOptions: {
    // `RequestInit` options
  },
});
配置代理

若要修改代理行为,可以提供自定义 fetchOptions,为请求添加特定于运行时的代理选项:

README 配图 Node [文档]

import Telnyx from 'telnyx';
import * as undici from 'undici';

const proxyAgent = new undici.ProxyAgent('http://localhost:8888');
const client = new Telnyx({
  fetchOptions: {
    dispatcher: proxyAgent,
  },
});

README 配图 Bun [文档]

import Telnyx from 'telnyx';

const client = new Telnyx({
  fetchOptions: {
    proxy: 'http://localhost:8888',
  },
});

README 配图 Deno [文档]

import Telnyx from 'npm:telnyx';

const httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } });
const client = new Telnyx({
  fetchOptions: {
    client: httpClient,
  },
});

常见问题

语义化版本

此软件包通常遵循 SemVer 约定,但某些不向后兼容的更改可能会作为次要版本发布:

  1. 仅影响静态类型、不破坏运行时行为的更改。
  2. 对库内部实现的更改:这些实现从技术上说是公开的,但并非面向外部使用或为外部使用提供文档。(如果您依赖此类内部实现,请提交 GitHub issue 告知我们。)
  3. 我们预计实际上不会影响绝大多数用户的更改。

我们非常重视向后兼容性,并努力确保您能够顺利升级。

我们期待您的反馈;如果您有疑问、发现错误或有建议,请提交 issue。

要求

支持 TypeScript >= 4.9。

支持以下运行时:

  • Web 浏览器(最新版 Chrome、Firefox、Safari、Edge 等)
  • Node.js 20 LTS 或更高版本(尚未停止维护)。
  • Deno v1.28.0 或更高版本。
  • Bun 1.0 或更高版本。
  • Cloudflare Workers。
  • Vercel Edge Runtime。
  • Jest 28 或更高版本,使用 "node" 环境(目前不支持 "jsdom")。
  • Nitro v2.6 或更高版本。

请注意,目前不支持 React Native。

如果您对其他运行时环境感兴趣,请在 GitHub 上提交 issue 或为相关 issue 投票。

贡献

请参阅贡献文档。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。