@tpmjs/tools-cloudflare 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/README.md +58 -0
- package/dist/index.d.ts +350 -0
- package/dist/index.js +772 -0
- package/package.json +114 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @tpmjs/tools-cloudflare
|
|
2
|
+
|
|
3
|
+
Cloudflare API tools for AI agents. Manage DNS records, zones, Workers, KV namespaces, and purge cache.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @tpmjs/tools-cloudflare
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Set your Cloudflare API token and account ID:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export CLOUDFLARE_API_TOKEN="..."
|
|
17
|
+
export CLOUDFLARE_ACCOUNT_ID="..." # Required for Workers and KV operations
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { listZones, listDnsRecords, createDnsRecord } from '@tpmjs/tools-cloudflare';
|
|
24
|
+
|
|
25
|
+
const zones = await listZones.execute({ per_page: 10 });
|
|
26
|
+
const records = await listDnsRecords.execute({ zone_id: 'abc123', type: 'A' });
|
|
27
|
+
const newRecord = await createDnsRecord.execute({
|
|
28
|
+
zone_id: 'abc123',
|
|
29
|
+
type: 'A',
|
|
30
|
+
name: 'app.example.com',
|
|
31
|
+
content: '1.2.3.4',
|
|
32
|
+
proxied: true,
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Tools
|
|
37
|
+
|
|
38
|
+
| Tool | Description |
|
|
39
|
+
|------|-------------|
|
|
40
|
+
| `listZones` | List zones with name and status filters |
|
|
41
|
+
| `getZone` | Get details of a specific zone |
|
|
42
|
+
| `purgeCache` | Purge cached content by URLs or purge everything |
|
|
43
|
+
| `listDnsRecords` | List DNS records with type and name filters |
|
|
44
|
+
| `createDnsRecord` | Create a new DNS record |
|
|
45
|
+
| `updateDnsRecord` | Update an existing DNS record |
|
|
46
|
+
| `deleteDnsRecord` | Delete a DNS record |
|
|
47
|
+
| `listWorkers` | List all Workers scripts |
|
|
48
|
+
| `getWorker` | Get metadata for a Worker script |
|
|
49
|
+
| `deleteWorker` | Delete a Worker script |
|
|
50
|
+
| `listKvNamespaces` | List KV namespaces |
|
|
51
|
+
| `listKvKeys` | List keys in a KV namespace |
|
|
52
|
+
| `getKvValue` | Get a value from KV |
|
|
53
|
+
| `putKvValue` | Write a key-value pair to KV |
|
|
54
|
+
| `deleteKvKey` | Delete a key from KV |
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import * as ai from 'ai';
|
|
2
|
+
|
|
3
|
+
interface ListZonesInput {
|
|
4
|
+
name?: string;
|
|
5
|
+
status?: string;
|
|
6
|
+
per_page?: number;
|
|
7
|
+
}
|
|
8
|
+
interface GetZoneInput {
|
|
9
|
+
zone_id: string;
|
|
10
|
+
}
|
|
11
|
+
interface PurgeCacheInput {
|
|
12
|
+
zone_id: string;
|
|
13
|
+
purge_everything?: boolean;
|
|
14
|
+
files?: string[];
|
|
15
|
+
}
|
|
16
|
+
interface ListDnsRecordsInput {
|
|
17
|
+
zone_id: string;
|
|
18
|
+
type?: string;
|
|
19
|
+
name?: string;
|
|
20
|
+
per_page?: number;
|
|
21
|
+
}
|
|
22
|
+
interface CreateDnsRecordInput {
|
|
23
|
+
zone_id: string;
|
|
24
|
+
type: string;
|
|
25
|
+
name: string;
|
|
26
|
+
content: string;
|
|
27
|
+
ttl?: number;
|
|
28
|
+
proxied?: boolean;
|
|
29
|
+
}
|
|
30
|
+
interface UpdateDnsRecordInput {
|
|
31
|
+
zone_id: string;
|
|
32
|
+
record_id: string;
|
|
33
|
+
type: string;
|
|
34
|
+
name: string;
|
|
35
|
+
content: string;
|
|
36
|
+
ttl?: number;
|
|
37
|
+
proxied?: boolean;
|
|
38
|
+
}
|
|
39
|
+
interface DeleteDnsRecordInput {
|
|
40
|
+
zone_id: string;
|
|
41
|
+
record_id: string;
|
|
42
|
+
}
|
|
43
|
+
interface ListWorkersInput {
|
|
44
|
+
per_page?: number;
|
|
45
|
+
}
|
|
46
|
+
interface GetWorkerInput {
|
|
47
|
+
script_name: string;
|
|
48
|
+
}
|
|
49
|
+
interface DeleteWorkerInput {
|
|
50
|
+
script_name: string;
|
|
51
|
+
}
|
|
52
|
+
interface ListKvNamespacesInput {
|
|
53
|
+
per_page?: number;
|
|
54
|
+
}
|
|
55
|
+
interface ListKvKeysInput {
|
|
56
|
+
namespace_id: string;
|
|
57
|
+
prefix?: string;
|
|
58
|
+
limit?: number;
|
|
59
|
+
}
|
|
60
|
+
interface GetKvValueInput {
|
|
61
|
+
namespace_id: string;
|
|
62
|
+
key_name: string;
|
|
63
|
+
}
|
|
64
|
+
interface PutKvValueInput {
|
|
65
|
+
namespace_id: string;
|
|
66
|
+
key_name: string;
|
|
67
|
+
value: string;
|
|
68
|
+
}
|
|
69
|
+
interface DeleteKvKeyInput {
|
|
70
|
+
namespace_id: string;
|
|
71
|
+
key_name: string;
|
|
72
|
+
}
|
|
73
|
+
declare const listZones: ai.Tool<ListZonesInput, {
|
|
74
|
+
success: boolean;
|
|
75
|
+
data: unknown;
|
|
76
|
+
error?: undefined;
|
|
77
|
+
} | {
|
|
78
|
+
success: boolean;
|
|
79
|
+
error: string;
|
|
80
|
+
data?: undefined;
|
|
81
|
+
}>;
|
|
82
|
+
declare const getZone: ai.Tool<GetZoneInput, {
|
|
83
|
+
success: boolean;
|
|
84
|
+
data: unknown;
|
|
85
|
+
error?: undefined;
|
|
86
|
+
} | {
|
|
87
|
+
success: boolean;
|
|
88
|
+
error: string;
|
|
89
|
+
data?: undefined;
|
|
90
|
+
}>;
|
|
91
|
+
declare const purgeCache: ai.Tool<PurgeCacheInput, {
|
|
92
|
+
success: boolean;
|
|
93
|
+
data: unknown;
|
|
94
|
+
error?: undefined;
|
|
95
|
+
} | {
|
|
96
|
+
success: boolean;
|
|
97
|
+
error: string;
|
|
98
|
+
data?: undefined;
|
|
99
|
+
}>;
|
|
100
|
+
declare const listDnsRecords: ai.Tool<ListDnsRecordsInput, {
|
|
101
|
+
success: boolean;
|
|
102
|
+
data: unknown;
|
|
103
|
+
error?: undefined;
|
|
104
|
+
} | {
|
|
105
|
+
success: boolean;
|
|
106
|
+
error: string;
|
|
107
|
+
data?: undefined;
|
|
108
|
+
}>;
|
|
109
|
+
declare const createDnsRecord: ai.Tool<CreateDnsRecordInput, {
|
|
110
|
+
success: boolean;
|
|
111
|
+
data: unknown;
|
|
112
|
+
error?: undefined;
|
|
113
|
+
} | {
|
|
114
|
+
success: boolean;
|
|
115
|
+
error: string;
|
|
116
|
+
data?: undefined;
|
|
117
|
+
}>;
|
|
118
|
+
declare const updateDnsRecord: ai.Tool<UpdateDnsRecordInput, {
|
|
119
|
+
success: boolean;
|
|
120
|
+
data: unknown;
|
|
121
|
+
error?: undefined;
|
|
122
|
+
} | {
|
|
123
|
+
success: boolean;
|
|
124
|
+
error: string;
|
|
125
|
+
data?: undefined;
|
|
126
|
+
}>;
|
|
127
|
+
declare const deleteDnsRecord: ai.Tool<DeleteDnsRecordInput, {
|
|
128
|
+
success: boolean;
|
|
129
|
+
data: unknown;
|
|
130
|
+
error?: undefined;
|
|
131
|
+
} | {
|
|
132
|
+
success: boolean;
|
|
133
|
+
error: string;
|
|
134
|
+
data?: undefined;
|
|
135
|
+
}>;
|
|
136
|
+
declare const listWorkers: ai.Tool<ListWorkersInput, {
|
|
137
|
+
success: boolean;
|
|
138
|
+
data: unknown;
|
|
139
|
+
error?: undefined;
|
|
140
|
+
} | {
|
|
141
|
+
success: boolean;
|
|
142
|
+
error: string;
|
|
143
|
+
data?: undefined;
|
|
144
|
+
}>;
|
|
145
|
+
declare const getWorker: ai.Tool<GetWorkerInput, {
|
|
146
|
+
success: boolean;
|
|
147
|
+
data: unknown;
|
|
148
|
+
error?: undefined;
|
|
149
|
+
} | {
|
|
150
|
+
success: boolean;
|
|
151
|
+
error: string;
|
|
152
|
+
data?: undefined;
|
|
153
|
+
}>;
|
|
154
|
+
declare const deleteWorker: ai.Tool<DeleteWorkerInput, {
|
|
155
|
+
success: boolean;
|
|
156
|
+
data: unknown;
|
|
157
|
+
error?: undefined;
|
|
158
|
+
} | {
|
|
159
|
+
success: boolean;
|
|
160
|
+
error: string;
|
|
161
|
+
data?: undefined;
|
|
162
|
+
}>;
|
|
163
|
+
declare const listKvNamespaces: ai.Tool<ListKvNamespacesInput, {
|
|
164
|
+
success: boolean;
|
|
165
|
+
data: unknown;
|
|
166
|
+
error?: undefined;
|
|
167
|
+
} | {
|
|
168
|
+
success: boolean;
|
|
169
|
+
error: string;
|
|
170
|
+
data?: undefined;
|
|
171
|
+
}>;
|
|
172
|
+
declare const listKvKeys: ai.Tool<ListKvKeysInput, {
|
|
173
|
+
success: boolean;
|
|
174
|
+
data: unknown;
|
|
175
|
+
error?: undefined;
|
|
176
|
+
} | {
|
|
177
|
+
success: boolean;
|
|
178
|
+
error: string;
|
|
179
|
+
data?: undefined;
|
|
180
|
+
}>;
|
|
181
|
+
declare const getKvValue: ai.Tool<GetKvValueInput, {
|
|
182
|
+
success: boolean;
|
|
183
|
+
data: {
|
|
184
|
+
value: string;
|
|
185
|
+
};
|
|
186
|
+
error?: undefined;
|
|
187
|
+
} | {
|
|
188
|
+
success: boolean;
|
|
189
|
+
error: string;
|
|
190
|
+
data?: undefined;
|
|
191
|
+
}>;
|
|
192
|
+
declare const putKvValue: ai.Tool<PutKvValueInput, {
|
|
193
|
+
success: boolean;
|
|
194
|
+
data: unknown;
|
|
195
|
+
error?: undefined;
|
|
196
|
+
} | {
|
|
197
|
+
success: boolean;
|
|
198
|
+
error: string;
|
|
199
|
+
data?: undefined;
|
|
200
|
+
}>;
|
|
201
|
+
declare const deleteKvKey: ai.Tool<DeleteKvKeyInput, {
|
|
202
|
+
success: boolean;
|
|
203
|
+
data: unknown;
|
|
204
|
+
error?: undefined;
|
|
205
|
+
} | {
|
|
206
|
+
success: boolean;
|
|
207
|
+
error: string;
|
|
208
|
+
data?: undefined;
|
|
209
|
+
}>;
|
|
210
|
+
declare const _default: {
|
|
211
|
+
listZones: ai.Tool<ListZonesInput, {
|
|
212
|
+
success: boolean;
|
|
213
|
+
data: unknown;
|
|
214
|
+
error?: undefined;
|
|
215
|
+
} | {
|
|
216
|
+
success: boolean;
|
|
217
|
+
error: string;
|
|
218
|
+
data?: undefined;
|
|
219
|
+
}>;
|
|
220
|
+
getZone: ai.Tool<GetZoneInput, {
|
|
221
|
+
success: boolean;
|
|
222
|
+
data: unknown;
|
|
223
|
+
error?: undefined;
|
|
224
|
+
} | {
|
|
225
|
+
success: boolean;
|
|
226
|
+
error: string;
|
|
227
|
+
data?: undefined;
|
|
228
|
+
}>;
|
|
229
|
+
purgeCache: ai.Tool<PurgeCacheInput, {
|
|
230
|
+
success: boolean;
|
|
231
|
+
data: unknown;
|
|
232
|
+
error?: undefined;
|
|
233
|
+
} | {
|
|
234
|
+
success: boolean;
|
|
235
|
+
error: string;
|
|
236
|
+
data?: undefined;
|
|
237
|
+
}>;
|
|
238
|
+
listDnsRecords: ai.Tool<ListDnsRecordsInput, {
|
|
239
|
+
success: boolean;
|
|
240
|
+
data: unknown;
|
|
241
|
+
error?: undefined;
|
|
242
|
+
} | {
|
|
243
|
+
success: boolean;
|
|
244
|
+
error: string;
|
|
245
|
+
data?: undefined;
|
|
246
|
+
}>;
|
|
247
|
+
createDnsRecord: ai.Tool<CreateDnsRecordInput, {
|
|
248
|
+
success: boolean;
|
|
249
|
+
data: unknown;
|
|
250
|
+
error?: undefined;
|
|
251
|
+
} | {
|
|
252
|
+
success: boolean;
|
|
253
|
+
error: string;
|
|
254
|
+
data?: undefined;
|
|
255
|
+
}>;
|
|
256
|
+
updateDnsRecord: ai.Tool<UpdateDnsRecordInput, {
|
|
257
|
+
success: boolean;
|
|
258
|
+
data: unknown;
|
|
259
|
+
error?: undefined;
|
|
260
|
+
} | {
|
|
261
|
+
success: boolean;
|
|
262
|
+
error: string;
|
|
263
|
+
data?: undefined;
|
|
264
|
+
}>;
|
|
265
|
+
deleteDnsRecord: ai.Tool<DeleteDnsRecordInput, {
|
|
266
|
+
success: boolean;
|
|
267
|
+
data: unknown;
|
|
268
|
+
error?: undefined;
|
|
269
|
+
} | {
|
|
270
|
+
success: boolean;
|
|
271
|
+
error: string;
|
|
272
|
+
data?: undefined;
|
|
273
|
+
}>;
|
|
274
|
+
listWorkers: ai.Tool<ListWorkersInput, {
|
|
275
|
+
success: boolean;
|
|
276
|
+
data: unknown;
|
|
277
|
+
error?: undefined;
|
|
278
|
+
} | {
|
|
279
|
+
success: boolean;
|
|
280
|
+
error: string;
|
|
281
|
+
data?: undefined;
|
|
282
|
+
}>;
|
|
283
|
+
getWorker: ai.Tool<GetWorkerInput, {
|
|
284
|
+
success: boolean;
|
|
285
|
+
data: unknown;
|
|
286
|
+
error?: undefined;
|
|
287
|
+
} | {
|
|
288
|
+
success: boolean;
|
|
289
|
+
error: string;
|
|
290
|
+
data?: undefined;
|
|
291
|
+
}>;
|
|
292
|
+
deleteWorker: ai.Tool<DeleteWorkerInput, {
|
|
293
|
+
success: boolean;
|
|
294
|
+
data: unknown;
|
|
295
|
+
error?: undefined;
|
|
296
|
+
} | {
|
|
297
|
+
success: boolean;
|
|
298
|
+
error: string;
|
|
299
|
+
data?: undefined;
|
|
300
|
+
}>;
|
|
301
|
+
listKvNamespaces: ai.Tool<ListKvNamespacesInput, {
|
|
302
|
+
success: boolean;
|
|
303
|
+
data: unknown;
|
|
304
|
+
error?: undefined;
|
|
305
|
+
} | {
|
|
306
|
+
success: boolean;
|
|
307
|
+
error: string;
|
|
308
|
+
data?: undefined;
|
|
309
|
+
}>;
|
|
310
|
+
listKvKeys: ai.Tool<ListKvKeysInput, {
|
|
311
|
+
success: boolean;
|
|
312
|
+
data: unknown;
|
|
313
|
+
error?: undefined;
|
|
314
|
+
} | {
|
|
315
|
+
success: boolean;
|
|
316
|
+
error: string;
|
|
317
|
+
data?: undefined;
|
|
318
|
+
}>;
|
|
319
|
+
getKvValue: ai.Tool<GetKvValueInput, {
|
|
320
|
+
success: boolean;
|
|
321
|
+
data: {
|
|
322
|
+
value: string;
|
|
323
|
+
};
|
|
324
|
+
error?: undefined;
|
|
325
|
+
} | {
|
|
326
|
+
success: boolean;
|
|
327
|
+
error: string;
|
|
328
|
+
data?: undefined;
|
|
329
|
+
}>;
|
|
330
|
+
putKvValue: ai.Tool<PutKvValueInput, {
|
|
331
|
+
success: boolean;
|
|
332
|
+
data: unknown;
|
|
333
|
+
error?: undefined;
|
|
334
|
+
} | {
|
|
335
|
+
success: boolean;
|
|
336
|
+
error: string;
|
|
337
|
+
data?: undefined;
|
|
338
|
+
}>;
|
|
339
|
+
deleteKvKey: ai.Tool<DeleteKvKeyInput, {
|
|
340
|
+
success: boolean;
|
|
341
|
+
data: unknown;
|
|
342
|
+
error?: undefined;
|
|
343
|
+
} | {
|
|
344
|
+
success: boolean;
|
|
345
|
+
error: string;
|
|
346
|
+
data?: undefined;
|
|
347
|
+
}>;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
export { createDnsRecord, _default as default, deleteDnsRecord, deleteKvKey, deleteWorker, getKvValue, getWorker, getZone, listDnsRecords, listKvKeys, listKvNamespaces, listWorkers, listZones, purgeCache, putKvValue, updateDnsRecord };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
import { tool, jsonSchema } from 'ai';
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
var BASE_URL = "https://api.cloudflare.com/client/v4";
|
|
5
|
+
function getApiToken() {
|
|
6
|
+
const token = process.env.CLOUDFLARE_API_TOKEN;
|
|
7
|
+
if (!token) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
"CLOUDFLARE_API_TOKEN environment variable is required. Get your token at https://dash.cloudflare.com/profile/api-tokens"
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
return token;
|
|
13
|
+
}
|
|
14
|
+
function getAccountId() {
|
|
15
|
+
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
16
|
+
if (!accountId) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
"CLOUDFLARE_ACCOUNT_ID environment variable is required. Find it at https://dash.cloudflare.com/"
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return accountId;
|
|
22
|
+
}
|
|
23
|
+
function buildQueryString(params) {
|
|
24
|
+
const searchParams = new URLSearchParams();
|
|
25
|
+
for (const [key, value] of Object.entries(params)) {
|
|
26
|
+
if (value !== void 0 && value !== null) {
|
|
27
|
+
searchParams.append(key, String(value));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const query = searchParams.toString();
|
|
31
|
+
return query ? `?${query}` : "";
|
|
32
|
+
}
|
|
33
|
+
async function apiRequest(endpoint, options = {}) {
|
|
34
|
+
const token = getApiToken();
|
|
35
|
+
const url = `${BASE_URL}${endpoint}`;
|
|
36
|
+
const response = await fetch(url, {
|
|
37
|
+
...options,
|
|
38
|
+
headers: {
|
|
39
|
+
Authorization: `Bearer ${token}`,
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
...options.headers
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
const data = await response.json();
|
|
45
|
+
if (!data.success) {
|
|
46
|
+
const errorMessages = data.errors.map((err) => `[${err.code}] ${err.message}`).join("; ");
|
|
47
|
+
throw new Error(`Cloudflare API error: ${errorMessages}`);
|
|
48
|
+
}
|
|
49
|
+
return data.result;
|
|
50
|
+
}
|
|
51
|
+
async function apiRequestRaw(endpoint, options = {}) {
|
|
52
|
+
const token = getApiToken();
|
|
53
|
+
const url = `${BASE_URL}${endpoint}`;
|
|
54
|
+
const response = await fetch(url, {
|
|
55
|
+
...options,
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: `Bearer ${token}`,
|
|
58
|
+
...options.headers
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
const errorText = await response.text();
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Cloudflare API error: ${response.status} ${response.statusText} - ${errorText}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return response.text();
|
|
68
|
+
}
|
|
69
|
+
function handleApiError(error) {
|
|
70
|
+
if (error instanceof Error) {
|
|
71
|
+
return error.message;
|
|
72
|
+
}
|
|
73
|
+
return "An unknown error occurred";
|
|
74
|
+
}
|
|
75
|
+
var listZones = tool({
|
|
76
|
+
description: "List all zones (domains) in your Cloudflare account with optional filtering",
|
|
77
|
+
inputSchema: jsonSchema({
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: {
|
|
80
|
+
name: {
|
|
81
|
+
type: "string",
|
|
82
|
+
description: "Filter zones by name (domain)"
|
|
83
|
+
},
|
|
84
|
+
status: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: 'Filter by zone status (e.g., "active", "pending")'
|
|
87
|
+
},
|
|
88
|
+
per_page: {
|
|
89
|
+
type: "number",
|
|
90
|
+
description: "Number of results per page (default: 20, max: 50)"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
additionalProperties: false
|
|
94
|
+
}),
|
|
95
|
+
execute: async ({ name, status, per_page }) => {
|
|
96
|
+
try {
|
|
97
|
+
const queryParams = {};
|
|
98
|
+
if (name) queryParams.name = name;
|
|
99
|
+
if (status) queryParams.status = status;
|
|
100
|
+
if (per_page) queryParams.per_page = per_page;
|
|
101
|
+
const query = buildQueryString(queryParams);
|
|
102
|
+
const result = await apiRequest(`/zones${query}`);
|
|
103
|
+
return {
|
|
104
|
+
success: true,
|
|
105
|
+
data: result
|
|
106
|
+
};
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: handleApiError(error)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
var getZone = tool({
|
|
116
|
+
description: "Get detailed information about a specific zone",
|
|
117
|
+
inputSchema: jsonSchema({
|
|
118
|
+
type: "object",
|
|
119
|
+
properties: {
|
|
120
|
+
zone_id: {
|
|
121
|
+
type: "string",
|
|
122
|
+
description: "The zone ID to retrieve"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
required: ["zone_id"],
|
|
126
|
+
additionalProperties: false
|
|
127
|
+
}),
|
|
128
|
+
execute: async ({ zone_id }) => {
|
|
129
|
+
try {
|
|
130
|
+
if (!zone_id) {
|
|
131
|
+
throw new Error("zone_id is required");
|
|
132
|
+
}
|
|
133
|
+
const result = await apiRequest(`/zones/${zone_id}`);
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
data: result
|
|
137
|
+
};
|
|
138
|
+
} catch (error) {
|
|
139
|
+
return {
|
|
140
|
+
success: false,
|
|
141
|
+
error: handleApiError(error)
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
var purgeCache = tool({
|
|
147
|
+
description: "Purge cached content from Cloudflare CDN for a zone (all files or specific URLs)",
|
|
148
|
+
inputSchema: jsonSchema({
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
zone_id: {
|
|
152
|
+
type: "string",
|
|
153
|
+
description: "The zone ID to purge cache for"
|
|
154
|
+
},
|
|
155
|
+
purge_everything: {
|
|
156
|
+
type: "boolean",
|
|
157
|
+
description: "Purge all cached content (default: false)"
|
|
158
|
+
},
|
|
159
|
+
files: {
|
|
160
|
+
type: "array",
|
|
161
|
+
items: { type: "string" },
|
|
162
|
+
description: "Array of URLs to purge (use if purge_everything is false)"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
required: ["zone_id"],
|
|
166
|
+
additionalProperties: false
|
|
167
|
+
}),
|
|
168
|
+
execute: async ({ zone_id, purge_everything, files }) => {
|
|
169
|
+
try {
|
|
170
|
+
if (!zone_id) {
|
|
171
|
+
throw new Error("zone_id is required");
|
|
172
|
+
}
|
|
173
|
+
const body = {};
|
|
174
|
+
if (purge_everything) {
|
|
175
|
+
body.purge_everything = true;
|
|
176
|
+
} else if (files && files.length > 0) {
|
|
177
|
+
body.files = files;
|
|
178
|
+
} else {
|
|
179
|
+
throw new Error(
|
|
180
|
+
"Either purge_everything must be true or files must be provided"
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
const result = await apiRequest(
|
|
184
|
+
`/zones/${zone_id}/purge_cache`,
|
|
185
|
+
{
|
|
186
|
+
method: "POST",
|
|
187
|
+
body: JSON.stringify(body)
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
return {
|
|
191
|
+
success: true,
|
|
192
|
+
data: result
|
|
193
|
+
};
|
|
194
|
+
} catch (error) {
|
|
195
|
+
return {
|
|
196
|
+
success: false,
|
|
197
|
+
error: handleApiError(error)
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
var listDnsRecords = tool({
|
|
203
|
+
description: "List DNS records for a specific zone with optional filtering",
|
|
204
|
+
inputSchema: jsonSchema({
|
|
205
|
+
type: "object",
|
|
206
|
+
properties: {
|
|
207
|
+
zone_id: {
|
|
208
|
+
type: "string",
|
|
209
|
+
description: "The zone ID to list DNS records for"
|
|
210
|
+
},
|
|
211
|
+
type: {
|
|
212
|
+
type: "string",
|
|
213
|
+
description: "Filter by record type (A, AAAA, CNAME, MX, TXT, etc.)"
|
|
214
|
+
},
|
|
215
|
+
name: {
|
|
216
|
+
type: "string",
|
|
217
|
+
description: 'Filter by record name (e.g., "example.com")'
|
|
218
|
+
},
|
|
219
|
+
per_page: {
|
|
220
|
+
type: "number",
|
|
221
|
+
description: "Number of results per page (default: 20, max: 100)"
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
required: ["zone_id"],
|
|
225
|
+
additionalProperties: false
|
|
226
|
+
}),
|
|
227
|
+
execute: async ({ zone_id, type, name, per_page }) => {
|
|
228
|
+
try {
|
|
229
|
+
if (!zone_id) {
|
|
230
|
+
throw new Error("zone_id is required");
|
|
231
|
+
}
|
|
232
|
+
const queryParams = {};
|
|
233
|
+
if (type) queryParams.type = type;
|
|
234
|
+
if (name) queryParams.name = name;
|
|
235
|
+
if (per_page) queryParams.per_page = per_page;
|
|
236
|
+
const query = buildQueryString(queryParams);
|
|
237
|
+
const result = await apiRequest(
|
|
238
|
+
`/zones/${zone_id}/dns_records${query}`
|
|
239
|
+
);
|
|
240
|
+
return {
|
|
241
|
+
success: true,
|
|
242
|
+
data: result
|
|
243
|
+
};
|
|
244
|
+
} catch (error) {
|
|
245
|
+
return {
|
|
246
|
+
success: false,
|
|
247
|
+
error: handleApiError(error)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
var createDnsRecord = tool({
|
|
253
|
+
description: "Create a new DNS record in a zone",
|
|
254
|
+
inputSchema: jsonSchema({
|
|
255
|
+
type: "object",
|
|
256
|
+
properties: {
|
|
257
|
+
zone_id: {
|
|
258
|
+
type: "string",
|
|
259
|
+
description: "The zone ID to create the DNS record in"
|
|
260
|
+
},
|
|
261
|
+
type: {
|
|
262
|
+
type: "string",
|
|
263
|
+
description: "DNS record type (A, AAAA, CNAME, MX, TXT, etc.)"
|
|
264
|
+
},
|
|
265
|
+
name: {
|
|
266
|
+
type: "string",
|
|
267
|
+
description: 'DNS record name (e.g., "example.com" or "subdomain.example.com")'
|
|
268
|
+
},
|
|
269
|
+
content: {
|
|
270
|
+
type: "string",
|
|
271
|
+
description: "DNS record content (e.g., IP address for A record, domain for CNAME)"
|
|
272
|
+
},
|
|
273
|
+
ttl: {
|
|
274
|
+
type: "number",
|
|
275
|
+
description: "Time to live in seconds (1 = automatic, default: 1)"
|
|
276
|
+
},
|
|
277
|
+
proxied: {
|
|
278
|
+
type: "boolean",
|
|
279
|
+
description: "Whether the record is proxied through Cloudflare (default: false)"
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
required: ["zone_id", "type", "name", "content"],
|
|
283
|
+
additionalProperties: false
|
|
284
|
+
}),
|
|
285
|
+
execute: async ({ zone_id, type, name, content, ttl, proxied }) => {
|
|
286
|
+
try {
|
|
287
|
+
if (!zone_id || !type || !name || !content) {
|
|
288
|
+
throw new Error("zone_id, type, name, and content are required");
|
|
289
|
+
}
|
|
290
|
+
const body = {
|
|
291
|
+
type,
|
|
292
|
+
name,
|
|
293
|
+
content
|
|
294
|
+
};
|
|
295
|
+
if (ttl !== void 0) body.ttl = ttl;
|
|
296
|
+
if (proxied !== void 0) body.proxied = proxied;
|
|
297
|
+
const result = await apiRequest(
|
|
298
|
+
`/zones/${zone_id}/dns_records`,
|
|
299
|
+
{
|
|
300
|
+
method: "POST",
|
|
301
|
+
body: JSON.stringify(body)
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
return {
|
|
305
|
+
success: true,
|
|
306
|
+
data: result
|
|
307
|
+
};
|
|
308
|
+
} catch (error) {
|
|
309
|
+
return {
|
|
310
|
+
success: false,
|
|
311
|
+
error: handleApiError(error)
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
var updateDnsRecord = tool({
|
|
317
|
+
description: "Update an existing DNS record",
|
|
318
|
+
inputSchema: jsonSchema({
|
|
319
|
+
type: "object",
|
|
320
|
+
properties: {
|
|
321
|
+
zone_id: {
|
|
322
|
+
type: "string",
|
|
323
|
+
description: "The zone ID containing the DNS record"
|
|
324
|
+
},
|
|
325
|
+
record_id: {
|
|
326
|
+
type: "string",
|
|
327
|
+
description: "The DNS record ID to update"
|
|
328
|
+
},
|
|
329
|
+
type: {
|
|
330
|
+
type: "string",
|
|
331
|
+
description: "DNS record type (A, AAAA, CNAME, MX, TXT, etc.)"
|
|
332
|
+
},
|
|
333
|
+
name: {
|
|
334
|
+
type: "string",
|
|
335
|
+
description: 'DNS record name (e.g., "example.com" or "subdomain.example.com")'
|
|
336
|
+
},
|
|
337
|
+
content: {
|
|
338
|
+
type: "string",
|
|
339
|
+
description: "DNS record content (e.g., IP address for A record, domain for CNAME)"
|
|
340
|
+
},
|
|
341
|
+
ttl: {
|
|
342
|
+
type: "number",
|
|
343
|
+
description: "Time to live in seconds (1 = automatic)"
|
|
344
|
+
},
|
|
345
|
+
proxied: {
|
|
346
|
+
type: "boolean",
|
|
347
|
+
description: "Whether the record is proxied through Cloudflare"
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
required: ["zone_id", "record_id", "type", "name", "content"],
|
|
351
|
+
additionalProperties: false
|
|
352
|
+
}),
|
|
353
|
+
execute: async ({
|
|
354
|
+
zone_id,
|
|
355
|
+
record_id,
|
|
356
|
+
type,
|
|
357
|
+
name,
|
|
358
|
+
content,
|
|
359
|
+
ttl,
|
|
360
|
+
proxied
|
|
361
|
+
}) => {
|
|
362
|
+
try {
|
|
363
|
+
if (!zone_id || !record_id || !type || !name || !content) {
|
|
364
|
+
throw new Error(
|
|
365
|
+
"zone_id, record_id, type, name, and content are required"
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
const body = {
|
|
369
|
+
type,
|
|
370
|
+
name,
|
|
371
|
+
content
|
|
372
|
+
};
|
|
373
|
+
if (ttl !== void 0) body.ttl = ttl;
|
|
374
|
+
if (proxied !== void 0) body.proxied = proxied;
|
|
375
|
+
const result = await apiRequest(
|
|
376
|
+
`/zones/${zone_id}/dns_records/${record_id}`,
|
|
377
|
+
{
|
|
378
|
+
method: "PUT",
|
|
379
|
+
body: JSON.stringify(body)
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
return {
|
|
383
|
+
success: true,
|
|
384
|
+
data: result
|
|
385
|
+
};
|
|
386
|
+
} catch (error) {
|
|
387
|
+
return {
|
|
388
|
+
success: false,
|
|
389
|
+
error: handleApiError(error)
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
var deleteDnsRecord = tool({
|
|
395
|
+
description: "Delete a DNS record from a zone",
|
|
396
|
+
inputSchema: jsonSchema({
|
|
397
|
+
type: "object",
|
|
398
|
+
properties: {
|
|
399
|
+
zone_id: {
|
|
400
|
+
type: "string",
|
|
401
|
+
description: "The zone ID containing the DNS record"
|
|
402
|
+
},
|
|
403
|
+
record_id: {
|
|
404
|
+
type: "string",
|
|
405
|
+
description: "The DNS record ID to delete"
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
required: ["zone_id", "record_id"],
|
|
409
|
+
additionalProperties: false
|
|
410
|
+
}),
|
|
411
|
+
execute: async ({ zone_id, record_id }) => {
|
|
412
|
+
try {
|
|
413
|
+
if (!zone_id || !record_id) {
|
|
414
|
+
throw new Error("zone_id and record_id are required");
|
|
415
|
+
}
|
|
416
|
+
const result = await apiRequest(
|
|
417
|
+
`/zones/${zone_id}/dns_records/${record_id}`,
|
|
418
|
+
{
|
|
419
|
+
method: "DELETE"
|
|
420
|
+
}
|
|
421
|
+
);
|
|
422
|
+
return {
|
|
423
|
+
success: true,
|
|
424
|
+
data: result
|
|
425
|
+
};
|
|
426
|
+
} catch (error) {
|
|
427
|
+
return {
|
|
428
|
+
success: false,
|
|
429
|
+
error: handleApiError(error)
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
var listWorkers = tool({
|
|
435
|
+
description: "List all Cloudflare Workers scripts in your account",
|
|
436
|
+
inputSchema: jsonSchema({
|
|
437
|
+
type: "object",
|
|
438
|
+
properties: {
|
|
439
|
+
per_page: {
|
|
440
|
+
type: "number",
|
|
441
|
+
description: "Number of results per page (default: 20)"
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
additionalProperties: false
|
|
445
|
+
}),
|
|
446
|
+
execute: async ({ per_page }) => {
|
|
447
|
+
try {
|
|
448
|
+
const accountId = getAccountId();
|
|
449
|
+
const queryParams = {};
|
|
450
|
+
if (per_page) queryParams.per_page = per_page;
|
|
451
|
+
const query = buildQueryString(queryParams);
|
|
452
|
+
const result = await apiRequest(
|
|
453
|
+
`/accounts/${accountId}/workers/scripts${query}`
|
|
454
|
+
);
|
|
455
|
+
return {
|
|
456
|
+
success: true,
|
|
457
|
+
data: result
|
|
458
|
+
};
|
|
459
|
+
} catch (error) {
|
|
460
|
+
return {
|
|
461
|
+
success: false,
|
|
462
|
+
error: handleApiError(error)
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
var getWorker = tool({
|
|
468
|
+
description: "Get settings and metadata for a specific Cloudflare Worker",
|
|
469
|
+
inputSchema: jsonSchema({
|
|
470
|
+
type: "object",
|
|
471
|
+
properties: {
|
|
472
|
+
script_name: {
|
|
473
|
+
type: "string",
|
|
474
|
+
description: "The name of the Worker script"
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
required: ["script_name"],
|
|
478
|
+
additionalProperties: false
|
|
479
|
+
}),
|
|
480
|
+
execute: async ({ script_name }) => {
|
|
481
|
+
try {
|
|
482
|
+
if (!script_name) {
|
|
483
|
+
throw new Error("script_name is required");
|
|
484
|
+
}
|
|
485
|
+
const accountId = getAccountId();
|
|
486
|
+
const result = await apiRequest(
|
|
487
|
+
`/accounts/${accountId}/workers/scripts/${script_name}/settings`
|
|
488
|
+
);
|
|
489
|
+
return {
|
|
490
|
+
success: true,
|
|
491
|
+
data: result
|
|
492
|
+
};
|
|
493
|
+
} catch (error) {
|
|
494
|
+
return {
|
|
495
|
+
success: false,
|
|
496
|
+
error: handleApiError(error)
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
var deleteWorker = tool({
|
|
502
|
+
description: "Delete a Cloudflare Worker script",
|
|
503
|
+
inputSchema: jsonSchema({
|
|
504
|
+
type: "object",
|
|
505
|
+
properties: {
|
|
506
|
+
script_name: {
|
|
507
|
+
type: "string",
|
|
508
|
+
description: "The name of the Worker script to delete"
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
required: ["script_name"],
|
|
512
|
+
additionalProperties: false
|
|
513
|
+
}),
|
|
514
|
+
execute: async ({ script_name }) => {
|
|
515
|
+
try {
|
|
516
|
+
if (!script_name) {
|
|
517
|
+
throw new Error("script_name is required");
|
|
518
|
+
}
|
|
519
|
+
const accountId = getAccountId();
|
|
520
|
+
const result = await apiRequest(
|
|
521
|
+
`/accounts/${accountId}/workers/scripts/${script_name}`,
|
|
522
|
+
{
|
|
523
|
+
method: "DELETE"
|
|
524
|
+
}
|
|
525
|
+
);
|
|
526
|
+
return {
|
|
527
|
+
success: true,
|
|
528
|
+
data: result
|
|
529
|
+
};
|
|
530
|
+
} catch (error) {
|
|
531
|
+
return {
|
|
532
|
+
success: false,
|
|
533
|
+
error: handleApiError(error)
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
var listKvNamespaces = tool({
|
|
539
|
+
description: "List all KV namespaces in your Cloudflare account",
|
|
540
|
+
inputSchema: jsonSchema({
|
|
541
|
+
type: "object",
|
|
542
|
+
properties: {
|
|
543
|
+
per_page: {
|
|
544
|
+
type: "number",
|
|
545
|
+
description: "Number of results per page (default: 20)"
|
|
546
|
+
}
|
|
547
|
+
},
|
|
548
|
+
additionalProperties: false
|
|
549
|
+
}),
|
|
550
|
+
execute: async ({ per_page }) => {
|
|
551
|
+
try {
|
|
552
|
+
const accountId = getAccountId();
|
|
553
|
+
const queryParams = {};
|
|
554
|
+
if (per_page) queryParams.per_page = per_page;
|
|
555
|
+
const query = buildQueryString(queryParams);
|
|
556
|
+
const result = await apiRequest(
|
|
557
|
+
`/accounts/${accountId}/storage/kv/namespaces${query}`
|
|
558
|
+
);
|
|
559
|
+
return {
|
|
560
|
+
success: true,
|
|
561
|
+
data: result
|
|
562
|
+
};
|
|
563
|
+
} catch (error) {
|
|
564
|
+
return {
|
|
565
|
+
success: false,
|
|
566
|
+
error: handleApiError(error)
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
var listKvKeys = tool({
|
|
572
|
+
description: "List all keys in a KV namespace with optional filtering",
|
|
573
|
+
inputSchema: jsonSchema({
|
|
574
|
+
type: "object",
|
|
575
|
+
properties: {
|
|
576
|
+
namespace_id: {
|
|
577
|
+
type: "string",
|
|
578
|
+
description: "The KV namespace ID"
|
|
579
|
+
},
|
|
580
|
+
prefix: {
|
|
581
|
+
type: "string",
|
|
582
|
+
description: "Filter keys by prefix"
|
|
583
|
+
},
|
|
584
|
+
limit: {
|
|
585
|
+
type: "number",
|
|
586
|
+
description: "Maximum number of keys to return (default: 1000)"
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
required: ["namespace_id"],
|
|
590
|
+
additionalProperties: false
|
|
591
|
+
}),
|
|
592
|
+
execute: async ({ namespace_id, prefix, limit }) => {
|
|
593
|
+
try {
|
|
594
|
+
if (!namespace_id) {
|
|
595
|
+
throw new Error("namespace_id is required");
|
|
596
|
+
}
|
|
597
|
+
const accountId = getAccountId();
|
|
598
|
+
const queryParams = {};
|
|
599
|
+
if (prefix) queryParams.prefix = prefix;
|
|
600
|
+
if (limit) queryParams.limit = limit;
|
|
601
|
+
const query = buildQueryString(queryParams);
|
|
602
|
+
const result = await apiRequest(
|
|
603
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespace_id}/keys${query}`
|
|
604
|
+
);
|
|
605
|
+
return {
|
|
606
|
+
success: true,
|
|
607
|
+
data: result
|
|
608
|
+
};
|
|
609
|
+
} catch (error) {
|
|
610
|
+
return {
|
|
611
|
+
success: false,
|
|
612
|
+
error: handleApiError(error)
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
var getKvValue = tool({
|
|
618
|
+
description: "Get the value of a key from a KV namespace",
|
|
619
|
+
inputSchema: jsonSchema({
|
|
620
|
+
type: "object",
|
|
621
|
+
properties: {
|
|
622
|
+
namespace_id: {
|
|
623
|
+
type: "string",
|
|
624
|
+
description: "The KV namespace ID"
|
|
625
|
+
},
|
|
626
|
+
key_name: {
|
|
627
|
+
type: "string",
|
|
628
|
+
description: "The key name to retrieve"
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
required: ["namespace_id", "key_name"],
|
|
632
|
+
additionalProperties: false
|
|
633
|
+
}),
|
|
634
|
+
execute: async ({ namespace_id, key_name }) => {
|
|
635
|
+
try {
|
|
636
|
+
if (!namespace_id || !key_name) {
|
|
637
|
+
throw new Error("namespace_id and key_name are required");
|
|
638
|
+
}
|
|
639
|
+
const accountId = getAccountId();
|
|
640
|
+
const value = await apiRequestRaw(
|
|
641
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespace_id}/values/${key_name}`
|
|
642
|
+
);
|
|
643
|
+
return {
|
|
644
|
+
success: true,
|
|
645
|
+
data: { value }
|
|
646
|
+
};
|
|
647
|
+
} catch (error) {
|
|
648
|
+
return {
|
|
649
|
+
success: false,
|
|
650
|
+
error: handleApiError(error)
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
var putKvValue = tool({
|
|
656
|
+
description: "Set the value of a key in a KV namespace",
|
|
657
|
+
inputSchema: jsonSchema({
|
|
658
|
+
type: "object",
|
|
659
|
+
properties: {
|
|
660
|
+
namespace_id: {
|
|
661
|
+
type: "string",
|
|
662
|
+
description: "The KV namespace ID"
|
|
663
|
+
},
|
|
664
|
+
key_name: {
|
|
665
|
+
type: "string",
|
|
666
|
+
description: "The key name to set"
|
|
667
|
+
},
|
|
668
|
+
value: {
|
|
669
|
+
type: "string",
|
|
670
|
+
description: "The value to store (will be stored as text)"
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
required: ["namespace_id", "key_name", "value"],
|
|
674
|
+
additionalProperties: false
|
|
675
|
+
}),
|
|
676
|
+
execute: async ({ namespace_id, key_name, value }) => {
|
|
677
|
+
try {
|
|
678
|
+
if (!namespace_id || !key_name || value === void 0) {
|
|
679
|
+
throw new Error("namespace_id, key_name, and value are required");
|
|
680
|
+
}
|
|
681
|
+
const accountId = getAccountId();
|
|
682
|
+
const token = getApiToken();
|
|
683
|
+
const url = `${BASE_URL}/accounts/${accountId}/storage/kv/namespaces/${namespace_id}/values/${key_name}`;
|
|
684
|
+
const response = await fetch(url, {
|
|
685
|
+
method: "PUT",
|
|
686
|
+
headers: {
|
|
687
|
+
Authorization: `Bearer ${token}`,
|
|
688
|
+
"Content-Type": "text/plain"
|
|
689
|
+
},
|
|
690
|
+
body: value
|
|
691
|
+
});
|
|
692
|
+
const data = await response.json();
|
|
693
|
+
if (!data.success) {
|
|
694
|
+
const errorMessages = data.errors.map((err) => `[${err.code}] ${err.message}`).join("; ");
|
|
695
|
+
throw new Error(`Cloudflare API error: ${errorMessages}`);
|
|
696
|
+
}
|
|
697
|
+
return {
|
|
698
|
+
success: true,
|
|
699
|
+
data: data.result
|
|
700
|
+
};
|
|
701
|
+
} catch (error) {
|
|
702
|
+
return {
|
|
703
|
+
success: false,
|
|
704
|
+
error: handleApiError(error)
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
var deleteKvKey = tool({
|
|
710
|
+
description: "Delete a key from a KV namespace",
|
|
711
|
+
inputSchema: jsonSchema({
|
|
712
|
+
type: "object",
|
|
713
|
+
properties: {
|
|
714
|
+
namespace_id: {
|
|
715
|
+
type: "string",
|
|
716
|
+
description: "The KV namespace ID"
|
|
717
|
+
},
|
|
718
|
+
key_name: {
|
|
719
|
+
type: "string",
|
|
720
|
+
description: "The key name to delete"
|
|
721
|
+
}
|
|
722
|
+
},
|
|
723
|
+
required: ["namespace_id", "key_name"],
|
|
724
|
+
additionalProperties: false
|
|
725
|
+
}),
|
|
726
|
+
execute: async ({ namespace_id, key_name }) => {
|
|
727
|
+
try {
|
|
728
|
+
if (!namespace_id || !key_name) {
|
|
729
|
+
throw new Error("namespace_id and key_name are required");
|
|
730
|
+
}
|
|
731
|
+
const accountId = getAccountId();
|
|
732
|
+
const result = await apiRequest(
|
|
733
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespace_id}/values/${key_name}`,
|
|
734
|
+
{
|
|
735
|
+
method: "DELETE"
|
|
736
|
+
}
|
|
737
|
+
);
|
|
738
|
+
return {
|
|
739
|
+
success: true,
|
|
740
|
+
data: result
|
|
741
|
+
};
|
|
742
|
+
} catch (error) {
|
|
743
|
+
return {
|
|
744
|
+
success: false,
|
|
745
|
+
error: handleApiError(error)
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
var index_default = {
|
|
751
|
+
// Zones
|
|
752
|
+
listZones,
|
|
753
|
+
getZone,
|
|
754
|
+
purgeCache,
|
|
755
|
+
// DNS Records
|
|
756
|
+
listDnsRecords,
|
|
757
|
+
createDnsRecord,
|
|
758
|
+
updateDnsRecord,
|
|
759
|
+
deleteDnsRecord,
|
|
760
|
+
// Workers
|
|
761
|
+
listWorkers,
|
|
762
|
+
getWorker,
|
|
763
|
+
deleteWorker,
|
|
764
|
+
// KV
|
|
765
|
+
listKvNamespaces,
|
|
766
|
+
listKvKeys,
|
|
767
|
+
getKvValue,
|
|
768
|
+
putKvValue,
|
|
769
|
+
deleteKvKey
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
export { createDnsRecord, index_default as default, deleteDnsRecord, deleteKvKey, deleteWorker, getKvValue, getWorker, getZone, listDnsRecords, listKvKeys, listKvNamespaces, listWorkers, listZones, purgeCache, putKvValue, updateDnsRecord };
|
package/package.json
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tpmjs/tools-cloudflare",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Cloudflare API tools for AI agents. Manage DNS records, zones, Workers, KV namespaces, and purge cache.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"tpmjs",
|
|
8
|
+
"cloudflare",
|
|
9
|
+
"dns",
|
|
10
|
+
"workers",
|
|
11
|
+
"agent"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch",
|
|
25
|
+
"type-check": "tsc --noEmit",
|
|
26
|
+
"clean": "rm -rf dist .turbo"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@tpmjs/tsconfig": "workspace:*",
|
|
30
|
+
"tsup": "^8.5.1",
|
|
31
|
+
"typescript": "^5.9.3"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"ai": "6.0.49"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/tpmjs/tpmjs.git",
|
|
42
|
+
"directory": "packages/tools/official/cloudflare"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://tpmjs.com",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"tpmjs": {
|
|
47
|
+
"category": "ops",
|
|
48
|
+
"frameworks": [
|
|
49
|
+
"vercel-ai"
|
|
50
|
+
],
|
|
51
|
+
"tools": [
|
|
52
|
+
{
|
|
53
|
+
"name": "listZones",
|
|
54
|
+
"description": "List Cloudflare zones with optional name and status filtering."
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "getZone",
|
|
58
|
+
"description": "Get details of a specific Cloudflare zone by ID."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "purgeCache",
|
|
62
|
+
"description": "Purge cached content from a Cloudflare zone by URLs or purge everything."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "listDnsRecords",
|
|
66
|
+
"description": "List DNS records for a Cloudflare zone with type and name filters."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "createDnsRecord",
|
|
70
|
+
"description": "Create a new DNS record in a Cloudflare zone."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "updateDnsRecord",
|
|
74
|
+
"description": "Update an existing DNS record in a Cloudflare zone."
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "deleteDnsRecord",
|
|
78
|
+
"description": "Delete a DNS record from a Cloudflare zone."
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "listWorkers",
|
|
82
|
+
"description": "List all Workers scripts in your Cloudflare account."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "getWorker",
|
|
86
|
+
"description": "Get metadata and bindings for a specific Worker script."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "deleteWorker",
|
|
90
|
+
"description": "Delete a Worker script from your Cloudflare account."
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "listKvNamespaces",
|
|
94
|
+
"description": "List KV namespaces in your Cloudflare account."
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "listKvKeys",
|
|
98
|
+
"description": "List keys in a Cloudflare KV namespace with optional prefix filter."
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "getKvValue",
|
|
102
|
+
"description": "Get the value of a key from a Cloudflare KV namespace."
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "putKvValue",
|
|
106
|
+
"description": "Write a key-value pair to a Cloudflare KV namespace."
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "deleteKvKey",
|
|
110
|
+
"description": "Delete a key from a Cloudflare KV namespace."
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
}
|