r2_bucket.tools.ts•21.4 kB
import { getCloudflareClient } from '../cloudflare-api'
import { MISSING_ACCOUNT_ID_RESPONSE } from '../constants'
import { getProps } from '../get-props'
import { type CloudflareMcpAgent } from '../types/cloudflare-mcp-agent.types'
import {
BucketListCursorParam,
BucketListDirectionParam,
BucketListNameContainsParam,
BucketListStartAfterParam,
BucketNameSchema,
} from '../types/r2_bucket.types'
import { PaginationPerPageParam } from '../types/shared.types'
export function registerR2BucketTools(agent: CloudflareMcpAgent) {
agent.server.tool(
'r2_buckets_list',
'List r2 buckets in your Cloudflare account',
{
cursor: BucketListCursorParam,
direction: BucketListDirectionParam,
name_contains: BucketListNameContainsParam,
per_page: PaginationPerPageParam,
start_after: BucketListStartAfterParam,
},
{
title: 'List R2 buckets',
annotations: {
readOnlyHint: true,
},
},
async ({ cursor, direction, name_contains, per_page, start_after }) => {
const account_id = await agent.getActiveAccountId()
if (!account_id) {
return MISSING_ACCOUNT_ID_RESPONSE
}
try {
const props = getProps(agent)
const client = getCloudflareClient(props.accessToken)
const listResponse = await client.r2.buckets.list({
account_id,
cursor: cursor ?? undefined,
direction: direction ?? undefined,
name_contains: name_contains ?? undefined,
per_page: per_page ?? undefined,
start_after: start_after ?? undefined,
})
return {
content: [
{
type: 'text',
text: JSON.stringify({
buckets: listResponse.buckets,
count: listResponse.buckets?.length ?? 0,
}),
},
],
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error listing R2 buckets: ${error instanceof Error && error.message}`,
},
],
}
}
}
)
agent.server.tool(
'r2_bucket_create',
'Create a new r2 bucket in your Cloudflare account',
{ name: BucketNameSchema },
{
title: 'Create R2 bucket',
annotations: {
readOnlyHint: false,
destructiveHint: false,
},
},
async ({ name }) => {
const account_id = await agent.getActiveAccountId()
if (!account_id) {
return MISSING_ACCOUNT_ID_RESPONSE
}
try {
const props = getProps(agent)
const client = getCloudflareClient(props.accessToken)
const bucket = await client.r2.buckets.create({
account_id,
name,
})
return {
content: [
{
type: 'text',
text: JSON.stringify(bucket),
},
],
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error creating KV namespace: ${error instanceof Error && error.message}`,
},
],
}
}
}
)
agent.server.tool(
'r2_bucket_get',
'Get details about a specific R2 bucket',
{ name: BucketNameSchema },
{
title: 'Get R2 bucket',
annotations: {
readOnlyHint: true,
},
},
async ({ name }) => {
const account_id = await agent.getActiveAccountId()
if (!account_id) {
return MISSING_ACCOUNT_ID_RESPONSE
}
try {
const props = getProps(agent)
const client = getCloudflareClient(props.accessToken)
const bucket = await client.r2.buckets.get(name, { account_id })
return {
content: [
{
type: 'text',
text: JSON.stringify(bucket),
},
],
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error getting R2 bucket: ${error instanceof Error && error.message}`,
},
],
}
}
}
)
agent.server.tool(
'r2_bucket_delete',
'Delete an R2 bucket',
{ name: BucketNameSchema },
{
title: 'Delete R2 bucket',
annotations: {
readOnlyHint: false,
destructiveHint: true,
},
},
async ({ name }) => {
const account_id = await agent.getActiveAccountId()
if (!account_id) {
return MISSING_ACCOUNT_ID_RESPONSE
}
try {
const props = getProps(agent)
const client = getCloudflareClient(props.accessToken)
const result = await client.r2.buckets.delete(name, { account_id })
return {
content: [
{
type: 'text',
text: JSON.stringify(result),
},
],
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error deleting R2 bucket: ${error instanceof Error && error.message}`,
},
],
}
}
}
)
// Commenting out non-CRUD tools for now to keep the bindings MCP surface small
// agent.server.tool(
// 'r2_bucket_cors_get',
// 'Get CORS configuration for an R2 bucket',
// {
// name: BucketNameSchema,
// params: CorsGetParamsSchema.optional(),
// },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const cors = await client.r2.buckets.cors.get(name, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(cors),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error getting R2 bucket CORS configuration: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_cors_update',
// 'Update CORS configuration for an R2 bucket',
// {
// name: BucketNameSchema,
// cors_config: CorsRulesSchema,
// },
// async ({ name, cors_config }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.cors.update(name, {
// account_id,
// ...cors_config,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error updating R2 bucket CORS configuration: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_cors_delete',
// 'Delete CORS configuration for an R2 bucket',
// {
// name: BucketNameSchema,
// params: CorsDeleteParamsSchema.optional(),
// },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.cors.delete(name, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error deleting R2 bucket CORS configuration: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_domains_list',
// 'List all of the domains for an R2 bucket',
// { name: BucketNameSchema, params: CustomDomainListParamsSchema.optional() },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const domains = await client.r2.buckets.domains.custom.list(name, { account_id, ...params })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(domains),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error listing R2 bucket domains: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_domains_get',
// 'Get details about a specific domain for an R2 bucket',
// {
// name: BucketNameSchema,
// domain: CustomDomainNameSchema,
// params: CustomDomainGetParamsSchema.optional(),
// },
// async ({ name, domain, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.domains.custom.get(name, domain, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error getting R2 bucket domain: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_domains_create',
// 'Create a new domain for an R2 bucket',
// { name: BucketNameSchema, params: CustomDomainCreateParamsSchema },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.domains.custom.create(name, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error creating R2 bucket domain: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_domains_delete',
// 'Delete a domain for an R2 bucket',
// {
// name: BucketNameSchema,
// domain: CustomDomainNameSchema,
// params: CustomDomainDeleteParamsSchema.optional(),
// },
// async ({ name, domain, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.domains.custom.delete(name, domain, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error deleting R2 bucket domain: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_domains_update',
// 'Update a domain for an R2 bucket',
// {
// name: BucketNameSchema,
// domain: CustomDomainNameSchema,
// params: CustomDomainUpdateParamsSchema,
// },
// async ({ name, domain, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.domains.custom.update(name, domain, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error updating R2 bucket domain: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_event_notifications_get',
// 'Get event notifications for an R2 bucket',
// { name: BucketNameSchema, params: EventNotificationGetParamsSchema.optional() },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.eventNotifications.get(name, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error getting R2 bucket event notifications: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_event_notifications_update',
// 'Update event notifications for an R2 bucket',
// {
// name: BucketNameSchema,
// queueId: QueueIdSchema,
// params: EventNotificationUpdateParamsSchema.optional(),
// },
// async ({ name, queueId, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.eventNotifications.update(name, queueId, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error updating R2 bucket event notifications: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_event_notifications_delete',
// 'Delete event notifications for an R2 bucket',
// {
// name: BucketNameSchema,
// queueId: QueueIdSchema,
// params: EventNotificationDeleteParamsSchema.optional(),
// },
// async ({ name, queueId, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.eventNotifications.delete(name, queueId, {
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error deleting R2 bucket event notifications: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_locks_get',
// 'Get locks for an R2 bucket',
// { name: BucketNameSchema, params: LockGetParamsSchema.optional() },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.locks.get(name, { account_id, ...params })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error getting R2 bucket locks: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_locks_update',
// 'Update locks for an R2 bucket',
// { name: BucketNameSchema, params: LockUpdateParamsSchema },
// async ({ name, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.locks.update(name, { account_id, ...params })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error updating R2 bucket locks: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_bucket_temporary_credentials_create',
// 'Create temporary credentials for an R2 bucket',
// { params: TemporaryCredentialsCreateParamsSchema },
// async ({ params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.temporaryCredentials.create({
// account_id,
// ...params,
// })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error creating temporary credentials for R2 bucket: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool('r2_metrics_list', 'List metrics for an R2 bucket', async () => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.metrics.list({ account_id })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error listing R2 bucket metrics: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// })
// agent.server.tool(
// 'r2_sippy_get',
// 'Get configuration for sippy for an R2 bucket',
// { bucketName: BucketNameSchema, params: SippyGetParamsSchema.optional() },
// async ({ bucketName, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.sippy.get(bucketName, { account_id, ...params })
// console.log('sippy get result', result)
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result ?? null),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error getting R2 bucket sippy: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_sippy_update',
// 'Update configuration for sippy for an R2 bucket',
// { bucketName: BucketNameSchema, params: SippyUpdateParamsSchema },
// async ({ bucketName, params }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.sippy.update(bucketName, { account_id, ...params })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error updating R2 bucket sippy: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
// agent.server.tool(
// 'r2_sippy_delete',
// 'Delete sippy for an R2 bucket',
// { bucketName: BucketNameSchema },
// async ({ bucketName }) => {
// const account_id = await agent.getActiveAccountId()
// if (!account_id) {
// return MISSING_ACCOUNT_ID_RESPONSE
// }
// try {
// const client = getCloudflareClient(props.accessToken)
// const result = await client.r2.buckets.sippy.delete(bucketName, { account_id })
// return {
// content: [
// {
// type: 'text',
// text: JSON.stringify(result),
// },
// ],
// }
// } catch (error) {
// return {
// content: [
// {
// type: 'text',
// text: `Error deleting R2 bucket sippy: ${error instanceof Error && error.message}`,
// },
// ],
// }
// }
// }
// )
}