- Security.
- Cloudflare's quick-start template is authless: 'anyone can connect and use the server'.
- Never point an authless server at internal data.
- Use test data only until sign-in (step 3 or 4) and the step 6 tests pass.
You will need
- A Cloudflare account (Workers has a free plan; Workers Paid starts at $5 a month)
- Your data in a store the Worker can read, for example Cloudflare D1
- An identity provider for sign-in (GitHub, Google, Cloudflare Access or your own)
- A written list of the records and fields agents may read
You will end up with
- A remote MCP server that rejects any request without a valid sign-in token
- One read-only tool per record type, returning only the fields on your list
- Tools shown only to users who are allowed to use them
List what agents may read
Write down each record type and field agents should see. Leave out anything sensitive. This list is what you will test against in step 6.
Build the server with the Agents SDK
Create a remote MCP server on Workers with the Agents SDK (createMcpHandler). Create one tool per record type, each with a narrow input schema (for example with Zod) and a handler that runs a fixed, parameterised SELECT. Mark the tools readOnlyHint: true, but do not rely on that hint for security: clients treat annotations as untrusted, so the real protection is that your handlers only read.
Sources: Cloudflare docs: Build a Remote MCP server · Cloudflare docs: MCP Tools · Cloudflare D1 · MCP spec 2025-06-18: Schema (ToolAnnotations) · MCP spec 2025-11-25: Tools
Require sign-in (OAuth) before any tool runs
Do not deploy the authless template with real data: Cloudflare's guide says that without authentication 'anyone can connect and use the server'. Instead, build an authorization server Worker with Cloudflare's Workers OAuth Provider library (OAuthAuthorizationServer). Its /authorize page signs users in through GitHub, Google, Cloudflare Access or another identity provider. Wrap your MCP handler in OAuthResourceServer: it answers requests without a valid token with a 401 and rejects tokens issued for any other resource. MCP clients follow the 401, sign the user in, and retry with a token. This is the OAuth 2.1 flow the MCP specification defines.
Sources: Cloudflare docs: Build a Remote MCP server · cloudflare/workers-oauth-provider on GitHub · Cloudflare docs: MCP Authorization · MCP spec: Authorization
Alternative: put it behind Cloudflare Access
If your team already uses Cloudflare Access, it can sign users in to the MCP server with your identity provider or a one-time PIN, and only lets in people who match your Access policies.
Sources: Cloudflare docs: MCP Authorization — Cloudflare Access · Cloudflare One docs: Secure MCP servers with Access
Limit tools by user
Use the signed-in user's details (getMcpAuthContext) to check permissions inside each tool, or register only the tools a user may use. Never log or return the props, since they can hold access tokens.
Sources: Cloudflare docs: MCP Authorization — permission-based tool access
Test every tool before connecting agents
Use the MCP Inspector to call each tool, signed in as a normal user and with no token at all. A request with no token must get a 401. Each tool must return only the fields on your list. Keep a person able to deny tool calls in the client.
Sources: MCP Inspector · MCP spec 2025-06-18: Tools
Human checkpoint. A person approves this step before the agent goes further.