telnyx-mcp-server-fastmcp 0.1.3__py3-none-any.whl
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.
- telnyx_mcp_server/__init__.py +0 -0
- telnyx_mcp_server/__main__.py +23 -0
- telnyx_mcp_server/config.py +148 -0
- telnyx_mcp_server/mcp.py +148 -0
- telnyx_mcp_server/server.py +497 -0
- telnyx_mcp_server/telnyx/__init__.py +1 -0
- telnyx_mcp_server/telnyx/client.py +363 -0
- telnyx_mcp_server/telnyx/services/__init__.py +0 -0
- telnyx_mcp_server/telnyx/services/assistants.py +155 -0
- telnyx_mcp_server/telnyx/services/call_control.py +217 -0
- telnyx_mcp_server/telnyx/services/cloud_storage.py +289 -0
- telnyx_mcp_server/telnyx/services/connections.py +92 -0
- telnyx_mcp_server/telnyx/services/embeddings.py +52 -0
- telnyx_mcp_server/telnyx/services/messaging.py +93 -0
- telnyx_mcp_server/telnyx/services/messaging_profiles.py +196 -0
- telnyx_mcp_server/telnyx/services/numbers.py +193 -0
- telnyx_mcp_server/telnyx/services/secrets.py +74 -0
- telnyx_mcp_server/tools/__init__.py +126 -0
- telnyx_mcp_server/tools/assistants.py +313 -0
- telnyx_mcp_server/tools/call_control.py +242 -0
- telnyx_mcp_server/tools/cloud_storage.py +183 -0
- telnyx_mcp_server/tools/connections.py +78 -0
- telnyx_mcp_server/tools/embeddings.py +80 -0
- telnyx_mcp_server/tools/messaging.py +57 -0
- telnyx_mcp_server/tools/messaging_profiles.py +123 -0
- telnyx_mcp_server/tools/phone_numbers.py +161 -0
- telnyx_mcp_server/tools/secrets.py +75 -0
- telnyx_mcp_server/tools/sms_conversations.py +455 -0
- telnyx_mcp_server/tools/webhooks.py +111 -0
- telnyx_mcp_server/utils/__init__.py +0 -0
- telnyx_mcp_server/utils/error_handler.py +30 -0
- telnyx_mcp_server/utils/logger.py +32 -0
- telnyx_mcp_server/utils/service.py +33 -0
- telnyx_mcp_server/webhook/__init__.py +25 -0
- telnyx_mcp_server/webhook/handler.py +596 -0
- telnyx_mcp_server/webhook/server.py +369 -0
- telnyx_mcp_server_fastmcp-0.1.3.dist-info/METADATA +430 -0
- telnyx_mcp_server_fastmcp-0.1.3.dist-info/RECORD +40 -0
- telnyx_mcp_server_fastmcp-0.1.3.dist-info/WHEEL +4 -0
- telnyx_mcp_server_fastmcp-0.1.3.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""Cloud storage related MCP tools."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any, Dict, List
|
|
5
|
+
|
|
6
|
+
from ..mcp import mcp
|
|
7
|
+
from ..telnyx.services.cloud_storage import BucketInfo, CloudStorageService
|
|
8
|
+
from ..utils.error_handler import handle_telnyx_error
|
|
9
|
+
from ..utils.logger import get_logger
|
|
10
|
+
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def instantiate_cloud_storage() -> CloudStorageService:
|
|
15
|
+
api_key = os.getenv("TELNYX_API_KEY", "")
|
|
16
|
+
if not api_key:
|
|
17
|
+
raise ValueError("TELNYX_API_KEY environment variable must be set")
|
|
18
|
+
return CloudStorageService(
|
|
19
|
+
access_key_id=api_key,
|
|
20
|
+
secret_access_key=api_key,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@mcp.tool()
|
|
25
|
+
async def cloud_storage_create_bucket(request: Dict[str, Any]) -> str:
|
|
26
|
+
"""Create a new bucket.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
bucket_name: Required. Name of the bucket to create
|
|
30
|
+
region: Required. Region to create the bucket in (us-east-1, us-west-1, us-central-1)
|
|
31
|
+
Returns:
|
|
32
|
+
str: `Success!!` if it uploaded, otherwise returns an exception message
|
|
33
|
+
"""
|
|
34
|
+
try:
|
|
35
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
36
|
+
if not cloud_storage_service:
|
|
37
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
38
|
+
return cloud_storage_service.create_bucket(
|
|
39
|
+
bucket_name=request["bucket_name"], region=request.get("region")
|
|
40
|
+
)
|
|
41
|
+
except Exception as e:
|
|
42
|
+
logger.error(f"Error creating bucket: {e}")
|
|
43
|
+
raise handle_telnyx_error(e)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@mcp.tool()
|
|
47
|
+
async def cloud_storage_list_buckets() -> List[BucketInfo]:
|
|
48
|
+
"""List all buckets across all regions.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
List[Dict[str, str]]: List of dictionaries containing bucket information:
|
|
52
|
+
- name: Name of the bucket
|
|
53
|
+
- region: Region where the bucket is located
|
|
54
|
+
"""
|
|
55
|
+
try:
|
|
56
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
57
|
+
if not cloud_storage_service:
|
|
58
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
59
|
+
return cloud_storage_service.list_buckets()
|
|
60
|
+
except Exception as e:
|
|
61
|
+
logger.error(f"Error listing buckets: {e}")
|
|
62
|
+
raise handle_telnyx_error(e)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@mcp.tool()
|
|
66
|
+
async def cloud_storage_upload_file(request: Dict[str, Any]) -> str:
|
|
67
|
+
"""Upload a file to cloud storage.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
absolute_file_path: Required. Absolute File Path to the file to upload
|
|
71
|
+
object_name: Optional. Name to give the object in storage (defaults to file name)
|
|
72
|
+
bucket_name: Optional. Bucket to upload to (defaults to instance default)
|
|
73
|
+
Returns:
|
|
74
|
+
str: `Success!!` if it uploaded, otherwise returns an exception message
|
|
75
|
+
"""
|
|
76
|
+
try:
|
|
77
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
78
|
+
if not cloud_storage_service:
|
|
79
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
80
|
+
return cloud_storage_service.upload_file(
|
|
81
|
+
file_path=request["absolute_file_path"],
|
|
82
|
+
object_name=request.get("object_name"),
|
|
83
|
+
bucket_name=request.get("bucket_name"),
|
|
84
|
+
)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
logger.error(f"Error uploading file: {e}")
|
|
87
|
+
raise handle_telnyx_error(e)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@mcp.tool()
|
|
91
|
+
async def cloud_storage_download_file(request: Dict[str, Any]) -> str:
|
|
92
|
+
"""Download a file from cloud storage.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
object_name: Required. Name of the object to download
|
|
96
|
+
file_path: Required. Path where to save the downloaded file
|
|
97
|
+
bucket_name: Optional. Bucket to download from (defaults to instance default)
|
|
98
|
+
Returns:
|
|
99
|
+
str: 'Success' if the file was downloaded successfully
|
|
100
|
+
"""
|
|
101
|
+
try:
|
|
102
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
103
|
+
if not cloud_storage_service:
|
|
104
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
105
|
+
cloud_storage_service.download_file(
|
|
106
|
+
object_name=request["object_name"],
|
|
107
|
+
file_path=request["file_path"],
|
|
108
|
+
bucket_name=request.get("bucket_name"),
|
|
109
|
+
)
|
|
110
|
+
return "Success"
|
|
111
|
+
except Exception as e:
|
|
112
|
+
logger.error(f"Error downloading file: {e}")
|
|
113
|
+
raise handle_telnyx_error(e)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@mcp.tool()
|
|
117
|
+
async def cloud_storage_list_objects(request: Dict[str, Any]) -> List[str]:
|
|
118
|
+
"""List objects in a bucket with optional prefix filtering.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
prefix: Optional. Only list objects beginning with this prefix. Defaults to "".
|
|
122
|
+
bucket_name: Optional. Bucket to list from (defaults to instance default)
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
List[str]: List of object names
|
|
126
|
+
"""
|
|
127
|
+
try:
|
|
128
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
129
|
+
if not cloud_storage_service:
|
|
130
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
131
|
+
return cloud_storage_service.list_objects(
|
|
132
|
+
prefix=request.get("prefix", ""),
|
|
133
|
+
bucket_name=request.get("bucket_name"),
|
|
134
|
+
)
|
|
135
|
+
except Exception as e:
|
|
136
|
+
logger.error(f"Error listing objects: {e}")
|
|
137
|
+
raise handle_telnyx_error(e)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@mcp.tool()
|
|
141
|
+
async def cloud_storage_delete_object(request: Dict[str, Any]) -> str:
|
|
142
|
+
"""Delete an object from cloud storage.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
object_name: Required. Name of the object to delete
|
|
146
|
+
bucket_name: Optional. Bucket to delete from (defaults to instance default)
|
|
147
|
+
Returns:
|
|
148
|
+
str: 'Success' if the object was deleted successfully
|
|
149
|
+
"""
|
|
150
|
+
try:
|
|
151
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
152
|
+
if not cloud_storage_service:
|
|
153
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
154
|
+
cloud_storage_service.delete_object(
|
|
155
|
+
object_name=request["object_name"],
|
|
156
|
+
bucket_name=request.get("bucket_name"),
|
|
157
|
+
)
|
|
158
|
+
return "Success"
|
|
159
|
+
except Exception as e:
|
|
160
|
+
logger.error(f"Error deleting object: {e}")
|
|
161
|
+
raise handle_telnyx_error(e)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@mcp.tool()
|
|
165
|
+
async def cloud_storage_get_bucket_location(request: Dict[str, Any]) -> str:
|
|
166
|
+
"""Get the region where a bucket is located.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
bucket_name: Optional. Name of the bucket. If None, uses default bucket.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
str: The region where the bucket is located
|
|
173
|
+
"""
|
|
174
|
+
try:
|
|
175
|
+
cloud_storage_service = instantiate_cloud_storage()
|
|
176
|
+
if not cloud_storage_service:
|
|
177
|
+
raise RuntimeError(f"Cloud storage service not initialized")
|
|
178
|
+
return cloud_storage_service.get_bucket_location(
|
|
179
|
+
bucket_name=request.get("bucket_name")
|
|
180
|
+
)
|
|
181
|
+
except Exception as e:
|
|
182
|
+
logger.error(f"Error getting bucket location: {e}")
|
|
183
|
+
raise handle_telnyx_error(e)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Connection related MCP tools."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from ..mcp import mcp
|
|
6
|
+
from ..telnyx.services.connections import ConnectionsService
|
|
7
|
+
from ..utils.error_handler import handle_telnyx_error
|
|
8
|
+
from ..utils.logger import get_logger
|
|
9
|
+
from ..utils.service import get_authenticated_service
|
|
10
|
+
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@mcp.tool()
|
|
15
|
+
async def list_connections(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
16
|
+
"""List connections.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
page: Optional integer. Page number. Defaults to 1.
|
|
20
|
+
page_size: Optional integer. Page size. Defaults to 20.
|
|
21
|
+
filter_connection_name_contains: Optional. Filter by connection name.
|
|
22
|
+
filter_outbound_voice_profile_id: Optional. Filter by outbound voice profile ID.
|
|
23
|
+
sort: Optional. Sort order (created_at, connection_name, active).
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Dict[str, Any]: Response data
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
service = get_authenticated_service(ConnectionsService)
|
|
30
|
+
return service.list_connections(request)
|
|
31
|
+
except Exception as e:
|
|
32
|
+
logger.error(f"Error listing connections: {e}")
|
|
33
|
+
raise handle_telnyx_error(e)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@mcp.tool()
|
|
37
|
+
async def get_connection(id: str) -> Dict[str, Any]:
|
|
38
|
+
"""Get a connection by ID.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
id: Required. Connection ID.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Dict[str, Any]: Response data
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
service = get_authenticated_service(ConnectionsService)
|
|
48
|
+
return service.get_connection(connection_id=id)
|
|
49
|
+
except Exception as e:
|
|
50
|
+
logger.error(f"Error getting connection: {e}")
|
|
51
|
+
raise handle_telnyx_error(e)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@mcp.tool()
|
|
55
|
+
async def update_connection(id: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
56
|
+
"""Update a connection.
|
|
57
|
+
|
|
58
|
+
Note:
|
|
59
|
+
The Telnyx API does not support updating connections directly.
|
|
60
|
+
Only GET, HEAD, and OPTIONS methods are allowed.
|
|
61
|
+
Please create a new connection with the desired settings instead.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
id: Required. Connection ID.
|
|
65
|
+
data: Required. Update data.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Dict[str, Any]: Response data
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
Exception: The Telnyx API does not support updating connections directly.
|
|
72
|
+
"""
|
|
73
|
+
try:
|
|
74
|
+
service = get_authenticated_service(ConnectionsService)
|
|
75
|
+
return service.update_connection(connection_id=id, data=data)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.error(f"Error updating connection: {e}")
|
|
78
|
+
raise handle_telnyx_error(e)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Embeddings related MCP tools."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from ..mcp import mcp
|
|
6
|
+
from ..telnyx.services.embeddings import EmbeddingsService
|
|
7
|
+
from ..utils.error_handler import handle_telnyx_error
|
|
8
|
+
from ..utils.logger import get_logger
|
|
9
|
+
from ..utils.service import get_authenticated_service
|
|
10
|
+
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@mcp.tool()
|
|
15
|
+
async def list_embedded_buckets() -> Dict[str, Any]:
|
|
16
|
+
"""List user embedded buckets.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
Dict[str, Any]: Response data eg:
|
|
20
|
+
{
|
|
21
|
+
"data": {
|
|
22
|
+
"buckets": [
|
|
23
|
+
"string"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
service = get_authenticated_service(EmbeddingsService)
|
|
30
|
+
return service.list_embedded_buckets()
|
|
31
|
+
except Exception as e:
|
|
32
|
+
logger.error(f"Error listing embedded buckets: {e}")
|
|
33
|
+
raise handle_telnyx_error(e)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@mcp.tool()
|
|
37
|
+
async def embed_url(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
38
|
+
"""Scrape and embed a given URL. For a given website, this tool will scrape
|
|
39
|
+
the content of the pages and save the content in a new bucket. That bucket will
|
|
40
|
+
be automatically embedded.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
url: Required. URL to be scraped and embedded.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Dict[str, Any]: Response data containing bucket information
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
service = get_authenticated_service(EmbeddingsService)
|
|
50
|
+
return service.embed_url(request)
|
|
51
|
+
except Exception as e:
|
|
52
|
+
logger.error(f"Error embedding URL: {e}")
|
|
53
|
+
raise handle_telnyx_error(e)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@mcp.tool()
|
|
57
|
+
async def create_embeddings(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
58
|
+
"""Embed a bucket that containe files.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
bucket_name: Required. Bucket Name. The bucket must exist (string)
|
|
62
|
+
document_chunk_size: Optional. Document Chunk Size (integer)
|
|
63
|
+
document_chunk_overlap_size: Optional. Document Chunk Overlap Size (integer)
|
|
64
|
+
embedding_model: Optional. Supported models (thenlper/gte-large,
|
|
65
|
+
intfloat/multilingual-e5-large, sentence-transformers/all-mpnet-base-v2)
|
|
66
|
+
to vectorize and embed documents.
|
|
67
|
+
loader: Optional. (default, intercom) (string)
|
|
68
|
+
|
|
69
|
+
Agent should prefer only rely on required fields unless user explicitly
|
|
70
|
+
provides values for optional fields.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Dict[str, Any]: Response data containing the embeddings
|
|
74
|
+
"""
|
|
75
|
+
try:
|
|
76
|
+
service = get_authenticated_service(EmbeddingsService)
|
|
77
|
+
return service.create_embeddings(request)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
logger.error(f"Error creating embeddings: {e}")
|
|
80
|
+
raise handle_telnyx_error(e)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Messaging related MCP tools."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from ..mcp import mcp
|
|
6
|
+
from ..telnyx.services.messaging import MessagingService
|
|
7
|
+
from ..utils.error_handler import handle_telnyx_error
|
|
8
|
+
from ..utils.logger import get_logger
|
|
9
|
+
from ..utils.service import get_authenticated_service
|
|
10
|
+
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@mcp.tool()
|
|
15
|
+
async def send_message(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
16
|
+
"""Send a message.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
from_: Required. Sending address (phone number, alphanumeric sender ID, or short code).
|
|
20
|
+
to: Required. Receiving address(es).
|
|
21
|
+
text: Required. Message text.
|
|
22
|
+
messaging_profile_id: Optional. Messaging profile ID.
|
|
23
|
+
subject: Optional. Message subject.
|
|
24
|
+
media_urls: Optional. List of media URLs.
|
|
25
|
+
webhook_url: Optional. Webhook URL.
|
|
26
|
+
webhook_failover_url: Optional. Webhook failover URL.
|
|
27
|
+
use_profile_webhooks: Optional boolean. Whether to use profile webhooks. Defaults to True.
|
|
28
|
+
type: Optional. The protocol for sending the message, either "SMS" or "MMS".
|
|
29
|
+
auto_detect: Optional boolean. Automatically detect if an SMS message is unusually long.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Dict[str, Any]: Response data
|
|
33
|
+
"""
|
|
34
|
+
try:
|
|
35
|
+
service = get_authenticated_service(MessagingService)
|
|
36
|
+
return service.send_message(**request)
|
|
37
|
+
except Exception as e:
|
|
38
|
+
logger.error(f"Error sending message: {e}")
|
|
39
|
+
raise handle_telnyx_error(e)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@mcp.tool()
|
|
43
|
+
async def get_message(message_id: str) -> Dict[str, Any]:
|
|
44
|
+
"""Retrieve a message by ID.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
message_id: The ID of the message to retrieve
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Dict[str, Any]: Response data containing message details
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
service = get_authenticated_service(MessagingService)
|
|
54
|
+
return service.get_message(message_id)
|
|
55
|
+
except Exception as e:
|
|
56
|
+
logger.error(f"Error retrieving message: {e}")
|
|
57
|
+
raise handle_telnyx_error(e)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Messaging profiles related MCP tools."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from ..mcp import mcp
|
|
6
|
+
from ..telnyx.services.messaging_profiles import MessagingProfilesService
|
|
7
|
+
from ..utils.error_handler import handle_telnyx_error
|
|
8
|
+
from ..utils.logger import get_logger
|
|
9
|
+
from ..utils.service import get_authenticated_service
|
|
10
|
+
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@mcp.tool()
|
|
15
|
+
async def list_messaging_profiles(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
16
|
+
"""List messaging profiles.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
page: Optional integer. Page number. Defaults to 1.
|
|
20
|
+
page_size: Optional integer. Page size. Defaults to 20.
|
|
21
|
+
filter_name: Optional. Filter by profile name.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Dict[str, Any]: Response data
|
|
25
|
+
"""
|
|
26
|
+
try:
|
|
27
|
+
service = get_authenticated_service(MessagingProfilesService)
|
|
28
|
+
return service.list_messaging_profiles(**request)
|
|
29
|
+
except Exception as e:
|
|
30
|
+
logger.error(f"Error listing messaging profiles: {e}")
|
|
31
|
+
raise handle_telnyx_error(e)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@mcp.tool()
|
|
35
|
+
async def create_messaging_profile(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
36
|
+
"""Create a messaging profile.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
name: Required. A user friendly name for the messaging profile.
|
|
40
|
+
whitelisted_destinations: Required. List of destinations to which messages are allowed to be sent (ISO 3166-1 alpha-2 country codes). Use ["*"] to allow all destinations.
|
|
41
|
+
enabled: Optional boolean. Specifies whether the messaging profile is enabled. Defaults to True.
|
|
42
|
+
webhook_url: Optional. The URL where webhooks related to this messaging profile will be sent.
|
|
43
|
+
webhook_failover_url: Optional. The failover URL for webhooks if the primary URL fails.
|
|
44
|
+
webhook_api_version: Optional. Webhook format version ("1", "2", or "2010-04-01"). Defaults to "2".
|
|
45
|
+
number_pool_settings: Optional dictionary. Number pool configuration with possible settings:
|
|
46
|
+
- use_pool: Boolean indicating whether to use number pool.
|
|
47
|
+
- sticky_sender: Boolean indicating whether to use sticky sender.
|
|
48
|
+
- pool_weights: Dictionary mapping phone number types to weights.
|
|
49
|
+
url_shortener_settings: Optional dictionary. URL shortener configuration with possible settings:
|
|
50
|
+
- enabled: Boolean indicating whether URL shortening is enabled.
|
|
51
|
+
- domains: List of domains to be shortened.
|
|
52
|
+
alpha_sender: Optional. The alphanumeric sender ID for destinations requiring it.
|
|
53
|
+
daily_spend_limit: Optional. Maximum daily spend in USD before midnight UTC.
|
|
54
|
+
daily_spend_limit_enabled: Optional boolean. Whether to enforce the daily spend limit.
|
|
55
|
+
mms_fall_back_to_sms: Optional boolean. Enables SMS fallback for MMS messages.
|
|
56
|
+
mms_transcoding: Optional boolean. Enables automated resizing of MMS media.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Dict[str, Any]: Response data
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
service = get_authenticated_service(MessagingProfilesService)
|
|
63
|
+
return service.create_messaging_profile(**request)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
logger.error(f"Error creating messaging profile: {e}")
|
|
66
|
+
raise handle_telnyx_error(e)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@mcp.tool()
|
|
70
|
+
async def get_messaging_profile(profile_id: str) -> Dict[str, Any]:
|
|
71
|
+
"""Retrieve a messaging profile by ID.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
profile_id: The ID of the messaging profile to retrieve
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Dict[str, Any]: Response data containing messaging profile details
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
service = get_authenticated_service(MessagingProfilesService)
|
|
81
|
+
return service.get_messaging_profile(profile_id)
|
|
82
|
+
except Exception as e:
|
|
83
|
+
logger.error(f"Error retrieving messaging profile: {e}")
|
|
84
|
+
raise handle_telnyx_error(e)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@mcp.tool()
|
|
88
|
+
async def update_messaging_profile(
|
|
89
|
+
profile_id: str, request: Dict[str, Any]
|
|
90
|
+
) -> Dict[str, Any]:
|
|
91
|
+
"""Update a messaging profile.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
profile_id: Required. The ID of the messaging profile to update.
|
|
95
|
+
name: Optional. A user friendly name for the messaging profile.
|
|
96
|
+
enabled: Optional boolean. Specifies whether the messaging profile is enabled.
|
|
97
|
+
webhook_url: Optional. The URL where webhooks related to this messaging profile will be sent.
|
|
98
|
+
webhook_failover_url: Optional. The failover URL for webhooks if the primary URL fails.
|
|
99
|
+
webhook_api_version: Optional. Webhook format version ("1", "2", or "2010-04-01").
|
|
100
|
+
whitelisted_destinations: Optional list. Destinations to which messages are allowed (ISO 3166-1 alpha-2 country codes). Use ["*"] to allow all destinations.
|
|
101
|
+
v1_secret: Optional. Secret used to authenticate with v1 endpoints.
|
|
102
|
+
number_pool_settings: Optional dictionary. Number pool configuration with possible settings:
|
|
103
|
+
- use_pool: Boolean indicating whether to use number pool.
|
|
104
|
+
- sticky_sender: Boolean indicating whether to use sticky sender.
|
|
105
|
+
- pool_weights: Dictionary mapping phone number types to weights.
|
|
106
|
+
url_shortener_settings: Optional dictionary. URL shortener configuration with possible settings:
|
|
107
|
+
- enabled: Boolean indicating whether URL shortening is enabled.
|
|
108
|
+
- domains: List of domains to be shortened.
|
|
109
|
+
alpha_sender: Optional. The alphanumeric sender ID for destinations requiring it.
|
|
110
|
+
daily_spend_limit: Optional. Maximum daily spend in USD before midnight UTC.
|
|
111
|
+
daily_spend_limit_enabled: Optional boolean. Whether to enforce the daily spend limit.
|
|
112
|
+
mms_fall_back_to_sms: Optional boolean. Enables SMS fallback for MMS messages.
|
|
113
|
+
mms_transcoding: Optional boolean. Enables automated resizing of MMS media.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Dict[str, Any]: Response data
|
|
117
|
+
"""
|
|
118
|
+
try:
|
|
119
|
+
service = get_authenticated_service(MessagingProfilesService)
|
|
120
|
+
return service.update_messaging_profile(profile_id, **request)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
logger.error(f"Error updating messaging profile: {e}")
|
|
123
|
+
raise handle_telnyx_error(e)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""Phone number related MCP tools."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from ..mcp import mcp
|
|
8
|
+
from ..telnyx.services.numbers import NumbersService
|
|
9
|
+
from ..utils.error_handler import handle_telnyx_error
|
|
10
|
+
from ..utils.logger import get_logger
|
|
11
|
+
from ..utils.service import get_authenticated_service
|
|
12
|
+
|
|
13
|
+
logger = get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@mcp.tool()
|
|
17
|
+
async def list_phone_numbers(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
18
|
+
"""List phone numbers.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
page: Optional integer. Page number. Defaults to 1.
|
|
22
|
+
page_size: Optional integer. Page size. Defaults to 20.
|
|
23
|
+
filter_tag: Optional. Filter by phone number tag.
|
|
24
|
+
filter_phone_number: Optional. Filter by phone number.
|
|
25
|
+
filter_status: Optional. Filter by phone number status.
|
|
26
|
+
filter_country_iso_alpha2: Optional. Filter by country ISO alpha-2 code.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Dict[str, Any]: Response data
|
|
30
|
+
"""
|
|
31
|
+
try:
|
|
32
|
+
service = get_authenticated_service(NumbersService)
|
|
33
|
+
return service.list_phone_numbers(**request)
|
|
34
|
+
except Exception as e:
|
|
35
|
+
logger.error(f"Error listing phone numbers: {e}")
|
|
36
|
+
raise handle_telnyx_error(e)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@mcp.tool()
|
|
40
|
+
async def get_phone_number(
|
|
41
|
+
id: str = Field(..., description="Phone number ID as string"),
|
|
42
|
+
) -> Dict[str, Any]:
|
|
43
|
+
"""Get a phone number by ID.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
id: Phone number ID as string
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Dict[str, Any]: Response data containing Number Object(s) (record_type: "phone_number")
|
|
50
|
+
"""
|
|
51
|
+
try:
|
|
52
|
+
service = get_authenticated_service(NumbersService)
|
|
53
|
+
return service.get_phone_number(id=id)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
logger.error(f"Error getting phone number: {e}")
|
|
56
|
+
raise handle_telnyx_error(e)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@mcp.tool()
|
|
60
|
+
async def update_phone_number(
|
|
61
|
+
id: str, request: Dict[str, Any]
|
|
62
|
+
) -> Dict[str, Any]:
|
|
63
|
+
"""Update a phone number.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
id: Required. Phone number ID.
|
|
67
|
+
connection_id: Optional. Connection ID to associate with the number.
|
|
68
|
+
tags: Optional. List of tags to associate with the number.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Dict[str, Any]: Response data
|
|
72
|
+
"""
|
|
73
|
+
try:
|
|
74
|
+
service = get_authenticated_service(NumbersService)
|
|
75
|
+
return service.update_phone_number(id=id, data=request)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.error(f"Error updating phone number: {e}")
|
|
78
|
+
raise handle_telnyx_error(e)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@mcp.tool()
|
|
82
|
+
async def list_available_phone_numbers(
|
|
83
|
+
request: Dict[str, Any],
|
|
84
|
+
) -> Dict[str, Any]:
|
|
85
|
+
"""List available phone numbers.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
page: Optional integer. Page number. Defaults to 1.
|
|
89
|
+
page_size: Optional integer. Page size. Defaults to 20.
|
|
90
|
+
filter_phone_number_starts_with: Optional. Filter numbers starting with pattern.
|
|
91
|
+
filter_phone_number_ends_with: Optional. Filter numbers ending with pattern.
|
|
92
|
+
filter_phone_number_contains: Optional. Filter numbers containing pattern.
|
|
93
|
+
filter_locality: Optional. Filter by locality (city).
|
|
94
|
+
filter_administrative_area: Optional. Filter by administrative area (state).
|
|
95
|
+
filter_country_code: Optional. Filter by country code.
|
|
96
|
+
filter_features: Optional. List of features to filter by.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Dict[str, Any]: Response data
|
|
100
|
+
"""
|
|
101
|
+
try:
|
|
102
|
+
service = get_authenticated_service(NumbersService)
|
|
103
|
+
filter_params = {
|
|
104
|
+
key: value
|
|
105
|
+
for key, value in request.items()
|
|
106
|
+
if key.startswith("filter_")
|
|
107
|
+
}
|
|
108
|
+
base_params = {
|
|
109
|
+
key: value
|
|
110
|
+
for key, value in request.items()
|
|
111
|
+
if not key.startswith("filter_")
|
|
112
|
+
}
|
|
113
|
+
return service.list_available_phone_numbers(
|
|
114
|
+
**base_params, **filter_params
|
|
115
|
+
)
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"Error listing available phone numbers: {e}")
|
|
118
|
+
raise handle_telnyx_error(e)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@mcp.tool()
|
|
122
|
+
async def initiate_phone_number_order(
|
|
123
|
+
request: Dict[str, Any],
|
|
124
|
+
) -> Dict[str, Any]:
|
|
125
|
+
"""Initiate a phone number order.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
phone_number: Required. Phone number to buy.
|
|
129
|
+
connection_id: Optional. Connection ID to associate with the number.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Dict[str, Any]: Response data
|
|
133
|
+
"""
|
|
134
|
+
try:
|
|
135
|
+
service = get_authenticated_service(NumbersService)
|
|
136
|
+
return service.buy_phone_number(**request)
|
|
137
|
+
except Exception as e:
|
|
138
|
+
logger.error(f"Error buying phone number: {e}")
|
|
139
|
+
raise handle_telnyx_error(e)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@mcp.tool()
|
|
143
|
+
async def update_phone_number_messaging_settings(
|
|
144
|
+
id: str, request: Dict[str, Any]
|
|
145
|
+
) -> Dict[str, Any]:
|
|
146
|
+
"""Update the messaging profile and/or messaging product of a phone number.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
id: Required. The phone number ID to update.
|
|
150
|
+
messaging_profile_id: Optional. Configure the messaging profile this phone number is assigned to. Set to null to keep the current value, set to empty string to unassign, or set to a UUID to assign to that messaging profile.
|
|
151
|
+
messaging_product: Optional. Configure the messaging product for this number. Set to null to keep the current value, or set to a product ID to change.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
Dict[str, Any]: Response data
|
|
155
|
+
"""
|
|
156
|
+
try:
|
|
157
|
+
service = get_authenticated_service(NumbersService)
|
|
158
|
+
return service.update_phone_number_messaging_settings(id=id, **request)
|
|
159
|
+
except Exception as e:
|
|
160
|
+
logger.error(f"Error updating phone number messaging settings: {e}")
|
|
161
|
+
raise handle_telnyx_error(e)
|