Skip to content

Commit 8b60055

Browse files
authored
Merge pull request #37 from cloudflare/use-typescript-sdk-for-account-list-and-workers-endpoints
Use typescript SDK for account list + workers endpoints
2 parents 89dcbc8 + 26b3d58 commit 8b60055

File tree

8 files changed

+45
-205
lines changed

8 files changed

+45
-205
lines changed

.prettierrc.cjs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,7 @@ const config = {
3030
semi: false,
3131
singleQuote: true,
3232
printWidth: 100,
33-
plugins: [
34-
'@ianvs/prettier-plugin-sort-imports',
35-
'prettier-plugin-packagejson',
36-
'prettier-plugin-astro',
37-
'prettier-plugin-tailwindcss',
38-
],
33+
plugins: ['@ianvs/prettier-plugin-sort-imports'],
3934
importOrder: [...codeImports, ...typeImports],
4035
importOrderTypeScriptVersion: '5.5.4',
4136
overrides: [

apps/workers-observability/src/tools/account.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { z } from "zod";
22
import type { MyMCP } from "../index";
33
import { handleAccountsList } from "@repo/mcp-common/src/api/account"
4+
import { getCloudflareClient } from "@repo/mcp-common/src/cloudflare-api";
45

56
export function registerAccountTools(agent: MyMCP) {
67
// Tool to list all accounts
@@ -10,7 +11,7 @@ export function registerAccountTools(agent: MyMCP) {
1011
{},
1112
async () => {
1213
try {
13-
const results = await handleAccountsList({ apiToken: agent.props.accessToken });
14+
const results = await handleAccountsList({client: getCloudflareClient(agent.props.accessToken)});
1415
// Sort accounts by created_on date (newest first)
1516
const accounts = results
1617
// order by created_on desc ( newest first )

apps/workers-observability/src/tools/workers.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { z } from "zod";
22
import type { MyMCP } from "../index";
33
import { handleWorkersList, handleWorkerScriptDownload } from "@repo/mcp-common/src/api/workers"
4+
import { getCloudflareClient } from "@repo/mcp-common/src/cloudflare-api";
45

56
/**
67
* Registers the workers tools with the MCP server
@@ -31,8 +32,8 @@ export function registerWorkersTools(agent: MyMCP) {
3132
}
3233
try {
3334
const results = await handleWorkersList({
35+
client: getCloudflareClient(agent.props.accessToken),
3436
accountId,
35-
apiToken: agent.props.accessToken,
3637
});
3738
// Extract worker details and sort by created_on date (newest first)
3839
const workers = results
@@ -92,9 +93,9 @@ export function registerWorkersTools(agent: MyMCP) {
9293
try {
9394
const { scriptName } = params;
9495
const scriptContent = await handleWorkerScriptDownload({
96+
client: getCloudflareClient(agent.props.accessToken),
9597
scriptName,
9698
accountId,
97-
apiToken: agent.props.accessToken,
9899
});
99100
return {
100101
content: [

apps/workers-observability/wrangler.jsonc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919
"dev": {
2020
"port": 8976
2121
},
22+
"durable_objects": {
23+
"bindings": [
24+
{
25+
"class_name": "MyMCP",
26+
"name": "MCP_OBJECT"
27+
}
28+
]
29+
},
30+
"kv_namespaces": [
31+
{
32+
"binding": "OAUTH_KV",
33+
"id": "DEV_KV"
34+
}
35+
],
2236
"workers_dev": false,
2337
"preview_urls": false,
2438
"env": {
Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
1-
import { z } from "zod";
2-
import { V4Schema } from "../v4-api";
3-
4-
type AccountSchema = z.infer<typeof AccountSchema>
5-
const AccountSchema = z.object({
6-
id: z.string(),
7-
name: z.string(),
8-
created_on: z.string(),
9-
});
10-
const AccountsListResponseSchema = V4Schema(z.array(AccountSchema));
1+
import type { Cloudflare } from 'cloudflare';
2+
import type { Account } from "cloudflare/resources/accounts/accounts.mjs";
113

124
export async function handleAccountsList({
13-
apiToken,
5+
client,
146
}: {
15-
apiToken: string;
16-
}): Promise<AccountSchema[]> {
7+
client: Cloudflare
8+
}): Promise<Account[]> {
179
// Currently limited to 50 accounts
18-
const response = await fetch("https://api.cloudflare.com/client/v4/accounts?per_page=50", {
19-
method: "GET",
20-
headers: {
21-
Authorization: `Bearer ${apiToken}`,
22-
Accept: "application/javascript",
23-
},
24-
});
25-
26-
if (!response.ok) {
27-
const error = await response.text();
28-
throw new Error(`Cloudflare API request failed: ${error}`);
29-
}
30-
31-
return AccountsListResponseSchema.parse(await response.json()).result ?? [];
10+
const response = await client.accounts.list({query: {per_page: 50}})
11+
return response.result
3212
}
Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,36 @@
1-
import { z } from "zod";
2-
import { fetchCloudflareApi } from "../cloudflare-api";
3-
import { V4Schema } from "../v4-api";
4-
5-
const WorkerSchema = z.object({
6-
// id is usually the worker name
7-
id: z.string(),
8-
created_on: z.string().optional(),
9-
modified_on: z.string().optional(),
10-
});
11-
12-
const CloudflareWorkerListResponseSchema = V4Schema(z.array(WorkerSchema));
1+
import type { Cloudflare } from 'cloudflare';
132

143
/**
154
* Fetches list of workers from Cloudflare API
5+
* @param client Cloudflare API Client
166
* @param accountId Cloudflare account ID
17-
* @param apiToken Cloudflare API token
187
* @returns List of workers
198
*/
209
export async function handleWorkersList({
10+
client,
2111
accountId,
22-
apiToken,
2312
}: {
24-
accountId: string;
25-
apiToken: string;
26-
}) {
27-
const response = await fetchCloudflareApi({
28-
endpoint: "/workers/scripts",
29-
accountId,
30-
apiToken,
31-
responseSchema: CloudflareWorkerListResponseSchema,
32-
options: {
33-
method: "GET",
34-
},
35-
});
36-
37-
return response.result ?? [];
13+
client: Cloudflare
14+
accountId: string,
15+
}): Promise<Cloudflare.Workers.Scripts.Script[]> {
16+
return (await client.workers.scripts.list({account_id: accountId})).result
3817
}
3918

4019
/**
4120
* Downloads a specific worker script from Cloudflare API
21+
* @param client Cloudflare API Client
4222
* @param scriptName Name of the worker script to download
4323
* @param accountId Cloudflare account ID
44-
* @param apiToken Cloudflare API token
4524
* @returns The worker script content
4625
*/
4726
export async function handleWorkerScriptDownload({
27+
client,
4828
scriptName,
4929
accountId,
50-
apiToken,
5130
}: {
52-
scriptName: string;
53-
accountId: string;
54-
apiToken: string;
31+
client: Cloudflare
32+
scriptName: string,
33+
accountId: string,
5534
}): Promise<string> {
56-
const response = await fetch(
57-
`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts/${scriptName}`,
58-
{
59-
method: "GET",
60-
headers: {
61-
Authorization: `Bearer ${apiToken}`,
62-
Accept: "application/javascript",
63-
},
64-
},
65-
);
66-
67-
if (!response.ok) {
68-
const error = await response.text();
69-
throw new Error(`Failed to download worker script: ${error}`);
70-
}
71-
72-
return await response.text();
35+
return await client.workers.scripts.get(scriptName, {account_id: accountId})
7336
}

packages/mcp-common/src/cloudflare-api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import type { z } from "zod";
2+
import { Cloudflare } from 'cloudflare';
3+
4+
export function getCloudflareClient(apiToken: string) {
5+
return new Cloudflare({ apiToken })
6+
}
27

38
/**
49
* Makes a request to the Cloudflare API

packages/mcp-common/tests/workers.spec.ts

Lines changed: 0 additions & 119 deletions
This file was deleted.

0 commit comments

Comments
 (0)