Skip to content

Commit a2f8931

Browse files
Add Dev mode auth to our MCP servers (#89)
- Update README.md and add CONTRIBUTING.md in Radar server Co-authored-by: Nevi <[email protected]>
1 parent cfc859f commit a2f8931

File tree

29 files changed

+414
-313
lines changed

29 files changed

+414
-313
lines changed

CONTRIBUTING.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Developing
2+
3+
We welcome contributions to all of our MCP servers! Here's a quick run down on how to get started.
4+
5+
## Architecture
6+
7+
This monorepo has two top-level directories: `/apps` and `/packages`.
8+
9+
- **/apps**: Containing directories for each server. Within each server, you'll find a `CONTRIBUTING.md` with any special instructions on how to get set up:
10+
- [apps/workers-observability](apps/workers-observability)
11+
- [apps/workers-bindings](apps/workers-bindings)
12+
- [apps/radar](apps/radar)
13+
- [apps/cloudflare-one-casb](apps/cloudflare-one-casb)
14+
- **/packages**: Containing shared packages used across our various apps.
15+
- packages/eslint-config: Eslint config used by all apps and packages.
16+
- packages/typescript-config: tsconfig used by all apps and packages.
17+
- packages/mcp-common: Shared common tools and scripts to help manage this repo.
18+
19+
We use [TurboRepo](https://turbo.build/) and [pnpm](https://pnpm.io/) to manage this repository. TurboRepo manages the monorepo by ensuring commands are run across all apps.
20+
21+
## Getting Started
22+
23+
This section will guide you through setting up your developer environment and running tests.
24+
25+
### Installation
26+
27+
Install dependencies:
28+
29+
```bash
30+
pnpm install
31+
```
32+
33+
### Testing
34+
35+
The project uses Vitest as the testing framework with [fetchMock](https://developers.cloudflare.com/workers/testing/vitest-integration/test-apis/) for API mocking.
36+
37+
#### Running Tests
38+
39+
To run all tests:
40+
41+
```bash
42+
pnpm test
43+
```
44+
45+
To run a specific test file:
46+
47+
```bash
48+
pnpm test -- tests/tools/queues.test.ts
49+
```
50+
51+
To run tests in watch mode (useful during development):
52+
53+
```bash
54+
pnpm test:watch
55+
```

README.md

Lines changed: 20 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,47 @@
11
# Cloudflare MCP Server
22

3-
Model Context Protocol (MCP) is a [new, standardized protocol](https://modelcontextprotocol.io/introduction) for managing context between large language models (LLMs) and external systems. In this repository, we provide an installer as well as an MCP Server for [Cloudflare's API](https://api.cloudflare.com).
3+
Model Context Protocol (MCP) is a [new, standardized protocol](https://modelcontextprotocol.io/introduction) for managing context between large language models (LLMs) and external systems. In this repository, you can find several MCP servers allowing you to connect to Cloudflare's service from an MCP client (e.g. Cursor, Claude) and use natural language to accomplish tasks through your Cloudflare account.
44

5-
This lets you use Claude Desktop, or any MCP Client, to use natural language to accomplish things on your Cloudflare account, e.g.:
5+
These MCP servers allow your [MCP Client](https://modelcontextprotocol.io/clients) to read configurations from your account, process information, make suggestions based on data, and even make those suggested changes for you. All of these actions can happen across cloudflare's many services including application development, security and performance.
66

7-
- `List all the Cloudflare workers on my <some-email>@gmail.com account.`
8-
- `Can you tell me about any potential issues on this particular worker '...'?`
7+
The following servers are included in this repository:
98

10-
## Access the remote MCP server from Claude Desktop
9+
| Server Name | Description | Server URL |
10+
| ----------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------- |
11+
| [**Documentation server**](/apps/docs-autorag) | Get up to date reference information on Cloudflare | `https://docs.mcp.cloudflare.com/sse` |
12+
| [**Workers Bindings server**](/apps/bindings) | Build Workers applications with storage, AI, and compute primitives | `https://bindings.mcp.cloudflare.com/sse` |
13+
| [**Observability server**](/apps/observability) | Debug and get insight into your application’s logs and analytics | `https://observability.mcp.cloudflare.com/sse` |
14+
| [**Radar server**](/apps/radar) | Get global Internet traffic insights, trends, URL scans, and other utilities | `https://radar.mcp.cloudflare.com/sse` |
1115

12-
Open Claude Desktop and navigate to Settings -> Developer -> Edit Config. This opens the configuration file that controls which MCP servers Claude can access.
16+
## Access the remote MCP server from any MCP client
1317

14-
Replace the content with the following configuration. Once you restart Claude Desktop, a browser window will open showing your OAuth login page. Complete the authentication flow to grant Claude access to your MCP server. After you grant access, the tools will become available for you to use.
18+
If your MCP client has first class support for remote MCP servers, the client will provide a way to accept the server URL directly within its interface (e.g. [Cloudflare AI Playground](https://playground.ai.cloudflare.com/))
19+
20+
If your client does not yet support remote MCP servers, you will need to set up its resepective configuration file using mcp-remote (https://www.npmjs.com/package/mcp-remote) to specify which servers your client can access.
1521

1622
```json
1723
{
1824
"mcpServers": {
19-
"cloudflare": {
25+
"cloudflare-observability": {
2026
"command": "npx",
2127
"args": ["mcp-remote", "https://observability.mcp.cloudflare.com/sse"]
28+
},
29+
"cloudflare-bindings": {
30+
"command": "npx",
31+
"args": ["mcp-remote", "https://bindings.mcp.cloudflare.com/sse"]
2232
}
2333
}
2434
}
2535
```
2636

2737
## Need access to more Cloudflare tools?
2838

29-
We're gradually moving over functionality to this remote MCP server repo. In the meantime please take a look at the local only mcp-server-cloudflare package which currently has more tools available.
30-
31-
Visit <https://www.npmjs.com/package/@cloudflare/mcp-server-cloudflare>
39+
We're continuing to add more functionality to this remote MCP server repo. If you'd like to leave feedback, file a bug or provide a feature request, [please open an issue](https://github.com/cloudflare/mcp-server-cloudflare/issues/new/choose) on this repository
3240

3341
## Paid Features
3442

3543
Some features may require a paid Cloudflare Workers plan. Ensure your Cloudflare account has the necessary subscription level for the features you intend to use.
3644

37-
## Features
38-
39-
### Workers Management
40-
41-
- `worker_list`: List all Workers in your account
42-
- `worker_get_worker`: Get a Worker's script content
43-
44-
### Workers Logs
45-
46-
- `worker_logs_by_worker_name`: Analyze recent logs for a Cloudflare Worker by worker name
47-
- `worker_logs_by_ray_id`: Analyze recent logs across all workers for a specific request by Cloudflare Ray ID
48-
- `worker_logs_keys`: Get available telemetry keys for a Cloudflare Worker
49-
50-
## Developing
51-
52-
### Apps
53-
54-
- [workers-observability](apps/workers-observability): The Workers Observability MCP server
55-
- [radar](apps/radar): The Cloudflare Radar MCP server
56-
57-
### Packages
58-
59-
- eslint-config: Eslint config used by all apps and packages.
60-
- typescript-config: tsconfig used by all apps and packages.
61-
- mcp-common: Shared common tools and scripts to help manage this repo.
62-
63-
For more details on development in this monorepo, take a look at apps/workers-observability
64-
65-
## Testing
66-
67-
The project uses Vitest as the testing framework with MSW (Mock Service Worker) for API mocking.
68-
69-
### Running Tests
70-
71-
To run all tests:
72-
73-
```bash
74-
pnpm test
75-
```
76-
77-
To run a specific test file:
78-
79-
```bash
80-
pnpm test -- tests/tools/queues.test.ts
81-
```
82-
83-
To run tests in watch mode (useful during development):
84-
85-
```bash
86-
pnpm test:watch
87-
```
88-
8945
## Contributing
9046

91-
Contributions are welcome! Please feel free to submit a Pull Request.
47+
Interested in contributing, and running this server locally? See [CONTRIBUTING.md](CONTRIBUTING.md) to get started.

apps/cloudflare-one-casb/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
},
2424
"devDependencies": {
2525
"@cloudflare/vitest-pool-workers": "0.8.14",
26-
"@cloudflare/workers-types": "4.20250410.0",
2726
"@types/jsonwebtoken": "9.0.9",
2827
"prettier": "3.5.3",
2928
"typescript": "5.5.4",

apps/cloudflare-one-casb/src/context.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ export interface Env {
77
MCP_OBJECT: DurableObjectNamespace<CASBMCP>
88
MCP_METRICS: AnalyticsEngineDataset
99
AI: Ai
10-
1110
CLOUDFLARE_CLIENT_ID: string
1211
CLOUDFLARE_CLIENT_SECRET: string
13-
1412
USER_DETAILS: DurableObjectNamespace<UserDetails>
13+
DEV_DISABLE_OAUTH: string
14+
DEV_CLOUDFLARE_API_TOKEN: string
15+
DEV_CLOUDFLARE_EMAIL: string
1516
}

apps/cloudflare-one-casb/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
88
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details'
99
import { getEnv } from '@repo/mcp-common/src/env'
10+
import { RequiredScopes } from '@repo/mcp-common/src/scopes'
1011
import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
1112
import { registerAccountTools } from '@repo/mcp-common/src/tools/account'
1213

@@ -86,10 +87,9 @@ export class CASBMCP extends McpAgent<Env, State, Props> {
8687
}
8788
}
8889
const CloudflareOneCasbScopes = {
90+
...RequiredScopes,
8991
'account:read': 'See your account info such as account details, analytics, and memberships.',
90-
'user:read': 'See your user info such as name, email address, and account memberships.',
9192
'teams:read': 'See Cloudflare One Resources',
92-
offline_access: 'Grants refresh tokens for long-lived access.',
9393
} as const
9494

9595
export default new OAuthProvider({

apps/dex-analysis/.eslintrc.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
module.exports = {
33
root: true,
44
extends: ['@repo/eslint-config/default.cjs'],
5-
}
5+
}

apps/dex-analysis/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@
2525
},
2626
"devDependencies": {
2727
"@cloudflare/vitest-pool-workers": "0.8.14",
28-
"@cloudflare/workers-types": "4.20250410.0",
2928
"@types/jsonwebtoken": "9.0.9",
3029
"prettier": "3.5.3",
3130
"typescript": "5.5.4",
3231
"vitest": "3.0.9",
3332
"wrangler": "4.10.0"
3433
}
35-
}
34+
}

apps/dex-analysis/src/context.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ export interface Env {
1111
MCP_OBJECT: DurableObjectNamespace<CloudflareDEXMCP>
1212
USER_DETAILS: DurableObjectNamespace<UserDetails>
1313
MCP_METRICS: AnalyticsEngineDataset
14+
DEV_DISABLE_OAUTH: string
15+
DEV_CLOUDFLARE_API_TOKEN: string
16+
DEV_CLOUDFLARE_EMAIL: string
1417
}

apps/dex-analysis/src/index.ts

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { McpAgent } from 'agents/mcp'
33

44
import {
55
createAuthHandlers,
6+
getUserAndAccounts,
67
handleTokenExchangeCallback,
78
} from '@repo/mcp-common/src/cloudflare-oauth-handler'
89
import { getUserDetails, UserDetails } from '@repo/mcp-common/src/durable-objects/user_details'
@@ -96,16 +97,42 @@ const DexScopes = {
9697
'dex:read': 'See Cloudflare Cloudflare DEX data for your account',
9798
} as const
9899

99-
export default new OAuthProvider({
100-
apiRoute: '/sse',
101-
apiHandler: CloudflareDEXMCP.mount('/sse'),
102-
// @ts-ignore
103-
defaultHandler: createAuthHandlers({ scopes: DexScopes, metrics }),
104-
authorizeEndpoint: '/oauth/authorize',
105-
tokenEndpoint: '/token',
106-
tokenExchangeCallback: (options) =>
107-
handleTokenExchangeCallback(options, env.CLOUDFLARE_CLIENT_ID, env.CLOUDFLARE_CLIENT_SECRET),
108-
// Cloudflare access token TTL
109-
accessTokenTTL: 3600,
110-
clientRegistrationEndpoint: '/register',
111-
})
100+
// TODO: Move this in to mcp-common
101+
async function handleDevMode(req: Request, env: Env, ctx: ExecutionContext) {
102+
const { user, accounts } = await getUserAndAccounts(env.DEV_CLOUDFLARE_API_TOKEN, {
103+
'X-Auth-Email': env.DEV_CLOUDFLARE_EMAIL,
104+
'X-Auth-Key': env.DEV_CLOUDFLARE_API_TOKEN,
105+
})
106+
ctx.props = {
107+
accessToken: env.DEV_CLOUDFLARE_API_TOKEN,
108+
user,
109+
accounts,
110+
} as Props
111+
return CloudflareDEXMCP.mount('/sse').fetch(req, env, ctx)
112+
}
113+
114+
export default {
115+
fetch: async (req: Request, env: Env, ctx: ExecutionContext) => {
116+
if (env.ENVIRONMENT === 'development' && env.DEV_DISABLE_OAUTH === 'true') {
117+
return await handleDevMode(req, env, ctx)
118+
}
119+
120+
return new OAuthProvider({
121+
apiRoute: '/sse',
122+
apiHandler: CloudflareDEXMCP.mount('/sse'),
123+
// @ts-ignore
124+
defaultHandler: createAuthHandlers({ scopes: DexScopes, metrics }),
125+
authorizeEndpoint: '/oauth/authorize',
126+
tokenEndpoint: '/token',
127+
tokenExchangeCallback: (options) =>
128+
handleTokenExchangeCallback(
129+
options,
130+
env.CLOUDFLARE_CLIENT_ID,
131+
env.CLOUDFLARE_CLIENT_SECRET
132+
),
133+
// Cloudflare access token TTL
134+
accessTokenTTL: 3600,
135+
clientRegistrationEndpoint: '/register',
136+
}).fetch(req, env, ctx)
137+
},
138+
}

apps/dex-analysis/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"extends": "@repo/typescript-config/workers.json",
3-
"include": ["*/**.ts"]
3+
"include": ["*/**.ts", "./vitest.config.ts", "./types.d.ts"]
44
}

0 commit comments

Comments
 (0)