#
tokens: 49737/50000 38/376 files (page 3/25)
lines: off (toggle) GitHub
raw markdown copy
This is page 3 of 25. Use http://codebase.md/cloudflare/mcp-server-cloudflare?page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── README.md
├── .dockerignore
├── .editorconfig
├── .eslintrc.cjs
├── .github
│   ├── actions
│   │   └── setup
│   │       └── action.yml
│   ├── ISSUE_TEMPLATE
│   │   └── bug_report.md
│   └── workflows
│       ├── branches.yml
│       ├── main.yml
│       └── release.yml
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc.cjs
├── .syncpackrc.cjs
├── .vscode
│   ├── extensions.json
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── apps
│   ├── ai-gateway
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── ai-gateway.app.ts
│   │   │   ├── ai-gateway.context.ts
│   │   │   ├── tools
│   │   │   │   └── ai-gateway.tools.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── auditlogs
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── auditlogs.app.ts
│   │   │   ├── auditlogs.context.ts
│   │   │   └── tools
│   │   │       └── auditlogs.tools.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── autorag
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── autorag.app.ts
│   │   │   ├── autorag.context.ts
│   │   │   ├── tools
│   │   │   │   └── autorag.tools.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── browser-rendering
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── browser.app.ts
│   │   │   ├── browser.context.ts
│   │   │   └── tools
│   │   │       └── browser.tools.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── cloudflare-one-casb
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── cf1-casb.app.ts
│   │   │   ├── cf1-casb.context.ts
│   │   │   └── tools
│   │   │       └── integrations.tools.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── demo-day
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── frontend
│   │   │   ├── index.html
│   │   │   ├── public
│   │   │   │   ├── anthropic.svg
│   │   │   │   ├── asana.svg
│   │   │   │   ├── atlassian.svg
│   │   │   │   ├── canva.svg
│   │   │   │   ├── cloudflare_logo.svg
│   │   │   │   ├── cloudflare.svg
│   │   │   │   ├── dina.jpg
│   │   │   │   ├── favicon-16x16.png
│   │   │   │   ├── favicon-32x32.png
│   │   │   │   ├── favicon.ico
│   │   │   │   ├── favicon.png
│   │   │   │   ├── intercom.svg
│   │   │   │   ├── linear.svg
│   │   │   │   ├── matt.jpg
│   │   │   │   ├── mcp_demo_day.svg
│   │   │   │   ├── mcpog.png
│   │   │   │   ├── more.svg
│   │   │   │   ├── paypal.svg
│   │   │   │   ├── pete.jpeg
│   │   │   │   ├── sentry.svg
│   │   │   │   ├── special_guest.png
│   │   │   │   ├── square.svg
│   │   │   │   ├── stripe.svg
│   │   │   │   ├── sunil.jpg
│   │   │   │   └── webflow.svg
│   │   │   ├── script.js
│   │   │   └── styles.css
│   │   ├── package.json
│   │   ├── src
│   │   │   └── demo-day.app.ts
│   │   ├── tsconfig.json
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.json
│   ├── dex-analysis
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── dex-analysis.app.ts
│   │   │   ├── dex-analysis.context.ts
│   │   │   ├── tools
│   │   │   │   └── dex-analysis.tools.ts
│   │   │   └── warp_diag_reader.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── dns-analytics
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── dns-analytics.app.ts
│   │   │   ├── dns-analytics.context.ts
│   │   │   └── tools
│   │   │       └── dex-analytics.tools.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── docs-autorag
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── docs-autorag.app.ts
│   │   │   ├── docs-autorag.context.ts
│   │   │   └── tools
│   │   │       └── docs-autorag.tools.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── docs-vectorize
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── docs-vectorize.app.ts
│   │   │   └── docs-vectorize.context.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── graphql
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── graphql.app.ts
│   │   │   ├── graphql.context.ts
│   │   │   └── tools
│   │   │       └── graphql.tools.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── logpush
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── logpush.app.ts
│   │   │   ├── logpush.context.ts
│   │   │   └── tools
│   │   │       └── logpush.tools.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── radar
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── radar.app.ts
│   │   │   ├── radar.context.ts
│   │   │   ├── tools
│   │   │   │   ├── radar.tools.ts
│   │   │   │   └── url-scanner.tools.ts
│   │   │   ├── types
│   │   │   │   ├── radar.ts
│   │   │   │   └── url-scanner.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── sandbox-container
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── container
│   │   │   ├── fileUtils.spec.ts
│   │   │   ├── fileUtils.ts
│   │   │   ├── sandbox.container.app.ts
│   │   │   └── tsconfig.json
│   │   ├── CONTRIBUTING.md
│   │   ├── Dockerfile
│   │   ├── evals
│   │   │   ├── exec.eval.ts
│   │   │   ├── files.eval.ts
│   │   │   ├── initialize.eval.ts
│   │   │   └── utils.ts
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── server
│   │   │   ├── containerHelpers.ts
│   │   │   ├── containerManager.ts
│   │   │   ├── containerMcp.ts
│   │   │   ├── metrics.ts
│   │   │   ├── prompts.ts
│   │   │   ├── sandbox.server.app.ts
│   │   │   ├── sandbox.server.context.ts
│   │   │   ├── userContainer.ts
│   │   │   ├── utils.spec.ts
│   │   │   └── utils.ts
│   │   ├── shared
│   │   │   ├── consts.ts
│   │   │   └── schema.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.evals.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── workers-bindings
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── evals
│   │   │   ├── accounts.eval.ts
│   │   │   ├── hyperdrive.eval.ts
│   │   │   ├── kv_namespaces.eval.ts
│   │   │   ├── types.d.ts
│   │   │   └── utils.ts
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── bindings.app.ts
│   │   │   └── bindings.context.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.evals.ts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   ├── workers-builds
│   │   ├── .dev.vars.example
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── tools
│   │   │   │   └── workers-builds.tools.ts
│   │   │   ├── workers-builds.app.ts
│   │   │   └── workers-builds.context.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vite.config.mts
│   │   ├── vitest.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.jsonc
│   └── workers-observability
│       ├── .dev.vars.example
│       ├── .eslintrc.cjs
│       ├── CHANGELOG.md
│       ├── CONTRIBUTING.md
│       ├── package.json
│       ├── README.md
│       ├── src
│       │   ├── tools
│       │   │   └── workers-observability.tools.ts
│       │   ├── workers-observability.app.ts
│       │   └── workers-observability.context.ts
│       ├── tsconfig.json
│       ├── types.d.ts
│       ├── vitest.config.ts
│       ├── worker-configuration.d.ts
│       └── wrangler.jsonc
├── CONTRIBUTING.md
├── implementation-guides
│   ├── evals.md
│   ├── tools.md
│   └── type-validators.md
├── LICENSE
├── package.json
├── packages
│   ├── eslint-config
│   │   ├── CHANGELOG.md
│   │   ├── default.cjs
│   │   ├── package.json
│   │   └── README.md
│   ├── eval-tools
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── runTask.ts
│   │   │   ├── scorers.ts
│   │   │   └── test-models.ts
│   │   ├── tsconfig.json
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.json
│   ├── mcp-common
│   │   ├── .eslintrc.cjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── api
│   │   │   │   ├── account.api.ts
│   │   │   │   ├── cf1-integration.api.ts
│   │   │   │   ├── workers-builds.api.ts
│   │   │   │   ├── workers-observability.api.ts
│   │   │   │   ├── workers.api.ts
│   │   │   │   └── zone.api.ts
│   │   │   ├── api-handler.ts
│   │   │   ├── api-token-mode.ts
│   │   │   ├── cloudflare-api.ts
│   │   │   ├── cloudflare-auth.ts
│   │   │   ├── cloudflare-oauth-handler.ts
│   │   │   ├── config.ts
│   │   │   ├── constants.ts
│   │   │   ├── durable-kv-store.ts
│   │   │   ├── durable-objects
│   │   │   │   └── user_details.do.ts
│   │   │   ├── env.ts
│   │   │   ├── format.spec.ts
│   │   │   ├── format.ts
│   │   │   ├── get-props.ts
│   │   │   ├── mcp-error.ts
│   │   │   ├── poll.ts
│   │   │   ├── prompts
│   │   │   │   └── docs-vectorize.prompts.ts
│   │   │   ├── scopes.ts
│   │   │   ├── sentry.ts
│   │   │   ├── server.ts
│   │   │   ├── tools
│   │   │   │   ├── account.tools.ts
│   │   │   │   ├── d1.tools.ts
│   │   │   │   ├── docs-vectorize.tools.ts
│   │   │   │   ├── hyperdrive.tools.ts
│   │   │   │   ├── kv_namespace.tools.ts
│   │   │   │   ├── r2_bucket.tools.ts
│   │   │   │   ├── worker.tools.ts
│   │   │   │   └── zone.tools.ts
│   │   │   ├── types
│   │   │   │   ├── cf1-integrations.types.ts
│   │   │   │   ├── cloudflare-mcp-agent.types.ts
│   │   │   │   ├── d1.types.ts
│   │   │   │   ├── hyperdrive.types.ts
│   │   │   │   ├── kv_namespace.types.ts
│   │   │   │   ├── r2_bucket.types.ts
│   │   │   │   ├── shared.types.ts
│   │   │   │   ├── tools.types.ts
│   │   │   │   ├── workers-builds.types.ts
│   │   │   │   ├── workers-logs.types.ts
│   │   │   │   └── workers.types.ts
│   │   │   ├── utils.spec.ts
│   │   │   ├── utils.ts
│   │   │   └── v4-api.ts
│   │   ├── tests
│   │   │   └── utils
│   │   │       └── cloudflare-mock.ts
│   │   ├── tsconfig.json
│   │   ├── types.d.ts
│   │   ├── vitest.config.ts
│   │   └── worker-configuration.d.ts
│   ├── mcp-observability
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── analytics-engine.ts
│   │   │   ├── index.ts
│   │   │   └── metrics.ts
│   │   ├── tsconfig.json
│   │   └── worker-configuration.d.ts
│   ├── tools
│   │   ├── .eslintrc.cjs
│   │   ├── bin
│   │   │   ├── run-changeset-new
│   │   │   ├── run-eslint-workers
│   │   │   ├── run-fix-deps
│   │   │   ├── run-tsc
│   │   │   ├── run-turbo
│   │   │   ├── run-vitest
│   │   │   ├── run-vitest-ci
│   │   │   ├── run-wrangler-deploy
│   │   │   ├── run-wrangler-types
│   │   │   └── runx
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── bin
│   │   │   │   └── runx.ts
│   │   │   ├── changesets.spec.ts
│   │   │   ├── changesets.ts
│   │   │   ├── cmd
│   │   │   │   └── deploy-published-packages.ts
│   │   │   ├── proc.ts
│   │   │   ├── test
│   │   │   │   ├── fixtures
│   │   │   │   │   └── changesets
│   │   │   │   │       ├── empty
│   │   │   │   │       │   └── .gitkeep
│   │   │   │   │       ├── invalid-json
│   │   │   │   │       │   └── published-packages.json
│   │   │   │   │       ├── invalid-schema
│   │   │   │   │       │   └── published-packages.json
│   │   │   │   │       └── valid
│   │   │   │   │           └── published-packages.json
│   │   │   │   └── setup.ts
│   │   │   └── tsconfig.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.ts
│   └── typescript-config
│       ├── CHANGELOG.md
│       ├── package.json
│       ├── tools.json
│       ├── workers-lib.json
│       └── workers.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── README.md
├── server.json
├── tsconfig.json
├── turbo.json
└── vitest.workspace.ts
```

# Files

--------------------------------------------------------------------------------
/packages/eval-tools/src/test-models.ts:
--------------------------------------------------------------------------------

```typescript
import { createAnthropic } from '@ai-sdk/anthropic'
import { AnthropicMessagesModelId } from '@ai-sdk/anthropic/internal'
import { createGoogleGenerativeAI } from '@ai-sdk/google'
import { GoogleGenerativeAILanguageModel } from '@ai-sdk/google/internal'
import { createOpenAI } from '@ai-sdk/openai'
import { OpenAIChatModelId } from '@ai-sdk/openai/internal'
import { createAiGateway } from 'ai-gateway-provider'
import { env } from 'cloudflare:test'
import { describe } from 'vitest'
import { createWorkersAI } from 'workers-ai-provider'

export const factualityModel = getOpenAiModel('gpt-4o')

type value2key<T, V> = {
	[K in keyof T]: T[K] extends V ? K : never
}[keyof T]
type AiTextGenerationModels = Exclude<
	value2key<AiModels, BaseAiTextGeneration>,
	value2key<AiModels, BaseAiTextToImage>
>

function getOpenAiModel(modelName: OpenAIChatModelId) {
	if (!env.CLOUDFLARE_ACCOUNT_ID || !env.AI_GATEWAY_ID || !env.AI_GATEWAY_TOKEN) {
		throw new Error('No AI gateway credentials set!')
	}

	const aigateway = createAiGateway({
		accountId: env.CLOUDFLARE_ACCOUNT_ID,
		gateway: env.AI_GATEWAY_ID,
		apiKey: env.AI_GATEWAY_TOKEN,
	})

	const ai = createOpenAI({
		apiKey: '',
	})

	const model = aigateway([ai(modelName)])

	return { modelName, model, ai }
}

function getAnthropicModel(modelName: AnthropicMessagesModelId) {
	const aigateway = createAiGateway({
		accountId: env.CLOUDFLARE_ACCOUNT_ID,
		gateway: env.AI_GATEWAY_ID,
		apiKey: env.AI_GATEWAY_TOKEN,
	})

	const ai = createAnthropic({
		apiKey: '',
	})

	const model = aigateway([ai(modelName)])

	return { modelName, model, ai }
}

function getGeminiModel(modelName: GoogleGenerativeAILanguageModel['modelId']) {
	if (!env.CLOUDFLARE_ACCOUNT_ID || !env.AI_GATEWAY_ID || !env.AI_GATEWAY_TOKEN) {
		throw new Error('No AI gateway credentials set!')
	}

	const aigateway = createAiGateway({
		accountId: env.CLOUDFLARE_ACCOUNT_ID,
		gateway: env.AI_GATEWAY_ID,
		apiKey: env.AI_GATEWAY_TOKEN,
	})

	const ai = createGoogleGenerativeAI({ apiKey: '' })

	const model = aigateway([ai(modelName)])

	return { modelName, model, ai }
}

function getWorkersAiModel(modelName: AiTextGenerationModels) {
	if (!env.AI) {
		throw new Error('No AI binding provided!')
	}

	const ai = createWorkersAI({ binding: env.AI })

	const model = ai(modelName)
	return { modelName, model, ai }
}

export const eachModel = describe.each([
	getOpenAiModel('gpt-4o'),
	getOpenAiModel('gpt-4o-mini'),
	// getAnthropicModel('claude-3-5-sonnet-20241022'), TODO: The evals pass with anthropic, but our rate limit is so low with AI wholesaling that we can't use it in CI because it's impossible to get a complete run with the current limits
	getGeminiModel('gemini-2.0-flash'),
	// llama 3 is somewhat inconsistent
	//getWorkersAiModel("@cf/meta/llama-3.3-70b-instruct-fp8-fast")
	// Currently llama 4 is having issues with tool calling
	//getWorkersAiModel("@cf/meta/llama-4-scout-17b-16e-instruct")
])

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/types/cf1-integrations.types.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

const Vendor = z.object({
	id: z.string(),
	name: z.string(),
	display_name: z.string(),
	description: z.string().nullable(),
	logo: z.string().nullable(),
	static_logo: z.string().nullable(),
})

const Policy = z.object({
	id: z.string(),
	name: z.string(),
	permissions: z.array(z.string()),
	link: z.string().nullable(),
	dlp_enabled: z.boolean(),
})

// Base Integration schema
export const Integration = z.object({
	id: z.string(),
	name: z.string(),
	status: z.enum(['Healthy', 'Unhealthy', 'Initializing', 'Paused']),
	upgradable: z.boolean(),
	permissions: z.array(z.string()),

	vendor: Vendor,
	policy: Policy,

	created: z.string(),
	updated: z.string(),
	credentials_expiry: z.string().nullable(),
	last_hydrated: z.string().nullable(),
})

// Schema for output: a single integration
export const IntegrationResponse = Integration
export type zReturnedIntegrationResult = z.infer<typeof IntegrationResponse>

// Schema for output: multiple integrations
export const IntegrationsResponse = z.array(Integration)
export type zReturnedIntegrationsResult = z.infer<typeof IntegrationsResponse>

export const AssetCategory = z.object({
	id: z.string().uuid(),
	type: z.string(),
	vendor: z.string(),
	service: z.string().nullable(),
})

export const AssetDetail = z.object({
	id: z.string().uuid(),
	external_id: z.string(),
	name: z.string(),
	link: z.string().nullable(),
	fields: z.array(
		z.object({
			link: z.string().nullable(),
			name: z.string(),
			value: z.any(),
		})
	),
	category: AssetCategory,
	integration: Integration,
})

export type zReturnedAssetResult = z.infer<typeof AssetDetail>

export const AssetsResponse = z.array(AssetDetail)
export type zReturnedAssetsResult = z.infer<typeof AssetsResponse>

export const AssetCategoriesResponse = z.array(AssetCategory)
export type zReturnedAssetCategoriesResult = z.infer<typeof AssetCategoriesResponse>

export const assetCategoryTypeParam = z
	.enum([
		'Account',
		'Alert',
		'App',
		'Authentication Method',
		'Bucket',
		'Bucket Iam Permission',
		'Bucket Permission',
		'Calendar',
		'Certificate',
		'Channel',
		'Commit',
		'Content',
		'Credential',
		'Domain',
		'Drive',
		'Environment',
		'Factor',
		'File',
		'File Permission',
		'Folder',
		'Group',
		'Incident',
		'Instance',
		'Issue',
		'Label',
		'Meeting',
		'Message',
		'Message Rule',
		'Namespace',
		'Organization',
		'Package',
		'Pipeline',
		'Project',
		'Report',
		'Repository',
		'Risky User',
		'Role',
		'Server',
		'Site',
		'Space',
		'Submodule',
		'Third Party User',
		'User',
		'User No Mfa',
		'Variable',
		'Webhook',
		'Workspace',
	])
	.optional()
	.describe('Type of cloud resource or service category')

export const assetCategoryVendorParam = z
	.enum([
		'AWS',
		'Bitbucket',
		'Box',
		'Confluence',
		'Dropbox',
		'GitHub',
		'Google Cloud Platform',
		'Google Workspace',
		'Jira',
		'Microsoft',
		'Microsoft Azure',
		'Okta',
		'Salesforce',
		'ServiceNow',
		'Slack',
		'Workday',
		'Zoom',
	])
	.describe('Vendor of the cloud service or resource')

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/server.ts:
--------------------------------------------------------------------------------

```typescript
import { isPromise } from 'node:util/types'
import { type ServerOptions } from '@modelcontextprotocol/sdk/server/index.js'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { type ZodRawShape } from 'zod'

import { MetricsTracker, SessionStart, ToolCall } from '../../mcp-observability/src'
import { McpError } from './mcp-error'

import type { ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js'
import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js'
import type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js'
import type { SentryClient } from './sentry'

export class CloudflareMCPServer extends McpServer {
	private metrics
	private sentry?: SentryClient

	constructor({
		userId,
		wae,
		serverInfo,
		options,
		sentry,
	}: {
		userId?: string
		wae: AnalyticsEngineDataset
		serverInfo: {
			[x: string]: unknown
			name: string
			version: string
		}
		options?: ServerOptions
		sentry?: SentryClient
	}) {
		super(serverInfo, options)
		this.metrics = new MetricsTracker(wae, serverInfo)
		this.sentry = sentry

		this.server.oninitialized = () => {
			const clientInfo = this.server.getClientVersion()
			const clientCapabilities = this.server.getClientCapabilities()
			this.metrics.logEvent(
				new SessionStart({
					userId,
					clientInfo,
					clientCapabilities,
				})
			)
		}

		this.server.onerror = (e) => {
			this.recordError(e)
		}

		const _tool = this.tool.bind(this)
		this.tool = (name: string, ...rest: unknown[]): ReturnType<typeof this.tool> => {
			const toolCb = rest[rest.length - 1] as ToolCallback<ZodRawShape | undefined>
			const replacementToolCb: ToolCallback<ZodRawShape | undefined> = (arg1, arg2) => {
				const toolCall = toolCb(
					arg1 as { [x: string]: any } & RequestHandlerExtra<ServerRequest, ServerNotification>,
					arg2
				)
				// There are 4 cases to track:
				try {
					if (isPromise(toolCall)) {
						return toolCall
							.then((r: any) => {
								// promise succeeds
								this.metrics.logEvent(
									new ToolCall({
										toolName: name,
										userId,
									})
								)
								return r
							})
							.catch((e: unknown) => {
								// promise throws
								this.trackToolCallError(e, name, userId)
								throw e
							})
					} else {
						// non-promise succeeds
						this.metrics.logEvent(
							new ToolCall({
								toolName: name,
								userId,
							})
						)
						return toolCall
					}
				} catch (e: unknown) {
					// non-promise throws
					this.trackToolCallError(e, name, userId)
					throw e
				}
			}
			rest[rest.length - 1] = replacementToolCb

			// @ts-ignore
			return _tool(name, ...rest)
		}
	}

	private trackToolCallError(e: unknown, toolName: string, userId?: string) {
		// placeholder error code
		let errorCode = -1
		if (e instanceof McpError) {
			errorCode = e.code
		}
		this.metrics.logEvent(
			new ToolCall({
				toolName,
				userId: userId,
				errorCode: errorCode,
			})
		)
	}

	public recordError(e: unknown) {
		this.sentry?.recordError(e)
	}
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/durable-kv-store.ts:
--------------------------------------------------------------------------------

```typescript
import type { ZodSchema } from 'zod'

export type DurableKVStorageKeys = { [key: string]: ZodSchema }

/**
 * DurableKVStore is a type-safe key/value store backed by Durable Object storage.
 *
 * @example
 *
 * ```ts
 * export class MyDurableObject extends DurableObject<Bindings> {
 * 	readonly kv
 * 	constructor(
 * 		readonly state: DurableObjectState,
 * 		env: Bindings
 * 	) {
 * 		super(state, env)
 * 		this.kv = new DurableKVStore({
 * 			state,
 * 			prefix: 'meta',
 * 			keys: {
 * 				// Each key has a matching Zod schema enforcing what's stored
 * 				date_key: z.coerce.date(),
 * 				// While empty keys will always return null, adding
 * 				// `nullable()` allows us to explicitly set it to null
 * 				string_key: z.string().nullable(),
 * 				number_key: z.number(),
 * 			} as const satisfies StorageKeys,
 * 		})
 * 	}
 *
 * 	async example(): Promise<void> {
 * 		await this.kv.get('number_key') // -> null
 * 		this.kv.put('number_key', 5)
 * 		await this.kv.get('number_key') // -> 5
 * 	}
 * }
 *	```
 */
export class DurableKVStore<T extends DurableKVStorageKeys> {
	private readonly prefix: string
	private readonly keys: T
	private readonly state: DurableObjectState

	constructor({ state, prefix, keys }: { state: DurableObjectState; prefix: string; keys: T }) {
		this.state = state
		this.prefix = prefix
		this.keys = keys
	}

	/** Add the prefix to a key (used for get/put operations) */
	private addPrefix<K extends keyof T>(key: K): string {
		if (this.prefix.length > 0) {
			return `${this.prefix}/${key.toString()}`
		}
		return key.toString()
	}

	/**
	 * Get a value from KV storage. Returns `null` if the value
	 * is not set (or if it's explicitly set to `null`)
	 */
	async get<K extends keyof T>(key: K): Promise<T[K]['_output'] | null>
	/**
	 * Get a value from KV storage or return the provided
	 * default if they value in storage is unset (undefined).
	 * The default value must match the schema for the given key.
	 *
	 * If defaultValue is explicitly set to undefined, it will still return null (avoid this).
	 *
	 * If the value in storage is null then this will return null instead of the default.
	 */
	async get<K extends keyof T>(key: K, defaultValue: T[K]['_output']): Promise<T[K]['_output']>
	async get<K extends keyof T>(
		key: K,
		defaultValue?: T[K]['_output']
	): Promise<T[K]['_output'] | null> {
		const schema = this.keys[key]
		if (schema === undefined) {
			throw new TypeError(`key ${key.toString()} has no matching schema`)
		}

		const res = await this.state.storage.get(this.addPrefix(key))
		if (res === undefined) {
			if (defaultValue !== undefined) {
				return schema.parse(defaultValue)
			}
			return null
		}

		return schema.parse(res)
	}

	/** Write value to KV storage */
	put<K extends keyof T>(key: K, value: T[K]['_input']): void {
		const schema = this.keys[key]
		if (schema === undefined) {
			throw new TypeError(`key ${key.toString()} has no matching schema`)
		}
		const parsedValue = schema.parse(value)
		void this.state.storage.put(this.addPrefix(key), parsedValue)
	}

	/**
	 * Delete value in KV storage. **Does not need to be awaited**
	 *
	 * @returns `true` if a value was deleted, or `false` if it did not.
	 */
	async delete<K extends keyof T>(key: K): Promise<boolean> {
		return this.state.storage.delete(this.addPrefix(key))
	}
}

```

--------------------------------------------------------------------------------
/apps/dns-analytics/src/tools/dex-analytics.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import { getCloudflareClient } from '@repo/mcp-common/src/cloudflare-api'
import { getProps } from '@repo/mcp-common/src/get-props'

import type { AccountGetParams } from 'cloudflare/resources/accounts/accounts.mjs'
import type { ReportGetParams } from 'cloudflare/resources/dns/analytics.mjs'
import type { ZoneGetParams } from 'cloudflare/resources/dns/settings.mjs'
import type { DNSAnalyticsMCP } from '../dns-analytics.app'

function getStartDate(days: number) {
	const today = new Date()
	const start_date = new Date(today.setDate(today.getDate() - days))
	return start_date.toISOString()
}

export function registerAnalyticTools(agent: DNSAnalyticsMCP) {
	// Register DNS Report tool
	agent.server.tool(
		'dns_report',
		'Fetch the DNS Report for a given zone since a date',
		{
			zone: z.string(),
			days: z.number(),
		},
		async ({ zone, days }) => {
			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const start_date = getStartDate(days)
				const params: ReportGetParams = {
					zone_id: zone,
					metrics: 'responseTimeAvg,queryCount,uncachedCount,staleCount',
					dimensions: 'responseCode,responseCached',
					since: start_date,
				}
				const result = await client.dns.analytics.reports.get(params)
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error fetching DNS report: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
	// Register Account DNS Settings display tool
	agent.server.tool(
		'show_account_dns_settings',
		'Show DNS settings for current account',
		async () => {
			try {
				const accountId = await agent.getActiveAccountId()
				if (!accountId) {
					return {
						content: [
							{
								type: 'text',
								text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
							},
						],
					}
				}
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const params: AccountGetParams = {
					account_id: accountId,
				}
				const result = await client.dns.settings.account.get(params)
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error fetching DNS report: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
	// Register Zone DNS Settings display tool
	agent.server.tool(
		'show_zone_dns_settings',
		'Show DNS settings for a zone',
		{
			zone: z.string(),
		},
		async ({ zone }) => {
			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const params: ZoneGetParams = {
					zone_id: zone,
				}
				const result = await client.dns.settings.zone.get(params)
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error fetching DNS report: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/tools/zone.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import { handleZonesList } from '../api/zone.api'
import { getCloudflareClient } from '../cloudflare-api'
import { getProps } from '../get-props'
import { type CloudflareMcpAgent } from '../types/cloudflare-mcp-agent.types'

export function registerZoneTools(agent: CloudflareMcpAgent) {
	// Tool to list all zones under an account
	agent.server.tool(
		'zones_list',
		'List all zones under a Cloudflare account',
		{
			name: z.string().optional().describe('Filter zones by name'),
			status: z
				.string()
				.optional()
				.describe(
					'Filter zones by status (active, pending, initializing, moved, deleted, deactivated, read only)'
				),
			page: z.number().min(1).default(1).describe('Page number for pagination'),
			perPage: z.number().min(5).max(1000).default(50).describe('Number of zones per page'),
			order: z
				.string()
				.default('name')
				.describe('Field to order results by (name, status, account_name)'),
			direction: z
				.enum(['asc', 'desc'])
				.default('desc')
				.describe('Direction to order results (asc, desc)'),
		},
		{
			title: 'List zones',
			annotations: {
				readOnlyHint: true,
				destructiveHint: false,
			},
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const { page = 1, perPage = 50 } = params

				const zones = await handleZonesList({
					client: getCloudflareClient(props.accessToken),
					accountId,
					...params,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								zones,
								count: zones.length,
								page,
								perPage,
								accountId,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error listing zones: ${error instanceof Error ? error.message : String(error)}`,
						},
					],
				}
			}
		}
	)

	// Tool to get zone details by ID
	agent.server.tool(
		'zone_details',
		'Get details for a specific Cloudflare zone',
		{
			zoneId: z.string().describe('The ID of the zone to get details for'),
		},
		{
			title: 'Get zone details',
			annotations: {
				readOnlyHint: true,
				destructiveHint: false,
			},
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const { zoneId } = params
				const client = getCloudflareClient(props.accessToken)

				// Use the zones.get method to fetch a specific zone
				const response = await client.zones.get({ zone_id: zoneId })

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								zone: response,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error fetching zone details: ${error instanceof Error ? error.message : String(error)}`,
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/types/hyperdrive.types.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import type { ConfigCreateParams } from 'cloudflare/resources/hyperdrive/configs.mjs'

// --- Base Field Schemas ---

/** Zod schema for a Hyperdrive config ID. */
export const HyperdriveConfigIdSchema = z
	.string()
	.describe('The ID of the Hyperdrive configuration')

/** Zod schema for a Hyperdrive config name. */
export const HyperdriveConfigNameSchema: z.ZodType<ConfigCreateParams['name']> = z
	.string()
	.min(1)
	.max(64)
	.regex(/^[a-zA-Z0-9_-]+$/)
	.describe('The name of the Hyperdrive configuration (alphanumeric, underscore, hyphen)')

// --- Origin Field Schemas ---

/** Zod schema for the origin database name. */
export const HyperdriveOriginDatabaseSchema: z.ZodType<
	ConfigCreateParams.PublicDatabase['database']
> = z.string().describe('The database name')
/** Zod schema for the origin database host. */
export const HyperdriveOriginHostSchema: z.ZodType<ConfigCreateParams.PublicDatabase['host']> = z
	.string()
	.describe('The database host address')
/** Zod schema for the origin database port. */
export const HyperdriveOriginPortSchema: z.ZodType<ConfigCreateParams.PublicDatabase['port']> = z
	.number()
	.int()
	.min(1)
	.max(65535)
	.describe('The database port')
/** Zod schema for the origin database scheme. */
export const HyperdriveOriginSchemeSchema: z.ZodType<ConfigCreateParams.PublicDatabase['scheme']> =
	z.enum(['postgresql']).describe('The database protocol')
/** Zod schema for the origin database user. */
export const HyperdriveOriginUserSchema: z.ZodType<ConfigCreateParams.PublicDatabase['user']> = z
	.string()
	.describe('The database user')
/** Zod schema for the origin database password. */
export const HyperdriveOriginPasswordSchema: z.ZodType<
	ConfigCreateParams.PublicDatabase['password']
> = z.string().describe('The database password')

// --- Caching Field Schemas (Referencing ConfigCreateParams.HyperdriveHyperdriveCachingEnabled) ---

/** Zod schema for disabling caching. */
export const HyperdriveCachingDisabledSchema: z.ZodType<
	ConfigCreateParams.HyperdriveHyperdriveCachingEnabled['disabled']
> = z.boolean().optional().describe('Whether caching is disabled')
/** Zod schema for the maximum cache age. */
export const HyperdriveCachingMaxAgeSchema: z.ZodType<
	ConfigCreateParams.HyperdriveHyperdriveCachingEnabled['max_age']
> = z.number().int().min(1).optional().describe('Maximum cache age in seconds')
/** Zod schema for the stale while revalidate duration. */
export const HyperdriveCachingStaleWhileRevalidateSchema: z.ZodType<
	ConfigCreateParams.HyperdriveHyperdriveCachingEnabled['stale_while_revalidate']
> = z.number().int().min(1).optional().describe('Stale while revalidate duration in seconds')

// --- List Parameter Schemas (Cannot directly type against SDK ConfigListParams which only has account_id) ---

/** Zod schema for the list page number. */
export const HyperdriveListParamPageSchema = z
	.number()
	.int()
	.positive()
	.optional()
	.describe('Page number of results')
/** Zod schema for the list results per page. */
export const HyperdriveListParamPerPageSchema = z
	.number()
	.int()
	.min(1)
	.max(100)
	.optional()
	.describe('Number of results per page')
/** Zod schema for the list order field. */
export const HyperdriveListParamOrderSchema = z
	.enum(['id', 'name'])
	.optional()
	.describe('Field to order by')
/** Zod schema for the list order direction. */
export const HyperdriveListParamDirectionSchema = z
	.enum(['asc', 'desc'])
	.optional()
	.describe('Direction to order')

// --- Tool Parameter Schemas ---

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/format.spec.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, expect, it } from 'vitest'

import { fmt } from './format'

describe('fmt', () => {
	describe('trim()', () => {
		it('should return an empty string for an empty input', () => {
			expect(fmt.trim('')).toBe('')
		})

		it('should trim leading and trailing spaces', () => {
			expect(fmt.trim('  hello  ')).toBe('hello')
		})

		it('should trim leading and trailing newlines', () => {
			expect(fmt.trim('\n\nhello\n\n')).toBe('hello')
		})

		it('should trim leading/trailing spaces and newlines from each line but not remove empty lines', () => {
			const input = `
        line1
          line2

        line3
      `
			const expected = `line1
line2

line3`
			expect(fmt.trim(input)).toBe(expected)
		})

		it('should handle a string that is already trimmed', () => {
			expect(fmt.trim('hello\nworld')).toBe('hello\nworld')
		})

		it('should handle a string with only spaces', () => {
			expect(fmt.trim('   ')).toBe('')
		})

		it('should handle a string with only newlines', () => {
			expect(fmt.trim('\n\n\n')).toBe('')
		})

		it('should preserve empty lines from the middle', () => {
			expect(fmt.trim('hello\n\nworld')).toBe('hello\n\nworld')
		})
	})

	describe('oneLine()', () => {
		it('should return an empty string for an empty input', () => {
			expect(fmt.oneLine('')).toBe('')
		})

		it('should convert a multi-line string to a single line', () => {
			expect(fmt.oneLine('hello\nworld')).toBe('hello world')
		})

		it('should trim leading/trailing spaces and newlines before joining', () => {
			expect(fmt.oneLine('  hello  \n  world  \n')).toBe('hello world')
		})

		it('should remove empty lines before joining', () => {
			expect(fmt.oneLine('hello\n\nworld')).toBe('hello world')
		})

		it('should handle a string that is already a single line', () => {
			expect(fmt.oneLine('hello world')).toBe('hello world')
		})

		it('should handle a string with only spaces and newlines', () => {
			expect(fmt.oneLine('  \n   \n  ')).toBe('')
		})
	})

	describe('asTSV()', () => {
		it('should convert an empty array to an empty string', async () => {
			expect(await fmt.asTSV([])).toBe('')
		})

		it('should convert an array of one object to a TSV string', async () => {
			const data = [{ a: 1, b: 'hello' }]
			expect(await fmt.asTSV(data)).toBe('a\tb\n1\thello')
		})

		it('should convert an array of multiple objects to a TSV string', async () => {
			const data = [
				{ a: 1, b: 'hello' },
				{ a: 2, b: 'world' },
			]
			expect(await fmt.asTSV(data)).toBe('a\tb\n1\thello\n2\tworld')
		})

		it('should handle objects with different keys (using keys from the first object as headers)', async () => {
			const data = [
				{ a: 1, b: 'hello' },
				{ a: 2, c: 'world' },
			]
			expect(await fmt.asTSV(data)).toBe('a\tb\n1\thello\n2\t')
			expect(await fmt.asTSV(data)).toMatchInlineSnapshot(`
				"a	b
				1	hello
				2	"
			`)
		})

		it('should handle values with tabs and newlines (fast-csv should quote them)', async () => {
			const data = [{ name: 'John\tDoe', description: 'Line1\nLine2' }]
			expect(await fmt.asTSV(data)).toBe('name\tdescription\n"John\tDoe"\t"Line1\nLine2"')
			expect(await fmt.asTSV(data)).toMatchInlineSnapshot(`
				"name	description
				"John	Doe"	"Line1
				Line2""
			`)
		})

		it('should handle values with quotes (fast-csv should escape them)', async () => {
			const data = [{ name: 'James "Jim" Raynor' }]
			expect(await fmt.asTSV(data)).toBe('name\n"James ""Jim"" Raynor"')
			expect(await fmt.asTSV(data)).toMatchInlineSnapshot(`
				"name
				"James ""Jim"" Raynor""
			`)
		})
	})
})

```

--------------------------------------------------------------------------------
/apps/logpush/src/tools/logpush.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import { fetchCloudflareApi } from '@repo/mcp-common/src/cloudflare-api'
import { getProps } from '@repo/mcp-common/src/get-props'

import type { LogsMCP } from '../logpush.app'

const zJobIdentifier = z.number().int().min(1).optional().describe('Unique id of the job.')
const zEnabled = z.boolean().optional().describe('Flag that indicates if the job is enabled.')
const zName = z
	.string()
	.regex(/^[a-zA-Z0-9\-.]*$/)
	.max(512)
	.nullable()
	.optional()
	.describe('Optional human readable job name. Not unique.')
const zDataset = z
	.string()
	.regex(/^[a-zA-Z0-9_-]*$/)
	.max(256)
	.nullable()
	.optional()
	.describe('Name of the dataset.')
const zLastComplete = z
	.string()
	.datetime()
	.nullable()
	.optional()
	.describe('Records the last time for which logs have been successfully pushed.')
const zLastError = z
	.string()
	.datetime()
	.nullable()
	.optional()
	.describe('Records the last time the job failed.')
const zErrorMessage = z
	.string()
	.nullable()
	.optional()
	.describe('If not null, the job is currently failing.')

export const zLogpushJob = z
	.object({
		id: zJobIdentifier,
		enabled: zEnabled,
		name: zName,
		dataset: zDataset,
		last_complete: zLastComplete,
		last_error: zLastError,
		error_message: zErrorMessage,
	})
	.nullable()
	.optional()

const zApiResponseCommon = z.object({
	success: z.literal(true),
	errors: z.array(z.object({ message: z.string() })).optional(),
})

const zLogPushJobResults = z.array(zLogpushJob).optional()

// The complete schema for zone_logpush_job_response_collection
export const zLogpushJobResponseCollection = zApiResponseCommon.extend({
	result: zLogPushJobResults,
})

/**
 * Fetches available telemetry keys for a specified Cloudflare Worker
 * @param accountId Cloudflare account ID
 * @param apiToken Cloudflare API token
 * @returns List of telemetry keys available for the worker
 */

export async function handleGetAccountLogPushJobs(
	accountId: string,
	apiToken: string
): Promise<z.infer<typeof zLogPushJobResults>> {
	// Call the Public API
	const data = await fetchCloudflareApi({
		endpoint: `/logpush/jobs`,
		accountId,
		apiToken,
		responseSchema: zLogpushJobResponseCollection,
		options: {
			method: 'GET',
			headers: {
				'Content-Type': 'application/json',
				'portal-version': '2',
			},
		},
	})

	const res = data as z.infer<typeof zLogpushJobResponseCollection>
	return (res.result ?? []).slice(0, 100)
}

/**
 * Registers the logs analysis tool with the MCP server
 * @param server The MCP server instance
 * @param accountId Cloudflare account ID
 * @param apiToken Cloudflare API token
 */
export function registerLogsTools(agent: LogsMCP) {
	// Register the worker logs analysis tool by worker name
	agent.server.tool(
		'logpush_jobs_by_account_id',
		`All Logpush jobs by Account ID.

		You should use this tool when:
		- You have questions or wish to request information about their Cloudflare Logpush jobs by account
		- You want a condensed version for the output results of your account's Cloudflare Logpush job

		This tool returns at most the first 100 jobs.
		`,
		{},
		async () => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}
			try {
				const props = getProps(agent)
				const result = await handleGetAccountLogPushJobs(accountId, props.accessToken)
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result,
							}),
						},
					],
				}
			} catch (e) {
				agent.server.recordError(e)
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								error: `Error analyzing logpush jobs: ${e instanceof Error && e.message}`,
							}),
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/apps/browser-rendering/src/tools/browser.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import { getCloudflareClient } from '@repo/mcp-common/src/cloudflare-api'
import { getProps } from '@repo/mcp-common/src/get-props'

import type { BrowserMCP } from '../browser.app'

export function registerBrowserTools(agent: BrowserMCP) {
	agent.server.tool(
		'get_url_html_content',
		'Get page HTML content',
		{
			url: z.string().url(),
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}
			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = await client.browserRendering.content.create({
					account_id: accountId,
					url: params.url,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: r,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting page html: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'get_url_markdown',
		'Get page converted into Markdown',
		{
			url: z.string().url(),
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}
			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = (await client.post(`/accounts/${accountId}/browser-rendering/markdown`, {
					body: {
						url: params.url,
					},
				})) as { result: string }

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: r.result,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting page in markdown: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'get_url_screenshot',
		'Get page screenshot',
		{
			url: z.string().url(),
			viewport: z
				.object({
					height: z.number().default(600),
					width: z.number().default(800),
				})
				.optional(),
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}
			try {
				const props = getProps(agent)
				// Cf client appears to be broken, so we use the raw API instead.
				// const client = getCloudflareClient(props.accessToken)
				// const r = await client.browserRendering.screenshot.create({
				// 	account_id: accountId,
				// 	url: params.url,
				// 	viewport: params.viewport,
				// })

				const r = await fetch(
					`https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-rendering/screenshot`,
					{
						method: 'POST',
						headers: {
							'Content-Type': 'application/json',
							Authorization: `Bearer ${props.accessToken}`,
						},
						body: JSON.stringify({
							url: params.url,
							viewport: params.viewport,
						}),
					}
				)

				const arrayBuffer = await r.arrayBuffer()
				const base64Image = Buffer.from(arrayBuffer).toString('base64')

				return {
					content: [
						{
							type: 'image',
							mimeType: 'image/png',
							data: base64Image,
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting page in markdown: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/apps/cloudflare-one-casb/src/cf1-casb.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerIntegrationsTools } from './tools/integrations.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './cf1-casb.context'

export { UserDetails }

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps

type State = { activeAccountId: string | null }
export class CASBMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}

	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)
		registerIntegrationsTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}
const CloudflareOneCasbScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'teams:read': 'See Cloudflare One Resources',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(CASBMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': CASBMCP.serve('/mcp'),
				'/sse': CASBMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: CloudflareOneCasbScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/autorag/src/autorag.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerAutoRAGTools } from './tools/autorag.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './autorag.context'

const env = getEnv<Env>()

export { UserDetails }

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps
type State = { activeAccountId: string | null }

export class AutoRAGMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)

		// Register Cloudflare Log Push tools
		registerAutoRAGTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const LogPushScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'rag:write': 'Grants write level access to AutoRag.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(AutoRAGMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': AutoRAGMCP.serve('/mcp'),
				'/sse': AutoRAGMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: LogPushScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/browser-rendering/src/browser.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerBrowserTools } from './tools/browser.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './browser.context'

const env = getEnv<Env>()

export { UserDetails }

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps
type State = { activeAccountId: string | null }

export class BrowserMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)

		// Register Cloudflare Log Push tools
		registerBrowserTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const BrowserScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'browser:write': 'Grants write level access to Browser Rendering.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(BrowserMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': BrowserMCP.serve('/mcp'),
				'/sse': BrowserMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: BrowserScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/ai-gateway/src/ai-gateway.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerAIGatewayTools } from './tools/ai-gateway.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './ai-gateway.context'

const env = getEnv<Env>()

export { UserDetails }

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps
type State = { activeAccountId: string | null }

export class AIGatewayMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)

		// Register Cloudflare Log Push tools
		registerAIGatewayTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const AIGatewayScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'aig:read': 'Grants read level access to AI Gateway.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(AIGatewayMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': AIGatewayMCP.serve('/mcp'),
				'/sse': AIGatewayMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: AIGatewayScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/auditlogs/src/auditlogs.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerAuditLogTools } from './tools/auditlogs.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './auditlogs.context'

const env = getEnv<Env>()

export { UserDetails }

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps

export type State = { activeAccountId: string | null }

export class AuditlogMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})
		registerAccountTools(this)

		// Register Cloudflare Audit Log tools
		registerAuditLogTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const AuditlogScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'auditlogs:read': 'See your resource configuration changes.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(AuditlogMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': AuditlogMCP.serve('/mcp'),
				'/sse': AuditlogMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: AuditlogScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/dex-analysis/src/dex-analysis.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { MetricsTracker } from '@repo/mcp-observability'

import { registerDEXTools } from './tools/dex-analysis.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './dex-analysis.context'

export { UserDetails }
export { WarpDiagReader } from './warp_diag_reader'

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps

type State = { activeAccountId: string | null }

export class CloudflareDEXMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}

	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)
		registerDEXTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const DexScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'dex:write':
		'Grants write level access to DEX resources like tests, fleet status, and remote captures.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(CloudflareDEXMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': CloudflareDEXMCP.serve('/mcp'),
				'/sse': CloudflareDEXMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: DexScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/sentry.ts:
--------------------------------------------------------------------------------

```typescript
import { APIError } from 'cloudflare'
import { Toucan, zodErrorsIntegration } from 'toucan-js'

import { McpError } from './mcp-error'

import type { BaseTransportOptions, Client, ClientOptions, Event, EventHint } from '@sentry/types'
import type { Context, Next } from 'hono'
import type { Context as SentryContext } from 'toucan-js/dist/types'
import type { MCPEnvironment } from './config'

function is5xxError(status: number): boolean {
	return status >= 500 && status <= 599
}

export class SentryClient {
	private sentry: Toucan
	constructor(sentry: Toucan) {
		this.sentry = sentry
	}

	public recordError(e: unknown) {
		if (this.sentry) {
			// ignore errors from McpError and APIError (cloudflare) that have reportToSentry = false, or aren't 5xx errors
			if (e instanceof McpError) {
				if (e.reportToSentry === false) {
					return
				}
			} else if (e instanceof APIError) {
				if (!is5xxError(e.status)) {
					return
				}
			}
			this.sentry.captureException(e)
		}
	}

	public setUser(userId: string) {
		this.sentry.setUser({ ...this.sentry.getUser(), user_id: userId })
	}
}

interface BaseBindings {
	ENVIRONMENT: MCPEnvironment
	GIT_HASH: string
	SENTRY_DSN: string
	SENTRY_ACCESS_CLIENT_ID: string
	SENTRY_ACCESS_CLIENT_SECRET: string
}

export interface BaseHonoContext {
	Bindings: BaseBindings
	Variables: {
		sentry?: SentryClient
	}
}

export function initSentry<T extends BaseBindings>(
	env: T,
	ctx: SentryContext,
	req?: Request<unknown, CfProperties>
): SentryClient {
	const sentry = new Toucan({
		dsn: env.SENTRY_DSN,
		request: req,
		environment: env.ENVIRONMENT,
		context: ctx,
		release: env.GIT_HASH,
		requestDataOptions: {
			allowedHeaders: [
				'user-agent',
				'cf-challenge',
				'accept-encoding',
				'accept-language',
				'cf-ray',
				'content-length',
				'content-type',
				'host',
			],
			// Allow ONLY the “scope” param in order to avoid recording jwt, code, state and any other callback params
			allowedSearchParams: /^scope$/,
		},
		integrations: [
			zodErrorsIntegration({ saveAttachments: true }),
			{
				name: 'mcp-api-errors',
				processEvent(
					event: Event,
					_hint: EventHint,
					_client: Client<ClientOptions<BaseTransportOptions>>
				): Event {
					const processedEvent = applyMcpErrorsToEvent(event)
					return processedEvent
				},
			},
		],
		transportOptions: {
			headers: {
				'CF-Access-Client-ID': env.SENTRY_ACCESS_CLIENT_ID,
				'CF-Access-Client-Secret': env.SENTRY_ACCESS_CLIENT_SECRET,
			},
		},
	})
	return new SentryClient(sentry)
}

export function initSentryWithUser<T extends BaseBindings>(
	env: T,
	ctx: SentryContext,
	userId: string,
	req?: Request<unknown, CfProperties>
): SentryClient {
	const sentryClient = initSentry(env, ctx, req)
	sentryClient.setUser(userId)
	return sentryClient
}

export async function useSentry<T extends BaseHonoContext>(
	c: Context<T>,
	next: Next
): Promise<void> {
	c.set('sentry', initSentry(c.env, c.executionCtx, c.req.raw))
	await next()
}

export function setSentryRequestHeaders(sentry: Toucan, req: Request<unknown, CfProperties>) {
	const colo: string = req.cf && typeof req.cf.colo === 'string' ? req.cf.colo : 'UNKNOWN'
	sentry.setTag('colo', colo)

	const ip_address = req.headers.get('cf-connecting-ip') ?? ''
	const userAgent = req.headers.get('user-agent') ?? ''
	sentry.setUser({
		...sentry.getUser(),
		ip_address,
		userAgent,
		colo,
	})
}

function applyMcpErrorsToEvent(event: Event): Event {
	if (event.exception === undefined || event.exception.values === undefined) {
		return event
	}

	if (event.exception instanceof McpError) {
		try {
			return {
				...event,
				extra: {
					...event.extra,
					statusCode: event.exception.code,
					internalMessage: event.exception.internalMessage,
				},
			}
		} catch (e) {
			// Hopefully we never throw errors here, but record it
			// with the event just in case.
			return {
				...event,
				extra: {
					...event.extra,
					'McpError sentry integration parse error': {
						message: `an exception was thrown while processing McpError within applyMcpErrorsToEvent()`,
						error: e instanceof Error ? `${e.name}: ${e.cause}\n${e.stack}` : 'unknown',
					},
				},
			}
		}
	}

	return event
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/tools/docs-vectorize.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import type { CloudflareMcpAgentNoAccount } from '../types/cloudflare-mcp-agent.types'

interface RequiredEnv {
	AI: Ai
	VECTORIZE: VectorizeIndex
}

// Always return 10 results for simplicity, don't make it configurable
const TOP_K = 10

/**
 * Registers the docs search tool with the MCP server
 * @param agent The MCP server instance
 */
export function registerDocsTools(agent: CloudflareMcpAgentNoAccount, env: RequiredEnv) {
	agent.server.tool(
		'search_cloudflare_documentation',
		`Search the Cloudflare documentation.

		This tool should be used to answer any question about Cloudflare products or features, including:
		- Workers, Pages, R2, Images, Stream, D1, Durable Objects, KV, Workflows, Hyperdrive, Queues
		- AutoRAG, Workers AI, Vectorize, AI Gateway, Browser Rendering
		- Zero Trust, Access, Tunnel, Gateway, Browser Isolation, WARP, DDOS, Magic Transit, Magic WAN
		- CDN, Cache, DNS, Zaraz, Argo, Rulesets, Terraform, Account and Billing

		Results are returned as semantically similar chunks to the query.
		`,
		{
			query: z.string(),
		},
		{
			title: 'Search Cloudflare docs',
			annotations: {
				readOnlyHint: true,
			},
		},
		async ({ query }) => {
			const results = await queryVectorize(env.AI, env.VECTORIZE, query, TOP_K)
			const resultsAsXml = results
				.map((result) => {
					return `<result>
<url>${result.url}</url>
<title>${result.title}</title>
<text>
${result.text}
</text>
</result>`
				})
				.join('\n')
			return {
				content: [{ type: 'text', text: resultsAsXml }],
			}
		}
	)

	// Note: this is a tool instead of a prompt because
	// prompt support is much less common than tools.
	agent.server.tool(
		'migrate_pages_to_workers_guide',
		`ALWAYS read this guide before migrating Pages projects to Workers.`,
		{},
		{
			title: 'Get Pages migration guide',
			annotations: {
				readOnlyHint: true,
			},
		},
		async () => {
			const res = await fetch(
				'https://developers.cloudflare.com/workers/prompts/pages-to-workers.txt',
				{
					cf: { cacheEverything: true, cacheTtl: 3600 },
				}
			)

			if (!res.ok) {
				return {
					content: [{ type: 'text', text: 'Error: Failed to fetch guide. Please try again.' }],
				}
			}

			return {
				content: [
					{
						type: 'text',
						text: await res.text(),
					},
				],
			}
		}
	)
}

async function queryVectorize(ai: Ai, vectorizeIndex: VectorizeIndex, query: string, topK: number) {
	// Recommendation from: https://ai.google.dev/gemma/docs/embeddinggemma/model_card#prompt_instructions
	const [queryEmbedding] = await getEmbeddings(ai, ['task: search result | query: ' + query])

	const { matches } = await vectorizeIndex.query(queryEmbedding, {
		topK,
		returnMetadata: 'all',
		returnValues: false,
	})

	return matches.map((match, _i) => ({
		similarity: Math.min(match.score, 1),
		id: match.id,
		url: sourceToUrl(String(match.metadata?.filePath ?? '')),
		title: String(match.metadata?.title ?? ''),
		text: String(match.metadata?.text ?? ''),
	}))
}

const TOP_DIR = 'src/content/docs'
function sourceToUrl(path: string) {
	const prefix = `${TOP_DIR}/`
	return (
		'https://developers.cloudflare.com/' +
		(path.startsWith(prefix) ? path.slice(prefix.length) : path)
			.replace(/index\.mdx$/, '')
			.replace(/\.mdx$/, '')
	)
}

async function getEmbeddings(ai: Ai, strings: string[]): Promise<number[][]> {
	const response = await doWithRetries(() =>
		// @ts-expect-error embeddinggemma not in types yet
		ai.run('@cf/google/embeddinggemma-300m', {
			text: strings,
		})
	)

	// @ts-expect-error embeddinggemma not in types yet
	return response.data
}

/**
 * @template T
 * @param {() => Promise<T>} action
 */
async function doWithRetries<T>(action: () => Promise<T>) {
	const NUM_RETRIES = 10
	const INIT_RETRY_MS = 50
	for (let i = 0; i <= NUM_RETRIES; i++) {
		try {
			return await action()
		} catch (e) {
			// TODO: distinguish between user errors (4xx) and system errors (5xx)
			console.error(e)
			if (i === NUM_RETRIES) {
				throw e
			}
			// Exponential backoff with full jitter
			await scheduler.wait(Math.random() * INIT_RETRY_MS * Math.pow(2, i))
		}
	}
	// Should never reach here – last loop iteration should return
	throw new Error('An unknown error occurred')
}

```

--------------------------------------------------------------------------------
/apps/logpush/src/logpush.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerLogsTools } from './tools/logpush.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './logpush.context'

const env = getEnv<Env>()

export { UserDetails }

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps
type State = { activeAccountId: string | null }

export class LogsMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)

		// Register Cloudflare Log Push tools
		registerLogsTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const LogPushScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'logpush:write':
		'Grants read and write access to Logpull and Logpush, and read access to Instant Logs. Note that all Logpush API operations require Logs: Write permission because Logpush jobs contain sensitive information.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(LogsMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': LogsMCP.serve('/mcp'),
				'/sse': LogsMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: LogPushScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/workers-bindings/evals/kv_namespaces.eval.ts:
--------------------------------------------------------------------------------

```typescript
import { expect } from 'vitest'
import { describeEval } from 'vitest-evals'

import { runTask } from '@repo/eval-tools/src/runTask'
import { checkFactuality } from '@repo/eval-tools/src/scorers'
import { eachModel } from '@repo/eval-tools/src/test-models'
import { KV_NAMESPACE_TOOLS } from '@repo/mcp-common/src/tools/kv_namespace.tools'

import { initializeClient } from './utils' // Assuming utils.ts will exist here

eachModel('$modelName', ({ model }) => {
	describeEval('Create Cloudflare KV Namespace', {
		data: async () => [
			{
				input: 'Create a new Cloudflare KV Namespace called "my-test-namespace".',
				expected: `The ${KV_NAMESPACE_TOOLS.kv_namespace_create} tool should be called to create a new kv namespace.`,
			},
		],
		task: async (input: string) => {
			const client = await initializeClient(/* Pass necessary mocks/config */)
			const { promptOutput, toolCalls } = await runTask(client, model, input)
			const toolCall = toolCalls.find(
				(call) => call.toolName === KV_NAMESPACE_TOOLS.kv_namespace_create
			)
			expect(toolCall, 'Tool kv_namespace_create was not called').toBeDefined()

			return promptOutput
		},
		scorers: [checkFactuality],
		threshold: 1,
		timeout: 60000, // 60 seconds
	})
	describeEval('List Cloudflare KV Namespaces', {
		data: async () => [
			{
				input: 'List all my Cloudflare KV Namespaces.',
				expected: `The ${KV_NAMESPACE_TOOLS.kv_namespaces_list} tool should be called to retrieve the list of kv namespaces. There should be at least one kv namespace in the list.`,
			},
		],
		task: async (input: string) => {
			const client = await initializeClient(/* Pass necessary mocks/config */)
			const { promptOutput, toolCalls } = await runTask(client, model, input)
			const toolCall = toolCalls.find(
				(call) => call.toolName === KV_NAMESPACE_TOOLS.kv_namespaces_list
			)
			expect(toolCall, 'Tool kv_namespaces_list was not called').toBeDefined()

			return promptOutput
		},
		scorers: [checkFactuality],
		threshold: 1,
		timeout: 60000, // 60 seconds
	})
	describeEval('Rename Cloudflare KV Namespace', {
		data: async () => [
			{
				input: 'Rename my Cloudflare KV Namespace with ID 1234 to "my-new-test-namespace".',
				expected: `The ${KV_NAMESPACE_TOOLS.kv_namespace_update} tool should be called to rename the kv namespace.`,
			},
		],
		task: async (input: string) => {
			const client = await initializeClient(/* Pass necessary mocks/config */)
			const { promptOutput, toolCalls } = await runTask(client, model, input)
			const toolCall = toolCalls.find(
				(call) => call.toolName === KV_NAMESPACE_TOOLS.kv_namespace_update
			)
			expect(toolCall, 'Tool kv_namespace_update was not called').toBeDefined()

			return promptOutput
		},
		scorers: [checkFactuality],
		threshold: 1,
		timeout: 60000, // 60 seconds
	})
	describeEval('Get Cloudflare KV Namespace Details', {
		data: async () => [
			{
				input: 'Get details of my Cloudflare KV Namespace with ID 1234.',
				expected: `The ${KV_NAMESPACE_TOOLS.kv_namespace_get} tool should be called to retrieve the details of the kv namespace.`,
			},
		],
		task: async (input: string) => {
			const client = await initializeClient(/* Pass necessary mocks/config */)
			const { promptOutput, toolCalls } = await runTask(client, model, input)
			const toolCall = toolCalls.find(
				(call) => call.toolName === KV_NAMESPACE_TOOLS.kv_namespace_get
			)
			expect(toolCall, 'Tool kv_namespace_get was not called').toBeDefined()

			return promptOutput
		},
		scorers: [checkFactuality],
		threshold: 1,
		timeout: 60000, // 60 seconds
	})
	describeEval('Delete Cloudflare KV Namespace', {
		data: async () => [
			{
				input: 'Delete the kv namespace with ID 1234.',
				expected: `The ${KV_NAMESPACE_TOOLS.kv_namespace_delete} tool should be called to delete the kv namespace.`,
			},
		],
		task: async (input: string) => {
			const client = await initializeClient(/* Pass necessary mocks/config */)
			const { promptOutput, toolCalls } = await runTask(client, model, input)
			const toolCall = toolCalls.find(
				(call) => call.toolName === KV_NAMESPACE_TOOLS.kv_namespace_delete
			)
			expect(toolCall, 'Tool kv_namespace_delete was not called').toBeDefined()

			return promptOutput
		},
		scorers: [checkFactuality],
		threshold: 1,
		timeout: 60000, // 60 seconds
	})
})

```

--------------------------------------------------------------------------------
/apps/radar/src/radar.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { MetricsTracker } from '@repo/mcp-observability'

import { BASE_INSTRUCTIONS } from './radar.context'
import { registerRadarTools } from './tools/radar.tools'
import { registerUrlScannerTools } from './tools/url-scanner.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './radar.context'

const env = getEnv<Env>()

export { UserDetails }

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps
type State = { activeAccountId: string | null }

export class RadarMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
			options: { instructions: BASE_INSTRUCTIONS },
		})

		registerAccountTools(this)
		registerRadarTools(this)
		registerUrlScannerTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const RadarScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'radar:read': 'Grants access to read Cloudflare Radar data.',
	'url_scanner:write': 'Grants write level access to URL Scanner',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(RadarMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': RadarMCP.serve('/mcp'),
				'/sse': RadarMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: RadarScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/packages/mcp-observability/src/analytics-engine.ts:
--------------------------------------------------------------------------------

```typescript
export type MetricsBindings = {
	MCP_METRICS: AnalyticsEngineDataset
}

/**
 * Generic metrics event utilities
 * @description Wrapper for RA binding
 */
export class MetricsTracker {
	constructor(
		private wae: AnalyticsEngineDataset,
		private mcpServerInfo: {
			name: string
			version: string
		}
	) {}

	logEvent(event: MetricsEvent): void {
		try {
			event.serverInfo = this.mcpServerInfo
			let dataPoint = event.toDataPoint()
			this.wae.writeDataPoint(dataPoint)
		} catch (e) {
			console.error(`Failed to log metrics event, ${e}`)
		}
	}
}

/**
 * MetricsEvent
 *
 * Each event type is stored with a different indexId and has an associated class which
 * maps a more ergonomic event object to a ReadyAnalyticsEvent
 */
export abstract class MetricsEvent {
	public _serverInfo: { name: string; version: string } | undefined
	set serverInfo(serverInfo: { name: string; version: string }) {
		this._serverInfo = serverInfo
	}

	get serverInfo(): { name: string; version: string } {
		if (!this._serverInfo) {
			throw new Error('Server info not set')
		}
		return this._serverInfo
	}

	/**
	 * Output a valid AnalyticsEngineDataPoint. Use `mapBlobs` and `mapDoubles` to write well defined
	 * analytics engine datapoints. The first and second blob entries are reserved for the MCP server name and
	 * MCP server version.
	 */
	abstract toDataPoint(): AnalyticsEngineDataPoint

	mapBlobs(blobs: Blobs): Array<string | null> {
		if (blobs.blob1 || blobs.blob2) {
			throw new MetricsError(
				'Failed to map blobs, blob1 and blob2 are reserved for MCP server info'
			)
		}
		// add placeholder blobs, filled in by the MetricsTracker later
		blobs.blob1 = this.serverInfo.name
		blobs.blob2 = this.serverInfo.version
		const blobsArray = new Array(Object.keys(blobs).length)
		for (const [key, value] of Object.entries(blobs)) {
			const match = key.match(/^blob(\d+)$/)
			if (match === null || match.length < 2) {
				// we should never hit this because of the typedefinitions above,
				// but this error is for safety
				throw new MetricsError('Failed to map blobs, invalid key')
			}
			const index = parseInt(match[1], 10)
			if (isNaN(index)) {
				// we should never hit this because of the typedefinitions above,
				// but this esrror is for safety
				throw new MetricsError('Failed to map blobs, invalid index')
			}
			if (index - 1 >= blobsArray.length) {
				throw new MetricsError('Failed to map blobs, missing blob')
			}
			blobsArray[index - 1] = value
		}
		return blobsArray
	}

	mapDoubles(doubles: Doubles): number[] {
		const doublesArray = new Array(Object.keys(doubles).length)
		for (const [key, value] of Object.entries(doubles)) {
			const match = key.match(/^double(\d+)$/)
			if (match === null || match.length < 2) {
				// we should never hit this because of the typedefinitions above,
				// but this error is for safety
				throw new MetricsError(': Failed to map doubles, invalid key')
			}
			const index = parseInt(match[1], 10)
			if (isNaN(index)) {
				// we should never hit this because of the typedefinitions above,
				// but this error is for safety
				throw new MetricsError('Failed to map doubles, invalid index')
			}
			if (index - 1 >= doublesArray.length) {
				throw new MetricsError('Failed to map doubles, missing blob')
			}
			doublesArray[index - 1] = value
		}
		return doublesArray
	}
}

export enum MetricsEventIndexIds {
	AUTH_USER = 'auth_user',
	SESSION_START = 'session_start',
	TOOL_CALL = 'tool_call',
	CONTAINER_MANAGER = 'container_manager',
}

/**
 * Utility functions to map named blob/double objects to an array
 * We do this so we don't have to annotate `blob1`, `blob2`, etc in comments.
 *
 * I prefer this to just writing it in an array because it'll be easier to reference
 * later when we are writing ready analytics queries.
 *
 * IMO named tuples and raw arrays aren't as ergonomic to work with, but they require less of this code below
 */
type Range1To20 =
	| 1
	| 2
	| 3
	| 4
	| 5
	| 6
	| 7
	| 8
	| 9
	| 10
	| 11
	| 12
	| 13
	| 14
	| 15
	| 16
	| 17
	| 18
	| 19
	| 20

// blob1 and blob2 are reserved for server name and version
type Blobs = {
	[key in `blob${Range1To20}`]?: string | null
}

type Doubles = {
	[key in `double${Range1To20}`]?: number
}

export class MetricsError extends Error {
	constructor(message: string) {
		super(message)
		this.name = 'MetricsError'
	}
}

```

--------------------------------------------------------------------------------
/apps/dns-analytics/src/dns-analytics.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { registerZoneTools } from '@repo/mcp-common/src/tools/zone.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerAnalyticTools } from './tools/dex-analytics.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './dns-analytics.context'

export { UserDetails }

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
export type Props = AuthProps

export type State = { activeAccountId: string | null }

export class DNSAnalyticsMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}

	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)

		// Register Cloudflare DNS Analytics tools
		registerAnalyticTools(this)

		registerZoneTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const AnalyticsScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'zone:read': 'See your zones',
	'dns_settings:read': 'See your DNS settings',
	'dns_analytics:read': 'See your DNS analytics',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(DNSAnalyticsMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': DNSAnalyticsMCP.serve('/mcp'),
				'/sse': DNSAnalyticsMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: AnalyticsScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/sandbox-container/container/sandbox.container.app.ts:
--------------------------------------------------------------------------------

```typescript
import { exec } from 'node:child_process'
import * as fs from 'node:fs/promises'
import path from 'node:path'
import { serve } from '@hono/node-server'
import { zValidator } from '@hono/zod-validator'
import { Hono } from 'hono'
import { streamText } from 'hono/streaming'
import mime from 'mime'

import { ExecParams, FileWrite } from '../shared/schema.ts'
import {
	DIRECTORY_CONTENT_TYPE,
	get_file_name_from_path,
	get_mime_type,
	list_files_in_directory,
} from './fileUtils.ts'

import type { FileList } from '../shared/schema.ts'

process.chdir('workdir')

const app = new Hono()

app.get('/ping', (c) => c.text('pong!'))

/**
 * GET /files/ls
 *
 * Gets all files in a directory
 */
app.get('/files/ls', async (c) => {
	const directoriesToRead = ['.']
	const files: FileList = { resources: [] }

	while (directoriesToRead.length > 0) {
		const curr = directoriesToRead.pop()
		if (!curr) {
			throw new Error('Popped empty stack, error while listing directories')
		}
		const fullPath = path.join(process.cwd(), curr)
		const dir = await fs.readdir(fullPath, { withFileTypes: true })
		for (const dirent of dir) {
			const relPath = path.relative(process.cwd(), `${fullPath}/${dirent.name}`)
			if (dirent.isDirectory()) {
				directoriesToRead.push(dirent.name)
				files.resources.push({
					uri: `file:///${relPath}`,
					name: dirent.name,
					mimeType: 'inode/directory',
				})
			} else {
				const mimeType = mime.getType(dirent.name)
				files.resources.push({
					uri: `file:///${relPath}`,
					name: dirent.name,
					mimeType: mimeType ?? undefined,
				})
			}
		}
	}

	return c.json(files)
})

/**
 * GET /files/contents/{filepath}
 *
 * Get the contents of a file or directory
 */
app.get('/files/contents/*', async (c) => {
	const reqPath = await get_file_name_from_path(c.req.path)
	try {
		const mimeType = await get_mime_type(reqPath)
		const headers = mimeType ? { 'Content-Type': mimeType } : undefined
		const contents = await fs.readFile(path.join(process.cwd(), reqPath))
		return c.newResponse(contents, 200, headers)
	} catch (e: any) {
		if (e.code) {
			if (e.code === 'EISDIR') {
				const files = await list_files_in_directory(reqPath)
				return c.newResponse(files.join('\n'), 200, {
					'Content-Type': DIRECTORY_CONTENT_TYPE,
				})
			}
			if (e.code === 'ENOENT') {
				return c.notFound()
			}
		}

		throw e
	}
})

/**
 * POST /files/contents
 *
 * Create or update file contents
 */
app.post('/files/contents', zValidator('json', FileWrite), async (c) => {
	const file = c.req.valid('json')
	const reqPath = await get_file_name_from_path(file.path)

	try {
		await fs.writeFile(reqPath, file.text)
		return c.newResponse(null, 200)
	} catch (e) {
		return c.newResponse(`Error: ${e}`, 400)
	}
})

/**
 * DELETE /files/contents/{filepath}
 *
 * Delete a file or directory
 */
app.delete('/files/contents/*', async (c) => {
	const reqPath = await get_file_name_from_path(c.req.path)

	try {
		await fs.rm(path.join(process.cwd(), reqPath), { recursive: true })
		return c.newResponse('ok', 200)
	} catch (e: any) {
		if (e.code) {
			if (e.code === 'ENOENT') {
				return c.notFound()
			}
		}

		throw e
	}
})

/**
 * POST /exec
 *
 * Execute a command in a shell
 */
app.post('/exec', zValidator('json', ExecParams), (c) => {
	const execParams = c.req.valid('json')
	const proc = exec(execParams.args)
	return streamText(c, async (stream) => {
		return new Promise((resolve, reject) => {
			if (proc.stdout) {
				// Stream data from stdout
				proc.stdout.on('data', async (data) => {
					await stream.write(data.toString())
				})
			} else {
				void stream.write('WARNING: no stdout stream for process')
			}

			if (execParams.streamStderr) {
				if (proc.stderr) {
					proc.stderr.on('data', async (data) => {
						await stream.write(data.toString())
					})
				} else {
					void stream.write('WARNING: no stderr stream for process')
				}
			}

			// Handle process exit
			proc.on('exit', async (code) => {
				await stream.write(`Process exited with code: ${code}`)
				if (code === 0) {
					await stream.close()
					resolve()
				} else {
					console.error(`Process exited with code ${code}`)
					reject(new Error(`Process failed with code ${code}`))
				}
			})

			proc.on('error', (err) => {
				console.error('Error with process: ', err)
				reject(err)
			})
		})
	})
})

serve({
	fetch: app.fetch,
	port: 8080,
})

```

--------------------------------------------------------------------------------
/apps/graphql/src/graphql.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { initSentryWithUser } from '@repo/mcp-common/src/sentry'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { registerZoneTools } from '@repo/mcp-common/src/tools/zone.tools'
import { MetricsTracker } from '@repo/mcp-observability'

import { registerGraphQLTools } from './tools/graphql.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './graphql.context'

export { UserDetails }

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps
type State = { activeAccountId: string | null }

export class GraphQLMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}

	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined
		const sentry =
			props.type === 'user_token' ? initSentryWithUser(env, this.ctx, props.user.id) : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
			sentry,
		})

		// Register account tools
		registerAccountTools(this)

		// Register zone tools
		registerZoneTools(this)

		// Register GraphQL tools
		registerGraphQLTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const GraphQLScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'zone:read': 'See zone data such as settings, analytics, and DNS records.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(GraphQLMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': GraphQLMCP.serve('/mcp'),
				'/sse': GraphQLMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: GraphQLScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/autorag/src/tools/autorag.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { V4PagePaginationArray } from 'cloudflare/src/pagination.js'
import { z } from 'zod'

import { getCloudflareClient } from '@repo/mcp-common/src/cloudflare-api'
import { getProps } from '@repo/mcp-common/src/get-props'

import { pageParam, perPageParam } from '../types'

import type { AutoRAGMCP } from '../autorag.app'

export function registerAutoRAGTools(agent: AutoRAGMCP) {
	agent.server.tool(
		'list_rags',
		'List AutoRAGs (vector stores)',
		{
			page: pageParam,
			per_page: perPageParam,
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}
			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = (await client.getAPIList(
					`/accounts/${accountId}/autorag/rags`,
					// @ts-ignore
					V4PagePaginationArray,
					{ query: { page: params.page, per_page: params.per_page } }
				)) as unknown as {
					result: Array<{ id: string; source: string; paused: boolean }>
					result_info: { total_count: number }
				}

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								autorags: r.result.map((obj) => {
									return {
										id: obj.id,
										source: obj.source,
										paused: obj.paused,
									}
								}),
								total_count: r.result_info.total_count,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error listing rags: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'search',
		'Search Documents using AutoRAG (vector store)',
		{
			rag_id: z.string().describe('ID of the AutoRAG to search'),
			query: z.string().describe('Query to search for. Can be a URL, a title, or a snippet.'),
		},
		async (params) => {
			try {
				const accountId = await agent.getActiveAccountId()
				if (!accountId) {
					return {
						content: [
							{
								type: 'text',
								text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
							},
						],
					}
				}

				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = (await client.post(
					`/accounts/${accountId}/autorag/rags/${params.rag_id}/search`,
					{
						body: {
							query: params.query,
							max_num_results: 5,
						},
					}
				)) as { result: { data: Array<{ filename: string; content: Array<{ text: string }> }> } }

				const chunks = r.result.data
					.map((item) => {
						const data = item.content
							.map((content) => {
								return content.text
							})
							.join('\n\n')

						return `<file name="${item.filename}">${data}</file>`
					})
					.join('\n\n')

				return {
					content: [
						{
							type: 'text',
							text: chunks,
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error searching rag: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'ai_search',
		'AI Search Documents using AutoRAG (vector store)',
		{
			rag_id: z.string().describe('ID of the AutoRAG to search'),
			query: z.string().describe('Query to search for. Can be a URL, a title, or a snippet.'),
		},
		async (params) => {
			try {
				const accountId = await agent.getActiveAccountId()
				if (!accountId) {
					return {
						content: [
							{
								type: 'text',
								text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
							},
						],
					}
				}

				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = (await client.post(
					`/accounts/${accountId}/autorag/rags/${params.rag_id}/ai-search`,
					{
						body: {
							query: params.query,
							max_num_results: 10, // Limit can be bigger here, since llm is only getting the end response and not individual chunks
						},
					}
				)) as { result: { response: string } }

				return {
					content: [
						{
							type: 'text',
							text: r.result.response,
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error searching rag: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/apps/sandbox-container/server/userContainer.ts:
--------------------------------------------------------------------------------

```typescript
import { DurableObject } from 'cloudflare:workers'

import { OPEN_CONTAINER_PORT } from '../shared/consts'
import { MAX_CONTAINERS, proxyFetch, startAndWaitForPort } from './containerHelpers'
import { getContainerManager } from './containerManager'
import { fileToBase64 } from './utils'

import type { ExecParams, FileList, FileWrite } from '../shared/schema'
import type { Env } from './sandbox.server.context'

export class UserContainer extends DurableObject<Env> {
	constructor(
		public ctx: DurableObjectState,
		public env: Env
	) {
		console.log('creating user container DO')
		super(ctx, env)
	}

	async destroyContainer(): Promise<void> {
		await this.ctx.container?.destroy()
	}

	async killContainer(): Promise<void> {
		console.log('Reaping container')
		const containerManager = getContainerManager(this.env)
		const active = await containerManager.listActive()
		if (this.ctx.id.toString() in active) {
			console.log('killing container')
			await this.destroyContainer()
			await containerManager.killContainer(this.ctx.id.toString())
		}
	}

	async container_initialize(): Promise<string> {
		// kill container
		await this.killContainer()

		// try to cleanup cleanup old containers
		const containerManager = getContainerManager(this.env)

		// if more than half of our containers are being used, let's try reaping
		if ((await containerManager.listActive()).length >= MAX_CONTAINERS / 2) {
			await containerManager.tryKillOldContainers()
			if ((await containerManager.listActive()).length >= MAX_CONTAINERS) {
				throw new Error(
					`Unable to reap enough containers. There are ${MAX_CONTAINERS} active container sandboxes, please wait`
				)
			}
		}

		// start container
		let startedContainer = false
		await this.ctx.blockConcurrencyWhile(async () => {
			startedContainer = await startAndWaitForPort(
				this.env.ENVIRONMENT,
				this.ctx.container,
				OPEN_CONTAINER_PORT
			)
		})
		if (!startedContainer) {
			throw new Error('Failed to start container')
		}

		// track and manage lifecycle
		await containerManager.trackContainer(this.ctx.id.toString())

		return `Created new container`
	}

	async container_ping(): Promise<string> {
		const res = await proxyFetch(
			this.env.ENVIRONMENT,
			this.ctx.container,
			new Request(`http://host:${OPEN_CONTAINER_PORT}/ping`),
			OPEN_CONTAINER_PORT
		)
		if (!res || !res.ok) {
			throw new Error(`Request to container failed: ${await res.text()}`)
		}
		return await res.text()
	}

	async container_exec(params: ExecParams): Promise<string> {
		const res = await proxyFetch(
			this.env.ENVIRONMENT,
			this.ctx.container,
			new Request(`http://host:${OPEN_CONTAINER_PORT}/exec`, {
				method: 'POST',
				body: JSON.stringify(params),
				headers: {
					'content-type': 'application/json',
				},
			}),
			OPEN_CONTAINER_PORT
		)
		if (!res || !res.ok) {
			throw new Error(`Request to container failed: ${await res.text()}`)
		}
		const txt = await res.text()
		return txt
	}

	async container_ls(): Promise<FileList> {
		const res = await proxyFetch(
			this.env.ENVIRONMENT,
			this.ctx.container,
			new Request(`http://host:${OPEN_CONTAINER_PORT}/files/ls`),
			OPEN_CONTAINER_PORT
		)
		if (!res || !res.ok) {
			throw new Error(`Request to container failed: ${await res.text()}`)
		}
		const json = (await res.json()) as FileList
		return json
	}

	async container_file_delete(filePath: string): Promise<boolean> {
		const res = await proxyFetch(
			this.env.ENVIRONMENT,
			this.ctx.container,
			new Request(`http://host:${OPEN_CONTAINER_PORT}/files/contents/${filePath}`, {
				method: 'DELETE',
			}),
			OPEN_CONTAINER_PORT
		)
		return res.ok
	}
	async container_file_read(
		filePath: string
	): Promise<
		| { type: 'text'; textOutput: string; mimeType: string | undefined }
		| { type: 'base64'; base64Output: string; mimeType: string | undefined }
	> {
		const res = await proxyFetch(
			this.env.ENVIRONMENT,
			this.ctx.container,
			new Request(`http://host:${OPEN_CONTAINER_PORT}/files/contents/${filePath}`),
			OPEN_CONTAINER_PORT
		)
		if (!res || !res.ok) {
			throw new Error(`Request to container failed: ${await res.text()}`)
		}

		const mimeType = res.headers.get('Content-Type') ?? undefined
		const blob = await res.blob()

		if (mimeType && mimeType.startsWith('text')) {
			return {
				type: 'text',
				textOutput: await blob.text(),
				mimeType,
			}
		} else {
			return {
				type: 'base64',
				base64Output: await fileToBase64(blob),
				mimeType,
			}
		}
	}

	async container_file_write(file: FileWrite): Promise<string> {
		const res = await proxyFetch(
			this.env.ENVIRONMENT,
			this.ctx.container,
			new Request(`http://host:${OPEN_CONTAINER_PORT}/files/contents`, {
				method: 'POST',
				body: JSON.stringify(file),
				headers: {
					'content-type': 'application/json',
				},
			}),
			OPEN_CONTAINER_PORT
		)
		if (!res || !res.ok) {
			throw new Error(`Request to container failed: ${await res.text()}`)
		}
		return `Wrote file: ${file.path}`
	}
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/cloudflare-auth.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import { McpError } from './mcp-error'

import type { AuthRequest } from '@cloudflare/workers-oauth-provider'

// Constants
const PKCE_CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'
const RECOMMENDED_CODE_VERIFIER_LENGTH = 96
function base64urlEncode(value: string): string {
	let base64 = btoa(value)
	base64 = base64.replace(/\+/g, '-')
	base64 = base64.replace(/\//g, '_')
	base64 = base64.replace(/=/g, '')
	return base64
}

interface PKCECodes {
	codeChallenge: string
	codeVerifier: string
}
async function generatePKCECodes(): Promise<PKCECodes> {
	const output = new Uint32Array(RECOMMENDED_CODE_VERIFIER_LENGTH)
	crypto.getRandomValues(output)
	const codeVerifier = base64urlEncode(
		Array.from(output)
			.map((num: number) => PKCE_CHARSET[num % PKCE_CHARSET.length])
			.join('')
	)
	const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier))
	const hash = new Uint8Array(buffer)
	let binary = ''
	const hashLength = hash.byteLength
	for (let i = 0; i < hashLength; i++) {
		binary += String.fromCharCode(hash[i])
	}
	const codeChallenge = base64urlEncode(binary) //btoa(binary);
	return { codeChallenge, codeVerifier }
}

function generateAuthUrl({
	client_id,
	redirect_uri,
	state,
	code_challenge,
	scopes,
}: {
	client_id: string
	redirect_uri: string
	code_challenge: string
	state: string
	scopes: Record<string, string>
}) {
	const params = new URLSearchParams({
		response_type: 'code',
		client_id,
		redirect_uri,
		state,
		code_challenge,
		code_challenge_method: 'S256',
		scope: Object.keys(scopes).join(' '),
	})

	const upstream = new URL(`https://dash.cloudflare.com/oauth2/auth?${params.toString()}`)
	return upstream.href
}

/**
 * Constructs an authorization URL for Cloudflare.
 *
 * @param {Object} options
 * @param {string} options.client_id - The client ID of the application.
 * @param {string} options.redirect_uri - The redirect URI of the application.
 * @param {string} [options.state] - The state parameter.
 *
 * @returns {string} The authorization URL.
 */
export async function getAuthorizationURL({
	client_id,
	redirect_uri,
	state,
	scopes,
}: {
	client_id: string
	redirect_uri: string
	state: AuthRequest
	scopes: Record<string, string>
}): Promise<{ authUrl: string; codeVerifier: string }> {
	const { codeChallenge, codeVerifier } = await generatePKCECodes()

	return {
		authUrl: generateAuthUrl({
			client_id,
			redirect_uri,
			state: btoa(JSON.stringify({ ...state, codeVerifier })),
			code_challenge: codeChallenge,
			scopes,
		}),
		codeVerifier: codeVerifier,
	}
}

type AuthorizationToken = z.infer<typeof AuthorizationToken>
const AuthorizationToken = z.object({
	access_token: z.string(),
	expires_in: z.number(),
	refresh_token: z.string(),
	scope: z.string(),
	token_type: z.string(),
})
/**
 * Fetches an authorization token from Cloudflare.
 *
 * @param {Object} options
 * @param {string} options.client_id - The client ID of the application.
 * @param {string} options.client_secret - The client secret of the application.
 * @param {string} options.code - The authorization code.
 * @param {string} options.redirect_uri - The redirect URI of the application.
 *
 * @returns {Promise<[string, null] | [null, Response]>} A promise that resolves to an array containing the access token or an error response.
 */
export async function getAuthToken({
	client_id,
	client_secret,
	redirect_uri,
	code_verifier,
	code,
}: {
	client_id: string
	client_secret: string
	redirect_uri: string
	code_verifier: string
	code: string
}): Promise<AuthorizationToken> {
	if (!code) {
		throw new McpError('Missing code', 400)
	}

	const params = new URLSearchParams({
		grant_type: 'authorization_code',
		client_id,
		redirect_uri,
		code,
		code_verifier,
	}).toString()
	const resp = await fetch('https://dash.cloudflare.com/oauth2/token', {
		method: 'POST',
		headers: {
			Authorization: `Basic ${btoa(`${client_id}:${client_secret}`)}`,
			'Content-Type': 'application/x-www-form-urlencoded',
		},
		body: params,
	})

	if (!resp.ok) {
		console.log(await resp.text())
		throw new McpError('Failed to get OAuth token', 500, { reportToSentry: true })
	}

	return AuthorizationToken.parse(await resp.json())
}

export async function refreshAuthToken({
	client_id,
	client_secret,
	refresh_token,
}: {
	client_id: string
	client_secret: string
	refresh_token: string
}): Promise<AuthorizationToken> {
	const params = new URLSearchParams({
		grant_type: 'refresh_token',
		client_id,
		refresh_token,
	})

	const resp = await fetch('https://dash.cloudflare.com/oauth2/token', {
		method: 'POST',
		body: params.toString(),
		headers: {
			Authorization: `Basic ${btoa(`${client_id}:${client_secret}`)}`,
			'Content-Type': 'application/x-www-form-urlencoded',
		},
	})
	if (!resp.ok) {
		console.log(await resp.text())
		throw new McpError('Failed to get OAuth token', 500, { reportToSentry: true })
	}

	return AuthorizationToken.parse(await resp.json())
}

```

--------------------------------------------------------------------------------
/apps/workers-bindings/src/bindings.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { registerPrompts } from '@repo/mcp-common/src/prompts/docs-vectorize.prompts'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { registerD1Tools } from '@repo/mcp-common/src/tools/d1.tools'
import { registerDocsTools } from '@repo/mcp-common/src/tools/docs-vectorize.tools'
import { registerHyperdriveTools } from '@repo/mcp-common/src/tools/hyperdrive.tools'
import { registerKVTools } from '@repo/mcp-common/src/tools/kv_namespace.tools'
import { registerR2BucketTools } from '@repo/mcp-common/src/tools/r2_bucket.tools'
import { registerWorkersTools } from '@repo/mcp-common/src/tools/worker.tools'
import { MetricsTracker } from '@repo/mcp-observability'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './bindings.context'

export { UserDetails }

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

export type WorkersBindingsMCPState = { activeAccountId: string | null }

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps

export class WorkersBindingsMCP extends McpAgent<Env, WorkersBindingsMCPState, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}

	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	initialState: WorkersBindingsMCPState = {
		activeAccountId: null,
	}

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env)
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
		})

		registerAccountTools(this)
		registerKVTools(this)
		registerWorkersTools(this)
		registerR2BucketTools(this)
		registerD1Tools(this)
		registerHyperdriveTools(this)

		// Add docs tools
		registerDocsTools(this, this.env)
		registerPrompts(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const BindingsScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'workers:write':
		'See and change Cloudflare Workers data such as zones, KV storage, namespaces, scripts, and routes.',
	'd1:write': 'Create, read, and write to D1 databases',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			console.log('is token mode')
			return await handleApiTokenMode(WorkersBindingsMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': WorkersBindingsMCP.serve('/mcp'),
				'/sse': WorkersBindingsMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: BindingsScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/tools/worker.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

import {
	handleGetWorkersService,
	handleWorkerScriptDownload,
	handleWorkersList,
} from '../api/workers.api'
import { getCloudflareClient } from '../cloudflare-api'
import { fmt } from '../format'
import { getProps } from '../get-props'

import type { CloudflareMcpAgent } from '../types/cloudflare-mcp-agent.types'

/**
 * Registers the workers tools with the MCP server
 * @param server The MCP server instance
 * @param accountId Cloudflare account ID
 * @param apiToken Cloudflare API token
 */
// Define the scriptName parameter schema
const workerNameParam = z.string().describe('The name of the worker script to retrieve')

export function registerWorkersTools(agent: CloudflareMcpAgent) {
	// Tool to list all workers
	agent.server.tool(
		'workers_list',
		fmt.trim(`
			List all Workers in your Cloudflare account.

			If you only need details of a single Worker, use workers_get_worker.
		`),
		{},
		{
			title: 'List Workers',
			annotations: {
				readOnlyHint: true,
				destructiveHint: false,
			},
		},
		async () => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const results = await handleWorkersList({
					client: getCloudflareClient(props.accessToken),
					accountId,
				})
				// Extract worker details and sort by created_on date (newest first)
				const workers = results
					.map((worker) => ({
						name: worker.id,
						// The API client doesn't know tag exists. The tag is needed in other places such as Workers Builds
						id: z.object({ tag: z.string() }).parse(worker),
						modified_on: worker.modified_on || null,
						created_on: worker.created_on || null,
					}))
					// order by created_on desc ( newest first )
					.sort((a, b) => {
						if (!a.created_on) return 1
						if (!b.created_on) return -1
						return new Date(b.created_on).getTime() - new Date(a.created_on).getTime()
					})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								workers,
								count: workers.length,
							}),
						},
					],
				}
			} catch (e) {
				agent.server.recordError(e)
				return {
					content: [
						{
							type: 'text',
							text: `Error listing workers: ${e instanceof Error && e.message}`,
						},
					],
				}
			}
		}
	)

	// Tool to get a specific worker's script details
	agent.server.tool(
		'workers_get_worker',
		'Get the details of the Cloudflare Worker.',
		{
			scriptName: workerNameParam,
		},
		{
			title: 'Get Worker details',
			annotations: {
				readOnlyHint: true,
				destructiveHint: false,
			},
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const { scriptName } = params
				const res = await handleGetWorkersService({
					apiToken: props.accessToken,
					scriptName,
					accountId,
				})

				if (!res.result) {
					return {
						content: [
							{
								type: 'text',
								text: 'Worker not found',
							},
						],
					}
				}

				return {
					content: [
						{
							type: 'text',
							text: await fmt.asTSV([
								{
									name: res.result.id,
									id: res.result.default_environment.script_tag,
								},
							]),
						},
					],
				}
			} catch (e) {
				agent.server.recordError(e)
				return {
					content: [
						{
							type: 'text',
							text: `Error retrieving worker script: ${e instanceof Error && e.message}`,
						},
					],
				}
			}
		}
	)

	// Tool to get a specific worker's script content
	agent.server.tool(
		'workers_get_worker_code',
		'Get the source code of a Cloudflare Worker. Note: This may be a bundled version of the worker.',
		{ scriptName: workerNameParam },
		{
			title: 'Get Worker code',
			annotations: {
				readOnlyHint: true,
				destructiveHint: false,
			},
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const { scriptName } = params
				const scriptContent = await handleWorkerScriptDownload({
					client: getCloudflareClient(props.accessToken),
					scriptName,
					accountId,
				})
				return {
					content: [
						{
							type: 'text',
							text: scriptContent,
						},
					],
				}
			} catch (e) {
				agent.server.recordError(e)
				return {
					content: [
						{
							type: 'text',
							text: `Error retrieving worker script: ${e instanceof Error && e.message}`,
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/apps/workers-observability/src/workers-observability.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { getProps } from '@repo/mcp-common/src/get-props'
import { registerPrompts } from '@repo/mcp-common/src/prompts/docs-vectorize.prompts'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { initSentryWithUser } from '@repo/mcp-common/src/sentry'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { registerDocsTools } from '@repo/mcp-common/src/tools/docs-vectorize.tools'
import { registerWorkersTools } from '@repo/mcp-common/src/tools/worker.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerObservabilityTools } from './tools/workers-observability.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './workers-observability.context'

export { UserDetails }

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps

type State = { activeAccountId: string | null }

export class ObservabilityMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined
		const sentry =
			props.type === 'user_token' ? initSentryWithUser(env, this.ctx, props.user.id) : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
			sentry,
			options: {
				instructions: `# Cloudflare Workers Observability Tool
				* A cloudflare worker is a serverless function
				* Workers Observability is the tool to inspect the logs for your cloudflare Worker
				* Each log is a structured JSON payload with keys and values


				This server allows you to analyze your Cloudflare Workers logs and metrics.
				`,
			},
		})

		registerAccountTools(this)

		// Register Cloudflare Workers tools
		registerWorkersTools(this)

		// Register Cloudflare Workers logs tools
		registerObservabilityTools(this)

		// Add docs tools
		registerDocsTools(this, this.env)
		registerPrompts(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const ObservabilityScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'workers:read':
		'See and change Cloudflare Workers data such as zones, KV storage, namespaces, scripts, and routes.',
	'workers_observability:read': 'See observability logs for your account',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(ObservabilityMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': ObservabilityMCP.serve('/mcp'),
				'/sse': ObservabilityMCP.serveSSE('/sse'),
			},
			// @ts-ignore
			defaultHandler: createAuthHandlers({ scopes: ObservabilityScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```

--------------------------------------------------------------------------------
/apps/sandbox-container/server/containerMcp.ts:
--------------------------------------------------------------------------------

```typescript
import { McpAgent } from 'agents/mcp'

import { getProps } from '@repo/mcp-common/src/get-props'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'

import { ExecParams, FilePathParam, FileWrite } from '../shared/schema'
import { BASE_INSTRUCTIONS } from './prompts'
import { stripProtocolFromFilePath } from './utils'

import type { Props, UserContainer } from './sandbox.server.app'
import type { Env } from './sandbox.server.context'

export class ContainerMcpAgent extends McpAgent<Env, never, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}

	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}

		return this._server
	}

	get userContainer(): DurableObjectStub<UserContainer> {
		const props = getProps(this)
		// TODO: Support account scoped tokens?
		if (props.type === 'account_token') {
			throw new Error('Container server does not currently support account scoped tokens')
		}
		const userContainer = this.env.USER_CONTAINER.idFromName(props.user.id)
		return this.env.USER_CONTAINER.get(userContainer)
	}

	constructor(
		public ctx: DurableObjectState,
		public env: Env
	) {
		console.log('creating container DO')
		super(ctx, env)
	}

	async init() {
		const props = getProps(this)
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const userId = props.type === 'user_token' ? props.user.id : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
			options: { instructions: BASE_INSTRUCTIONS },
		})

		this.server.tool(
			'container_initialize',
			`Start or restart the container.
			Use this tool to initialize a container before running any python or node.js code that the user requests ro run.`,
			async () => {
				const props = getProps(this)
				if (props.type === 'account_token') {
					return {
						// TODO: Support account scoped tokens?
						// we'll need to add support for an account blocklist in that case
						content: [
							{
								type: 'text',
								text: 'Container server does not currently support account scoped tokens.',
							},
						],
					}
				}

				const userInBlocklist = await this.env.USER_BLOCKLIST.get(props.user.id)
				if (userInBlocklist) {
					return {
						content: [{ type: 'text', text: 'Blocked from intializing container.' }],
					}
				}
				return {
					content: [{ type: 'text', text: await this.userContainer.container_initialize() }],
				}
			}
		)

		this.server.tool(
			'container_ping',
			`Ping the container for liveliness. Use this tool to check if the container is running.`,
			async () => {
				return {
					content: [{ type: 'text', text: await this.userContainer.container_ping() }],
				}
			}
		)
		this.server.tool(
			'container_exec',
			`Run a command in a container and return the results from stdout.
			If necessary, set a timeout. To debug, stream back standard error.
			If you're using python, ALWAYS use python3 alongside pip3`,
			{ args: ExecParams },
			async ({ args }) => {
				return {
					content: [{ type: 'text', text: await this.userContainer.container_exec(args) }],
				}
			}
		)
		this.server.tool(
			'container_file_delete',
			'Delete file in the working directory',
			{ args: FilePathParam },
			async ({ args }) => {
				const path = await stripProtocolFromFilePath(args.path)
				const deleted = await this.userContainer.container_file_delete(path)
				return {
					content: [{ type: 'text', text: `File deleted: ${deleted}.` }],
				}
			}
		)
		this.server.tool(
			'container_file_write',
			'Create a new file with the provided contents in the working direcotry, overwriting the file if it already exists',
			{ args: FileWrite },
			async ({ args }) => {
				args.path = await stripProtocolFromFilePath(args.path)
				return {
					content: [{ type: 'text', text: await this.userContainer.container_file_write(args) }],
				}
			}
		)
		this.server.tool(
			'container_files_list',
			'List working directory file tree. This just reads the contents of the current working directory',
			async () => {
				// Begin workaround using container read rather than ls:
				const readFile = await this.userContainer.container_file_read('.')
				return {
					content: [
						{
							type: 'resource',
							resource: {
								text: readFile.type === 'text' ? readFile.textOutput : readFile.base64Output,
								uri: `file://`,
								mimeType: readFile.mimeType,
							},
						},
					],
				}
			}
		)
		this.server.tool(
			'container_file_read',
			'Read a specific file or directory. Use this tool if you would like to read files or display them to the user. This allow you to get a displayable image for the user if there is an image file.',
			{ args: FilePathParam },
			async ({ args }) => {
				const path = await stripProtocolFromFilePath(args.path)
				const readFile = await this.userContainer.container_file_read(path)

				return {
					content: [
						{
							type: 'resource',
							resource: {
								text: readFile.type === 'text' ? readFile.textOutput : readFile.base64Output,
								uri: `file://${path}`,
								mimeType: readFile.mimeType,
							},
						},
					],
				}
			}
		)
	}
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/api/cf1-integration.api.ts:
--------------------------------------------------------------------------------

```typescript
import { fetchCloudflareApi } from '../cloudflare-api'
import {
	AssetCategoriesResponse,
	AssetDetail,
	AssetsResponse,
	IntegrationResponse,
	IntegrationsResponse,
} from '../types/cf1-integrations.types'
import { V4Schema } from '../v4-api'

import type { z } from 'zod'
import type {
	zReturnedAssetCategoriesResult,
	zReturnedAssetsResult,
	zReturnedIntegrationResult,
	zReturnedIntegrationsResult,
} from '../types/cf1-integrations.types'

interface BaseParams {
	accountId: string
	apiToken: string
}

interface PaginationParams {
	page?: number
	pageSize?: number
}

type IntegrationParams = BaseParams & { integrationIdParam: string }
type AssetCategoryParams = BaseParams & { type?: string; vendor?: string }
type AssetSearchParams = BaseParams & { searchTerm: string } & PaginationParams
type AssetByIdParams = BaseParams & { assetId: string }
type AssetByCategoryParams = BaseParams & { categoryId: string } & PaginationParams
type AssetByIntegrationParams = BaseParams & { integrationId: string } & PaginationParams

const buildParams = (baseParams: Record<string, string>, pagination?: PaginationParams) => {
	const params = new URLSearchParams(baseParams)
	if (pagination?.page) params.append('page', String(pagination.page))
	if (pagination?.pageSize) params.append('page_size', String(pagination.pageSize))
	return params
}

const buildIntegrationEndpoint = (integrationId: string) => `/casb/integrations/${integrationId}`
const buildAssetEndpoint = (assetId?: string) =>
	assetId ? `/casb/assets/${assetId}` : '/casb/assets'
const buildAssetCategoryEndpoint = () => '/casb/asset_categories'

const makeApiCall = async <T>({
	endpoint,
	accountId,
	apiToken,
	responseSchema,
	params,
}: {
	endpoint: string
	accountId: string
	apiToken: string
	responseSchema: z.ZodType<any>
	params?: URLSearchParams
}): Promise<T> => {
	try {
		const fullEndpoint = params ? `${endpoint}?${params.toString()}` : endpoint
		const data = await fetchCloudflareApi({
			endpoint: fullEndpoint,
			accountId,
			apiToken,
			responseSchema,
			options: {
				method: 'GET',
				headers: { 'Content-Type': 'application/json' },
			},
		})
		return data.result as T
	} catch (error) {
		console.error(`API call failed for ${endpoint}:`, error)
		throw error
	}
}

// Resource-specific API call handlers
const makeIntegrationCall = <T>(params: IntegrationParams, responseSchema: z.ZodType<any>) =>
	makeApiCall<T>({
		endpoint: buildIntegrationEndpoint(params.integrationIdParam),
		accountId: params.accountId,
		apiToken: params.apiToken,
		responseSchema,
	})

const makeAssetCall = <T>(
	params: BaseParams & PaginationParams,
	responseSchema: z.ZodType<any>,
	assetId?: string,
	additionalParams?: Record<string, string>
) =>
	makeApiCall<T>({
		endpoint: buildAssetEndpoint(assetId),
		accountId: params.accountId,
		apiToken: params.apiToken,
		responseSchema,
		params: buildParams(additionalParams || {}, params),
	})

const makeAssetCategoryCall = <T>(params: AssetCategoryParams, responseSchema: z.ZodType<any>) =>
	makeApiCall<T>({
		endpoint: buildAssetCategoryEndpoint(),
		accountId: params.accountId,
		apiToken: params.apiToken,
		responseSchema,
		params: buildParams({
			...(params.vendor && { vendor: params.vendor }),
			...(params.type && { type: params.type }),
		}),
	})

// Integration handlers
export async function handleIntegrationById(
	params: IntegrationParams
): Promise<{ integration: zReturnedIntegrationResult | null }> {
	const integration = await makeIntegrationCall<zReturnedIntegrationResult>(
		params,
		V4Schema(IntegrationResponse)
	)
	return { integration }
}

export async function handleIntegrations(
	params: BaseParams
): Promise<{ integrations: zReturnedIntegrationsResult | null }> {
	const integrations = await makeApiCall<zReturnedIntegrationsResult>({
		endpoint: '/casb/integrations',
		accountId: params.accountId,
		apiToken: params.apiToken,
		responseSchema: V4Schema(IntegrationsResponse),
	})
	return { integrations }
}

// Asset category handlers
export async function handleAssetCategories(
	params: AssetCategoryParams
): Promise<{ categories: zReturnedAssetCategoriesResult | null }> {
	const categories = await makeAssetCategoryCall<zReturnedAssetCategoriesResult>(
		params,
		V4Schema(AssetCategoriesResponse)
	)
	return { categories }
}

// Asset handlers
export async function handleAssets(params: BaseParams & PaginationParams) {
	const assets = await makeAssetCall<zReturnedAssetsResult>(params, V4Schema(AssetsResponse))
	return { assets }
}

export async function handleAssetsByIntegrationId(params: AssetByIntegrationParams) {
	const assets = await makeAssetCall<zReturnedAssetsResult>(
		params,
		V4Schema(AssetsResponse),
		undefined,
		{ integration_id: params.integrationId }
	)
	return { assets }
}

export async function handleAssetById(params: AssetByIdParams) {
	const asset = await makeAssetCall<zReturnedAssetsResult>(
		params,
		V4Schema(AssetDetail),
		params.assetId
	)
	return { asset }
}

export async function handleAssetsByAssetCategoryId(params: AssetByCategoryParams) {
	const assets = await makeAssetCall<zReturnedAssetsResult>(
		params,
		V4Schema(AssetsResponse),
		undefined,
		{ category_id: params.categoryId }
	)
	return { assets }
}

export async function handleAssetsSearch(params: AssetSearchParams) {
	const assets = await makeAssetCall<zReturnedAssetsResult>(
		params,
		V4Schema(AssetsResponse),
		undefined,
		{ search: params.searchTerm }
	)
	return { assets }
}

```

--------------------------------------------------------------------------------
/apps/ai-gateway/src/tools/ai-gateway.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { getCloudflareClient } from '@repo/mcp-common/src/cloudflare-api'
import { getProps } from '@repo/mcp-common/src/get-props'

import { GatewayIdParam, ListLogsParams, LogIdParam, pageParam, perPageParam } from '../types'

import type { LogListParams } from 'cloudflare/resources/ai-gateway'
import type { AIGatewayMCP } from '../ai-gateway.app'

export function registerAIGatewayTools(agent: AIGatewayMCP) {
	agent.server.tool(
		'list_gateways',
		'List Gateways',
		{
			page: pageParam,
			per_page: perPageParam,
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}
			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = await client.aiGateway.list({
					account_id: accountId,
					page: params.page,
					per_page: params.per_page,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: r.result,
								result_info: r.result_info,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error listing gateways: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool('list_logs', 'List Logs', ListLogsParams, async (params) => {
		try {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			const { gateway_id, ...filters } = params

			const props = getProps(agent)
			const client = getCloudflareClient(props.accessToken)
			const r = await client.aiGateway.logs.list(gateway_id, {
				...filters,
				account_id: accountId,
			} as LogListParams)

			return {
				content: [
					{
						type: 'text',
						text: JSON.stringify({
							result: r.result,
							result_info: r.result_info,
						}),
					},
				],
			}
		} catch (error) {
			return {
				content: [
					{
						type: 'text',
						text: `Error listing logs: ${error instanceof Error && error.message}`,
					},
				],
			}
		}
	})

	agent.server.tool(
		'get_log_details',
		'Get a single Log details',
		{
			gateway_id: GatewayIdParam,
			log_id: LogIdParam,
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = await client.aiGateway.logs.get(params.gateway_id, params.log_id, {
					account_id: accountId,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: r,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting log: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'get_log_request_body',
		'Get Log Request Body',
		{
			gateway_id: GatewayIdParam,
			log_id: LogIdParam,
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = await client.aiGateway.logs.request(params.gateway_id, params.log_id, {
					account_id: accountId,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: r,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting log request body: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'get_log_response_body',
		'Get Log Response Body',
		{
			gateway_id: GatewayIdParam,
			log_id: LogIdParam,
		},
		async (params) => {
			const accountId = await agent.getActiveAccountId()
			if (!accountId) {
				return {
					content: [
						{
							type: 'text',
							text: 'No currently active accountId. Try listing your accounts (accounts_list) and then setting an active account (set_active_account)',
						},
					],
				}
			}

			try {
				const props = getProps(agent)
				const client = getCloudflareClient(props.accessToken)
				const r = await client.aiGateway.logs.response(params.gateway_id, params.log_id, {
					account_id: accountId,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: r,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting log response body: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
}

```

--------------------------------------------------------------------------------
/packages/mcp-common/src/tools/d1.tools.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod'

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 {
	D1DatabaseNameParam,
	D1DatabasePrimaryLocationHintParam,
	D1DatabaseQueryParamsParam,
	D1DatabaseQuerySqlParam,
} from '../types/d1.types'
import { PaginationPageParam, PaginationPerPageParam } from '../types/shared.types'

export function registerD1Tools(agent: CloudflareMcpAgent) {
	agent.server.tool(
		'd1_databases_list',
		'List all of the D1 databases in your Cloudflare account',
		{
			name: D1DatabaseNameParam.nullable().optional(),
			page: PaginationPageParam,
			per_page: PaginationPerPageParam,
		},
		{
			title: 'List D1 databases',
			annotations: {
				readOnlyHint: true,
			},
		},
		async ({ name, page, per_page }) => {
			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.d1.database.list({
					account_id,
					name: name ?? undefined,
					page: page ?? undefined,
					per_page: per_page ?? undefined,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify({
								result: listResponse.result,
								result_info: listResponse.result_info,
							}),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error listing D1 databases: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'd1_database_create',
		'Create a new D1 database in your Cloudflare account',
		{
			name: D1DatabaseNameParam,
			primary_location_hint: D1DatabasePrimaryLocationHintParam.nullable().optional(),
		},
		{
			title: 'Create D1 database',
			annotations: {
				readOnlyHint: false,
				destructiveHint: false,
			},
		},
		async ({ name, primary_location_hint }) => {
			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 d1Database = await client.d1.database.create({
					account_id,
					name,
					primary_location_hint: primary_location_hint ?? undefined,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify(d1Database),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error creating D1 database: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'd1_database_delete',
		'Delete a d1 database in your Cloudflare account',
		{ database_id: z.string() },
		{
			title: 'Delete D1 database',
			annotations: {
				readOnlyHint: false,
				destructiveHint: true,
			},
		},
		async ({ database_id }) => {
			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 deleteResponse = await client.d1.database.delete(database_id, {
					account_id,
				})
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify(deleteResponse),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error deleting D1 database: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'd1_database_get',
		'Get a D1 database in your Cloudflare account',
		{ database_id: z.string() },
		{
			title: 'Get D1 database',
			annotations: {
				readOnlyHint: true,
			},
		},
		async ({ database_id }) => {
			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 d1Database = await client.d1.database.get(database_id, {
					account_id,
				})

				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify(d1Database),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error getting D1 database: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)

	agent.server.tool(
		'd1_database_query',
		'Query a D1 database in your Cloudflare account',
		{
			database_id: z.string(),
			sql: D1DatabaseQuerySqlParam,
			params: D1DatabaseQueryParamsParam.nullable(),
		},
		{
			title: 'Query D1 database',
			annotations: {
				readOnlyHint: false,
				destructiveHint: false,
			},
		},
		async ({ database_id, sql, params }) => {
			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 queryResult = await client.d1.database.query(database_id, {
					account_id,
					sql,
					params: params ?? undefined,
				})
				return {
					content: [
						{
							type: 'text',
							text: JSON.stringify(queryResult.result),
						},
					],
				}
			} catch (error) {
				return {
					content: [
						{
							type: 'text',
							text: `Error querying D1 database: ${error instanceof Error && error.message}`,
						},
					],
				}
			}
		}
	)
}

```

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

```typescript
import { z } from 'zod'

import { withAccountCheck } from '@repo/mcp-common/src/api/account.api'
import {
	handleAssetById,
	handleAssetCategories,
	handleAssets,
	handleAssetsByAssetCategoryId,
	handleAssetsByIntegrationId,
	handleAssetsSearch,
	handleIntegrationById,
	handleIntegrations,
} from '@repo/mcp-common/src/api/cf1-integration.api'
import {
	assetCategoryTypeParam,
	assetCategoryVendorParam,
} from '@repo/mcp-common/src/types/cf1-integrations.types'

import type { ToolDefinition } from '@repo/mcp-common/src/types/tools.types'
import type { CASBMCP } from '../cf1-casb.app'

const PAGE_SIZE = 3

const integrationIdParam = z.string().describe('The UUID of the integration to analyze')
const assetSearchTerm = z.string().describe('The search keyword for assets')
const assetIdParam = z.string().describe('The UUID of the asset to analyze')
const assetCategoryIdParam = z.string().describe('The UUID of the asset category to analyze')

const toolDefinitions: Array<ToolDefinition<any>> = [
	{
		name: 'integration_by_id',
		description: 'Analyze Cloudflare One Integration by ID',
		params: { integrationIdParam },
		handler: async ({
			integrationIdParam,
			accountId,
			apiToken,
		}: {
			integrationIdParam: string
			accountId: string
			apiToken: string
		}) => {
			const { integration } = await handleIntegrationById({
				integrationIdParam,
				accountId,
				apiToken,
			})
			return { integration }
		},
	},
	{
		name: 'integrations_list',
		description: 'List all Cloudflare One Integrations in a given account',
		params: {},
		handler: async ({ accountId, apiToken }: { accountId: string; apiToken: string }) => {
			const { integrations } = await handleIntegrations({ accountId, apiToken })
			return { integrations }
		},
	},
	{
		name: 'assets_search',
		description: 'Search Assets by keyword',
		params: { assetSearchTerm },
		handler: async ({
			assetSearchTerm,
			accountId,
			apiToken,
		}: {
			assetSearchTerm: string
			accountId: string
			apiToken: string
		}) => {
			const { assets } = await handleAssetsSearch({
				accountId,
				apiToken,
				searchTerm: assetSearchTerm,
				pageSize: PAGE_SIZE,
			})
			return { assets }
		},
	},
	{
		name: 'asset_by_id',
		description: 'Search Assets by ID',
		params: { assetIdParam },
		handler: async ({
			assetIdParam,
			accountId,
			apiToken,
		}: {
			assetIdParam: string
			accountId: string
			apiToken: string
		}) => {
			const { asset } = await handleAssetById({
				accountId,
				apiToken,
				assetId: assetIdParam,
			})
			return { asset }
		},
	},
	{
		name: 'assets_by_integration_id',
		description: 'Search Assets by Integration ID',
		params: { integrationIdParam },
		handler: async ({
			integrationIdParam,
			accountId,
			apiToken,
		}: {
			integrationIdParam: string
			accountId: string
			apiToken: string
		}) => {
			const { assets } = await handleAssetsByIntegrationId({
				accountId,
				apiToken,
				integrationId: integrationIdParam,
				pageSize: PAGE_SIZE,
			})
			return { assets }
		},
	},
	{
		name: 'assets_by_category_id',
		description: 'Search Assets by Asset Category ID',
		params: { assetCategoryIdParam },
		handler: async ({
			assetCategoryIdParam,
			accountId,
			apiToken,
		}: {
			assetCategoryIdParam: string
			accountId: string
			apiToken: string
		}) => {
			const { assets } = await handleAssetsByAssetCategoryId({
				accountId,
				apiToken,
				categoryId: assetCategoryIdParam,
				pageSize: PAGE_SIZE,
			})
			return { assets }
		},
	},
	{
		name: 'assets_list',
		description: 'Paginated list of Assets',
		params: {},
		handler: async ({ accountId, apiToken }: { accountId: string; apiToken: string }) => {
			const { assets } = await handleAssets({
				accountId,
				apiToken,
				pageSize: PAGE_SIZE,
			})
			return { assets }
		},
	},
	{
		name: 'asset_categories_list',
		description: 'List Asset Categories',
		params: {},
		handler: async ({ accountId, apiToken }: { accountId: string; apiToken: string }) => {
			const { categories } = await handleAssetCategories({
				accountId,
				apiToken,
			})
			return { categories }
		},
	},
	{
		name: 'asset_categories_by_vendor',
		description: 'List asset categories by vendor',
		params: { assetCategoryVendorParam },
		handler: async ({
			assetCategoryVendorParam,
			accountId,
			apiToken,
		}: {
			assetCategoryVendorParam: string
			accountId: string
			apiToken: string
		}) => {
			const { categories } = await handleAssetCategories({
				accountId,
				apiToken,
				vendor: assetCategoryVendorParam,
			})
			return { categories }
		},
	},
	{
		name: 'asset_categories_by_type',
		description: 'Search Asset Categories by type',
		params: { assetCategoryTypeParam },
		handler: async ({
			assetCategoryTypeParam,
			accountId,
			apiToken,
		}: {
			assetCategoryTypeParam?: string
			accountId: string
			apiToken: string
		}) => {
			const { categories } = await handleAssetCategories({
				accountId,
				apiToken,
				type: assetCategoryTypeParam,
			})
			return { categories }
		},
	},
	{
		name: 'asset_categories_by_vendor_and_type',
		description: 'Search Asset Categories by vendor and type',
		params: { assetCategoryTypeParam, assetCategoryVendorParam },
		handler: async ({
			assetCategoryTypeParam,
			assetCategoryVendorParam,
			accountId,
			apiToken,
		}: {
			assetCategoryTypeParam?: string
			assetCategoryVendorParam: string
			accountId: string
			apiToken: string
		}) => {
			const { categories } = await handleAssetCategories({
				accountId,
				apiToken,
				type: assetCategoryTypeParam,
				vendor: assetCategoryVendorParam,
			})
			return { categories }
		},
	},
]

/**
 * Registers the logs analysis tool with the MCP server
 * @param agent The MCP server instance
 */
export function registerIntegrationsTools(agent: CASBMCP) {
	toolDefinitions.forEach(({ name, description, params, handler }) => {
		agent.server.tool(name, description, params, withAccountCheck(agent, handler))
	})
}

```

--------------------------------------------------------------------------------
/implementation-guides/type-validators.md:
--------------------------------------------------------------------------------

```markdown
# MCP Tool Type Validator Implementation Guide

This guide outlines the best practices for creating Zod validators for the parameters of MCP (Model Context Protocol) tools, particularly those interacting with Cloudflare resources via the Cloudflare Typescript SDK.

## Purpose

Zod validators serve several critical functions:

1.  **Runtime Validation:** They ensure that the arguments provided to tools (often by an LLM) match the expected format, constraints, and types before the tool logic executes or interacts with external APIs (like the Cloudflare SDK).
2.  **Type Safety:** They provide strong typing for tool parameters within the TypeScript codebase.
3.  **Schema Definition:** They act as a clear, machine-readable definition of a tool's expected inputs, aiding both developers and LLMs in understanding how to use the tool correctly.
4.  **SDK Alignment:** They help maintain alignment with underlying SDKs, catching potential breaking changes.

## Core Principles

### 1. Link to SDK Types with `z.ZodType`

When a tool parameter corresponds directly to a parameter in the Cloudflare Node SDK (`cloudflare/resources/...`), **always** link your Zod schema to the SDK type using `z.ZodType<SDKType>`. This creates a compile-time dependency.

**Why?**

- **Detect SDK Changes:** If the underlying SDK type changes (e.g., type alias renamed, property added/removed/renamed, type changed from `string` to `string | null`), your Zod schema definition will likely cause a TypeScript error during compilation. This immediately flags the need to update the validator and potentially the tool logic, preventing runtime errors caused by SDK misalignment.
- **Accuracy:** Ensures your validator accurately reflects the type expected by the SDK function you intend to call.

**Example (`hyperdrive.types.ts`):**

```typescript
import { z } from 'zod'

import type { ConfigCreateParams } from 'cloudflare/resources/hyperdrive/configs.mjs'

/** Zod schema for a Hyperdrive config name. */
export const HyperdriveConfigNameSchema: z.ZodType<ConfigCreateParams['name']> = z
	.string()
	.min(1)
	.max(64)
	.regex(/^[a-zA-Z0-9_-]+$/)
	.describe('The name of the Hyperdrive configuration (alphanumeric, underscore, hyphen)')

/** Zod schema for the origin database host (IPv4). */
export const HyperdriveOriginHostSchema: z.ZodType<ConfigCreateParams.PublicDatabase['host']> = z
	.string()
	.ip({ version: 'v4' })
	.describe('The database host IPv4 address')
```

### 2. Define Individual Validators Per Field (Avoid Object Schemas for Tool Parameters)

Define a separate, named Zod schema for **each individual field** that a tool might accept as a parameter. Do **not** group multiple parameters into a single Zod object schema (`z.object({...})`) that the tool accepts as a single `params` argument.

**Why?**

- **LLM Clarity:** LLMs generally understand and handle distinct, named parameters better than complex nested objects. Providing individual schemas makes the tool's signature clearer for the LLM to interpret and use correctly.
- **Reusability:** Individual field schemas (like `HyperdriveConfigIdSchema`, `HyperdriveConfigNameSchema`) can be reused across different tools (e.g., `hyperdrive_create`, `hyperdrive_update`, `hyperdrive_get`).
- **Modularity:** Easier to manage, update, and test individual validation rules.

**Example (`hyperdrive.types.ts` Structure):**

```typescript
// --- Base Field Schemas ---
export const HyperdriveConfigIdSchema = z.string().describe(...);
export const HyperdriveConfigNameSchema: z.ZodType<...> = z.string()...describe(...);
export const HyperdriveOriginHostSchema: z.ZodType<...> = z.string()...describe(...);
export const HyperdriveOriginPortSchema: z.ZodType<...> = z.number()...describe(...);
// ... other individual fields
```

**Conceptual Tool Definition (Illustrative):**

Instead of:

```typescript
// DON'T DO THIS for tool params
const CreateParamsSchema = z.object({
	name: HyperdriveConfigNameSchema,
	host: HyperdriveOriginHostSchema,
	port: HyperdriveOriginPortSchema,
	// ... other fields
})

// Tool definition would accept one arg: { params: CreateParamsSchema }
```

Do:

```typescript
// DO THIS: Tool definition accepts multiple named args
// tool('hyperdrive_create', {
//     name: HyperdriveConfigNameSchema,
//     host: HyperdriveOriginHostSchema,
//     port: HyperdriveOriginPortSchema,
//     // ... other named parameters with their individual schemas
// }, ...)
```

### 3. Use `.describe()` Extensively

Add a clear, concise `.describe('...')` call to **every** Zod schema you define.

**Why?**

- **LLM Context:** The description is often extracted and provided to the LLM as part of the tool's definition, helping it understand the purpose and constraints of each parameter.
- **Developer Documentation:** Serves as inline documentation for developers working with the code.

**Example (`hyperdrive.types.ts`):**

```typescript
/** Zod schema for the list page number. */
export const HyperdriveListParamPageSchema = z
	.number()
	.int()
	.positive()
	.optional()
	.describe('Page number of results') // <-- Good description!
```

## Naming Conventions

Use a consistent naming convention for your validator schemas. A recommended pattern is:

`ServiceNameFieldNameSchema`

- `ServiceName`: The Cloudflare service (e.g., `Hyperdrive`, `KV`, `D1`, `R2`).
- `FieldName`: The specific field being validated (e.g., `ConfigId`, `ConfigName`, `OriginHost`, `ListParamPage`).
- `Schema`: Suffix indicating it's a Zod schema.

**Examples:**

- `HyperdriveConfigIdSchema`
- `KVKeySchema`
- `D1DatabaseIdSchema`
- `R2BucketNameSchema`

## Location

Place validators related to a specific service or concept in dedicated files within the `packages/mcp-common/src/types/` directory (e.g., `hyperdrive.types.ts`, `kv.ts`).

## Summary

By following these principles – linking to SDK types, using granular named validators, providing clear descriptions, and maintaining consistent naming – you create robust, maintainable, and LLM-friendly type validation for MCP tools.

```

--------------------------------------------------------------------------------
/apps/workers-builds/src/workers-builds.app.ts:
--------------------------------------------------------------------------------

```typescript
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpAgent } from 'agents/mcp'

import { handleApiTokenMode, isApiTokenRequest } from '@repo/mcp-common/src/api-token-mode'
import {
	createAuthHandlers,
	handleTokenExchangeCallback,
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details.do'
import { getEnv } from '@repo/mcp-common/src/env'
import { fmt } from '@repo/mcp-common/src/format'
import { getProps } from '@repo/mcp-common/src/get-props'
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
import { initSentryWithUser } from '@repo/mcp-common/src/sentry'
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
import { registerAccountTools } from '@repo/mcp-common/src/tools/account.tools'
import { registerWorkersTools } from '@repo/mcp-common/src/tools/worker.tools'

import { MetricsTracker } from '../../../packages/mcp-observability/src'
import { registerBuildsTools } from './tools/workers-builds.tools'

import type { AuthProps } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from './workers-builds.context'

export { UserDetails }

const env = getEnv<Env>()

const metrics = new MetricsTracker(env.MCP_METRICS, {
	name: env.MCP_SERVER_NAME,
	version: env.MCP_SERVER_VERSION,
})

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
type Props = AuthProps

type State = {
	activeAccountId: string | null
	activeBuildUUID: string | null
	activeWorkerId: string | null
}

export class BuildsMCP extends McpAgent<Env, State, Props> {
	_server: CloudflareMCPServer | undefined
	set server(server: CloudflareMCPServer) {
		this._server = server
	}
	get server(): CloudflareMCPServer {
		if (!this._server) {
			throw new Error('Tried to access server before it was initialized')
		}
		return this._server
	}

	async init() {
		// TODO: Probably we'll want to track account tokens usage through an account identifier at some point
		const props = getProps(this)
		const userId = props.type === 'user_token' ? props.user.id : undefined
		const sentry =
			props.type === 'user_token' ? initSentryWithUser(env, this.ctx, props.user.id) : undefined

		this.server = new CloudflareMCPServer({
			userId,
			wae: this.env.MCP_METRICS,
			serverInfo: {
				name: this.env.MCP_SERVER_NAME,
				version: this.env.MCP_SERVER_VERSION,
			},
			sentry,
			options: {
				instructions: fmt.trim(`
					# Cloudflare Workers Builds Tool
					* A Cloudflare Worker is a serverless function
					* Workers Builds is a CI/CD system for building and deploying your Worker whenever you push code to GitHub/GitLab.

					This server allows you to view and debug Cloudflare Workers Builds for your Workers (NOT Cloudflare Pages).

					To get started, you can list your accounts (accounts_list) and then set an active account (set_active_account).
					Once you have an active account, you can list your Workers (workers_list) and set an active Worker (workers_builds_set_active_worker).
					You can then list the builds for your Worker (workers_builds_list_builds) and set an active build (workers_builds_set_active_build).
					Once you have an active build, you can view the logs (workers_builds_get_build_logs).
				`),
			},
		})

		registerAccountTools(this)

		// Register Cloudflare Workers tools
		registerWorkersTools(this)

		// Register Cloudflare Workers logs tools
		registerBuildsTools(this)
	}

	async getActiveAccountId() {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return props.account.id
			}
			// Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
			// we do this so we can persist activeAccountId across sessions
			const userDetails = getUserDetails(env, props.user.id)
			return await userDetails.getActiveAccountId()
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveAccountId(accountId: string) {
		try {
			const props = getProps(this)
			// account tokens are scoped to one account
			if (props.type === 'account_token') {
				return
			}
			const userDetails = getUserDetails(env, props.user.id)
			await userDetails.setActiveAccountId(accountId)
		} catch (e) {
			this.server.recordError(e)
		}
	}

	async getActiveBuildUUID(): Promise<string | null> {
		try {
			return this.state.activeBuildUUID
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveBuildUUID(buildUUID: string | null): Promise<void> {
		try {
			this.setState({
				...this.state,
				activeBuildUUID: buildUUID,
			})
		} catch (e) {
			this.server.recordError(e)
		}
	}

	async getActiveWorkerId(): Promise<string | null> {
		try {
			return this.state.activeWorkerId
		} catch (e) {
			this.server.recordError(e)
			return null
		}
	}

	async setActiveWorkerId(workerId: string | null): Promise<void> {
		try {
			this.setState({
				...this.state,
				activeWorkerId: workerId,
			})
		} catch (e) {
			this.server.recordError(e)
		}
	}
}

const BuildsScopes = {
	...RequiredScopes,
	'account:read': 'See your account info such as account details, analytics, and memberships.',
	'workers:read':
		'See and change Cloudflare Workers data such as zones, KV storage, namespaces, scripts, and routes.',
	'workers_builds:read':
		'See and change Cloudflare Workers Builds data such as builds, build configuration, and logs.',
} as const

export default {
	fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
		if (await isApiTokenRequest(req, env)) {
			return await handleApiTokenMode(BuildsMCP, req, env, ctx)
		}

		return new OAuthProvider({
			apiHandlers: {
				'/mcp': BuildsMCP.serve('/mcp'),
				'/sse': BuildsMCP.serveSSE('/sse'),
			},
			// @ts-expect-error
			defaultHandler: createAuthHandlers({ scopes: BuildsScopes, metrics }),
			authorizeEndpoint: '/oauth/authorize',
			tokenEndpoint: '/token',
			tokenExchangeCallback: (options) =>
				handleTokenExchangeCallback(
					options,
					env.CLOUDFLARE_CLIENT_ID,
					env.CLOUDFLARE_CLIENT_SECRET
				),
			// Cloudflare access token TTL
			accessTokenTTL: 3600,
			clientRegistrationEndpoint: '/register',
		}).fetch(req, env, ctx)
	},
}

```
Page 3/25FirstPrevNextLast