Skip to content

Commit 7619dda

Browse files
committed
Refactor withAccount into shared repo
1 parent e306c73 commit 7619dda

File tree

3 files changed

+68
-60
lines changed

3 files changed

+68
-60
lines changed

apps/cloudflare-one-casb/src/tools/integrations.ts

Lines changed: 9 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { z } from 'zod'
22

3+
import { withAccountCheck } from '@repo/mcp-common/src/api/account'
34
import {
45
handleAssetById,
56
handleAssetCategories,
@@ -15,73 +16,17 @@ import {
1516
assetCategoryVendorParam,
1617
} from '@repo/mcp-common/src/schemas/cf1-integrations'
1718

19+
import type { McpAgentWithAccount } from '@repo/mcp-common/src/api/account'
20+
import type { ToolDefinition } from '@repo/mcp-common/src/types/tools'
1821
import type { CASBMCP } from '../index'
1922

2023
const PAGE_SIZE = 3
2124

22-
// CF1INT Integration Params
2325
const integrationIdParam = z.string().describe('The UUID of the integration to analyze')
24-
25-
// CF1INT Asset Params
2626
const assetSearchTerm = z.string().describe('The search keyword for assets')
2727
const assetIdParam = z.string().describe('The UUID of the asset to analyze')
2828
const assetCategoryIdParam = z.string().describe('The UUID of the asset category to analyze')
2929

30-
// Define types for our tool handlers
31-
type ToolHandler<T extends Record<string, any>> = (
32-
params: T & { accountId: string; apiToken: string }
33-
) => Promise<any>
34-
35-
interface ToolDefinition<T extends Record<string, any>> {
36-
name: string
37-
description: string
38-
params: Record<string, z.ZodType>
39-
handler: ToolHandler<T>
40-
}
41-
42-
// Helper function to handle common error cases and account ID checks
43-
const withAccountCheck = <T extends Record<string, any>>(
44-
agent: CASBMCP,
45-
handler: ToolHandler<T>
46-
) => {
47-
return async (params: T) => {
48-
const accountId = agent.getActiveAccountId()
49-
if (!accountId) {
50-
return {
51-
content: [
52-
{
53-
type: 'text' as const,
54-
text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
55-
},
56-
],
57-
}
58-
}
59-
60-
try {
61-
const result = await handler({
62-
...params,
63-
accountId,
64-
apiToken: agent.props.accessToken,
65-
})
66-
return {
67-
content: [{ type: 'text' as const, text: JSON.stringify(result) }],
68-
}
69-
} catch (error) {
70-
return {
71-
content: [
72-
{
73-
type: 'text' as const,
74-
text: JSON.stringify({
75-
error: `Error processing request: ${error instanceof Error ? error.message : 'Unknown error'}`,
76-
}),
77-
},
78-
],
79-
}
80-
}
81-
}
82-
}
83-
84-
// Tool definitions with their handlers
8530
const toolDefinitions: Array<ToolDefinition<any>> = [
8631
{
8732
name: 'integration_by_id',
@@ -109,7 +54,6 @@ const toolDefinitions: Array<ToolDefinition<any>> = [
10954
description: 'List all Cloudflare One Integrations in a given account',
11055
params: {},
11156
handler: async ({ accountId, apiToken }: { accountId: string; apiToken: string }) => {
112-
console.log('integrations_list', accountId, apiToken)
11357
const { integrations } = await handleIntegrations({ accountId, apiToken })
11458
return { integrations }
11559
},
@@ -300,6 +244,11 @@ const toolDefinitions: Array<ToolDefinition<any>> = [
300244
*/
301245
export function registerIntegrationsTools(agent: CASBMCP) {
302246
toolDefinitions.forEach(({ name, description, params, handler }) => {
303-
agent.server.tool(name, description, params, withAccountCheck(agent, handler))
247+
agent.server.tool(
248+
name,
249+
description,
250+
params,
251+
withAccountCheck(agent as unknown as McpAgentWithAccount, handler)
252+
)
304253
})
305254
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,55 @@
1+
import type { McpAgent } from 'agents/mcp'
12
import type { Cloudflare } from 'cloudflare'
23
import type { Account } from 'cloudflare/resources/accounts/accounts.mjs'
4+
import type { ToolHandler } from '../types/tools'
35

46
export async function handleAccountsList({ client }: { client: Cloudflare }): Promise<Account[]> {
57
// Currently limited to 50 accounts
68
const response = await client.accounts.list({ query: { per_page: 50 } })
79
return response.result
810
}
11+
12+
export interface McpAgentWithAccount extends McpAgent {
13+
getActiveAccountId: () => string
14+
}
15+
16+
export const withAccountCheck = <T extends Record<string, any>>(
17+
agent: McpAgentWithAccount,
18+
handler: ToolHandler<T>
19+
) => {
20+
return async (params: T) => {
21+
const accountId = agent.getActiveAccountId()
22+
if (!accountId) {
23+
return {
24+
content: [
25+
{
26+
type: 'text' as const,
27+
text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
28+
},
29+
],
30+
}
31+
}
32+
33+
try {
34+
const result = await handler({
35+
...params,
36+
accountId,
37+
apiToken: agent.props.accessToken as string,
38+
})
39+
return {
40+
content: [{ type: 'text' as const, text: JSON.stringify(result) }],
41+
}
42+
} catch (error) {
43+
return {
44+
content: [
45+
{
46+
type: 'text' as const,
47+
text: JSON.stringify({
48+
error: `Error processing request: ${error instanceof Error ? error.message : 'Unknown error'}`,
49+
}),
50+
},
51+
],
52+
}
53+
}
54+
}
55+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { z } from 'zod'
2+
3+
export type ToolHandler<T extends Record<string, any>> = (
4+
params: T & { accountId: string; apiToken: string }
5+
) => Promise<any>
6+
7+
export interface ToolDefinition<T extends Record<string, any>> {
8+
name: string
9+
description: string
10+
params: Record<string, z.ZodType>
11+
handler: ToolHandler<T>
12+
}

0 commit comments

Comments
 (0)