11import OAuthProvider from '@cloudflare/workers-oauth-provider'
22import { McpAgent } from 'agents/mcp'
3- import { env } from 'cloudflare:workers'
43
54import {
65 createAuthHandlers ,
76 handleTokenExchangeCallback ,
87} from '@repo/mcp-common/src/cloudflare-oauth-handler'
8+ import { getUserDetails , UserDetails } from '@repo/mcp-common/src/durable-objects/user_details'
9+ import { getEnv } from '@repo/mcp-common/src/env'
910import { RequiredScopes } from '@repo/mcp-common/src/scopes'
1011import { CloudflareMCPServer } from '@repo/mcp-common/src/server'
1112import { registerAccountTools } from '@repo/mcp-common/src/tools/account'
@@ -14,6 +15,11 @@ import { MetricsTracker } from '@repo/mcp-observability'
1415import { registerDEXTools } from './tools/dex'
1516
1617import type { AccountSchema , UserSchema } from '@repo/mcp-common/src/cloudflare-oauth-handler'
18+ import type { Env } from './context'
19+
20+ export { UserDetails }
21+
22+ const env = getEnv < Env > ( )
1723
1824const metrics = new MetricsTracker ( env . MCP_METRICS , {
1925 name : env . MCP_SERVER_NAME ,
@@ -62,36 +68,32 @@ export class CloudflareDEXMCP extends McpAgent<Env, State, Props> {
6268 registerDEXTools ( this )
6369 }
6470
65- initialState : State = {
66- activeAccountId : null ,
67- }
68-
69- getActiveAccountId ( ) {
70- // TODO: Figure out why this fail sometimes, and why we need to wrap this in a try catch
71+ async getActiveAccountId ( ) {
7172 try {
72- return this . state . activeAccountId ?? null
73+ // Get UserDetails Durable Object based off the userId and retrieve the activeAccountId from it
74+ // we do this so we can persist activeAccountId across sessions
75+ const userDetails = getUserDetails ( env , this . props . user . id )
76+ return await userDetails . getActiveAccountId ( )
7377 } catch ( e ) {
78+ this . server . recordError ( e )
7479 return null
7580 }
7681 }
7782
78- setActiveAccountId ( accountId : string ) {
79- // TODO: Figure out why this fail sometimes, and why we need to wrap this in a try catch
83+ async setActiveAccountId ( accountId : string ) {
8084 try {
81- this . setState ( {
82- ...this . state ,
83- activeAccountId : accountId ,
84- } )
85+ const userDetails = getUserDetails ( env , this . props . user . id )
86+ await userDetails . setActiveAccountId ( accountId )
8587 } catch ( e ) {
86- return null
88+ this . server . recordError ( e )
8789 }
8890 }
8991}
9092
9193const DexScopes = {
9294 ...RequiredScopes ,
95+ 'account:read' : 'See your account info such as account details, analytics, and memberships.' ,
9396 'dex:read' : 'See Cloudflare Cloudflare DEX data for your account' ,
94- offline_access : 'Grants refresh tokens for long-lived access.' ,
9597} as const
9698
9799export default new OAuthProvider ( {
0 commit comments