@pipeworx/mcp-twilio 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/package.json +20 -0
- package/server.json +18 -0
- package/src/index.ts +181 -0
- package/tsconfig.json +14 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pipeworx
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# mcp-twilio
|
|
2
|
+
|
|
3
|
+
Twilio MCP Pack — send SMS, list messages, make calls via Twilio REST API.
|
|
4
|
+
|
|
5
|
+
Part of the [Pipeworx](https://pipeworx.io) open MCP gateway.
|
|
6
|
+
|
|
7
|
+
## Tools
|
|
8
|
+
|
|
9
|
+
| Tool | Description |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
| `twilio_send_sms` | Send an SMS message via Twilio. Returns the message SID and status. |
|
|
12
|
+
| `twilio_list_messages` | List recent SMS/MMS messages from your Twilio account. Supports filtering by to/from number and pagination. |
|
|
13
|
+
| `twilio_get_message` | Get details of a specific Twilio message by its SID. |
|
|
14
|
+
| `twilio_list_calls` | List recent phone calls from your Twilio account. Returns call SID, status, duration, and direction. |
|
|
15
|
+
| `twilio_make_call` | Initiate a phone call via Twilio. Requires a TwiML URL or application SID to control call behavior. |
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
Add to your MCP client config:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"twilio": {
|
|
25
|
+
"url": "https://gateway.pipeworx.io/twilio/mcp"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or use the CLI:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx pipeworx use twilio
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pipeworx/mcp-twilio",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Twilio MCP Pack — send SMS, list messages, make calls via Twilio REST API.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"types": "src/index.ts",
|
|
8
|
+
"keywords": ["mcp", "mcp-server", "model-context-protocol", "pipeworx", "twilio"],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/pipeworx-io/mcp-twilio"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"typecheck": "tsc --noEmit"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.7.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.pipeworx-io/twilio",
|
|
4
|
+
"title": "twilio",
|
|
5
|
+
"description": "Twilio MCP Pack — send SMS, list messages, make calls via Twilio REST API.",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"websiteUrl": "https://pipeworx.io/packs/twilio",
|
|
8
|
+
"repository": {
|
|
9
|
+
"url": "https://github.com/pipeworx-io/mcp-twilio",
|
|
10
|
+
"source": "github"
|
|
11
|
+
},
|
|
12
|
+
"remotes": [
|
|
13
|
+
{
|
|
14
|
+
"type": "streamable-http",
|
|
15
|
+
"url": "https://gateway.pipeworx.io/twilio/mcp"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
interface McpToolDefinition {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: 'object';
|
|
6
|
+
properties: Record<string, unknown>;
|
|
7
|
+
required?: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface McpToolExport {
|
|
12
|
+
tools: McpToolDefinition[];
|
|
13
|
+
callTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Twilio MCP Pack — send SMS, list messages, make calls via Twilio REST API.
|
|
18
|
+
*
|
|
19
|
+
* BYO key: pass _accountSid and _authToken as parameters.
|
|
20
|
+
* Auth: HTTP Basic with accountSid:authToken.
|
|
21
|
+
* Note: Twilio uses form-encoded POST bodies, not JSON.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
function twilioHeaders(accountSid: string, authToken: string) {
|
|
26
|
+
const encoded = btoa(`${accountSid}:${authToken}`);
|
|
27
|
+
return { Authorization: `Basic ${encoded}` };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function baseUrl(accountSid: string) {
|
|
31
|
+
return `https://api.twilio.com/2010-04-01/Accounts/${accountSid}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function twilioGet(accountSid: string, authToken: string, path: string) {
|
|
35
|
+
const res = await fetch(`${baseUrl(accountSid)}${path}`, {
|
|
36
|
+
headers: twilioHeaders(accountSid, authToken),
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
const text = await res.text();
|
|
40
|
+
throw new Error(`Twilio API error (${res.status}): ${text}`);
|
|
41
|
+
}
|
|
42
|
+
return res.json();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function twilioPost(accountSid: string, authToken: string, path: string, body: URLSearchParams) {
|
|
46
|
+
const res = await fetch(`${baseUrl(accountSid)}${path}`, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: {
|
|
49
|
+
...twilioHeaders(accountSid, authToken),
|
|
50
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
51
|
+
},
|
|
52
|
+
body: body.toString(),
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok) {
|
|
55
|
+
const text = await res.text();
|
|
56
|
+
throw new Error(`Twilio API error (${res.status}): ${text}`);
|
|
57
|
+
}
|
|
58
|
+
return res.json();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const tools: McpToolExport['tools'] = [
|
|
62
|
+
{
|
|
63
|
+
name: 'twilio_send_sms',
|
|
64
|
+
description: 'Send an SMS message via Twilio. Returns the message SID and status.',
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: 'object' as const,
|
|
67
|
+
properties: {
|
|
68
|
+
_accountSid: { type: 'string', description: 'Twilio Account SID (starts with AC...)' },
|
|
69
|
+
_authToken: { type: 'string', description: 'Twilio Auth Token' },
|
|
70
|
+
to: { type: 'string', description: 'Destination phone number in E.164 format (e.g., +15551234567)' },
|
|
71
|
+
from: { type: 'string', description: 'Twilio phone number to send from in E.164 format' },
|
|
72
|
+
body: { type: 'string', description: 'Message body text (max 1600 characters)' },
|
|
73
|
+
},
|
|
74
|
+
required: ['_accountSid', '_authToken', 'to', 'from', 'body'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'twilio_list_messages',
|
|
79
|
+
description: 'List recent SMS/MMS messages from your Twilio account. Supports filtering by to/from number and pagination.',
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object' as const,
|
|
82
|
+
properties: {
|
|
83
|
+
_accountSid: { type: 'string', description: 'Twilio Account SID' },
|
|
84
|
+
_authToken: { type: 'string', description: 'Twilio Auth Token' },
|
|
85
|
+
limit: { type: 'number', description: 'Max messages to return (default 20, max 100)' },
|
|
86
|
+
to: { type: 'string', description: 'Filter by destination phone number' },
|
|
87
|
+
from: { type: 'string', description: 'Filter by sender phone number' },
|
|
88
|
+
},
|
|
89
|
+
required: ['_accountSid', '_authToken'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'twilio_get_message',
|
|
94
|
+
description: 'Get details of a specific Twilio message by its SID.',
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: 'object' as const,
|
|
97
|
+
properties: {
|
|
98
|
+
_accountSid: { type: 'string', description: 'Twilio Account SID' },
|
|
99
|
+
_authToken: { type: 'string', description: 'Twilio Auth Token' },
|
|
100
|
+
sid: { type: 'string', description: 'Message SID (starts with SM...)' },
|
|
101
|
+
},
|
|
102
|
+
required: ['_accountSid', '_authToken', 'sid'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'twilio_list_calls',
|
|
107
|
+
description: 'List recent phone calls from your Twilio account. Returns call SID, status, duration, and direction.',
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: 'object' as const,
|
|
110
|
+
properties: {
|
|
111
|
+
_accountSid: { type: 'string', description: 'Twilio Account SID' },
|
|
112
|
+
_authToken: { type: 'string', description: 'Twilio Auth Token' },
|
|
113
|
+
limit: { type: 'number', description: 'Max calls to return (default 20, max 100)' },
|
|
114
|
+
},
|
|
115
|
+
required: ['_accountSid', '_authToken'],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'twilio_make_call',
|
|
120
|
+
description: 'Initiate a phone call via Twilio. Requires a TwiML URL or application SID to control call behavior.',
|
|
121
|
+
inputSchema: {
|
|
122
|
+
type: 'object' as const,
|
|
123
|
+
properties: {
|
|
124
|
+
_accountSid: { type: 'string', description: 'Twilio Account SID' },
|
|
125
|
+
_authToken: { type: 'string', description: 'Twilio Auth Token' },
|
|
126
|
+
to: { type: 'string', description: 'Destination phone number in E.164 format' },
|
|
127
|
+
from: { type: 'string', description: 'Twilio phone number to call from in E.164 format' },
|
|
128
|
+
url: { type: 'string', description: 'TwiML URL that controls what happens when the call connects' },
|
|
129
|
+
},
|
|
130
|
+
required: ['_accountSid', '_authToken', 'to', 'from', 'url'],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
async function callTool(name: string, args: Record<string, unknown>): Promise<unknown> {
|
|
136
|
+
const accountSid = args._accountSid as string | undefined;
|
|
137
|
+
const authToken = args._authToken as string | undefined;
|
|
138
|
+
delete args._context;
|
|
139
|
+
delete args._apiKey;
|
|
140
|
+
delete args._accountSid;
|
|
141
|
+
delete args._authToken;
|
|
142
|
+
|
|
143
|
+
if (!accountSid || !authToken) {
|
|
144
|
+
throw new Error('Both _accountSid and _authToken are required for Twilio API access');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
switch (name) {
|
|
148
|
+
case 'twilio_send_sms': {
|
|
149
|
+
const body = new URLSearchParams();
|
|
150
|
+
body.set('To', args.to as string);
|
|
151
|
+
body.set('From', args.from as string);
|
|
152
|
+
body.set('Body', args.body as string);
|
|
153
|
+
return twilioPost(accountSid, authToken, '/Messages.json', body);
|
|
154
|
+
}
|
|
155
|
+
case 'twilio_list_messages': {
|
|
156
|
+
const params = new URLSearchParams();
|
|
157
|
+
params.set('PageSize', String(Math.min(100, (args.limit as number) ?? 20)));
|
|
158
|
+
if (args.to) params.set('To', args.to as string);
|
|
159
|
+
if (args.from) params.set('From', args.from as string);
|
|
160
|
+
return twilioGet(accountSid, authToken, `/Messages.json?${params}`);
|
|
161
|
+
}
|
|
162
|
+
case 'twilio_get_message':
|
|
163
|
+
return twilioGet(accountSid, authToken, `/Messages/${args.sid}.json`);
|
|
164
|
+
case 'twilio_list_calls': {
|
|
165
|
+
const params = new URLSearchParams();
|
|
166
|
+
params.set('PageSize', String(Math.min(100, (args.limit as number) ?? 20)));
|
|
167
|
+
return twilioGet(accountSid, authToken, `/Calls.json?${params}`);
|
|
168
|
+
}
|
|
169
|
+
case 'twilio_make_call': {
|
|
170
|
+
const body = new URLSearchParams();
|
|
171
|
+
body.set('To', args.to as string);
|
|
172
|
+
body.set('From', args.from as string);
|
|
173
|
+
body.set('Url', args.url as string);
|
|
174
|
+
return twilioPost(accountSid, authToken, '/Calls.json', body);
|
|
175
|
+
}
|
|
176
|
+
default:
|
|
177
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export default { tools, callTool, meter: { credits: 15 } } satisfies McpToolExport;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"rootDir": "src",
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|