Skip to content

Run prettier formatter over all files #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// This configuration only applies to the package manager root.
/** @type {import("eslint").Linter.Config} */
module.exports = {
ignorePatterns: [
'apps/**',
'packages/**',
],
extends: ['@repo/eslint-config/default.cjs']
ignorePatterns: ['apps/**', 'packages/**'],
extends: ['@repo/eslint-config/default.cjs'],
}
5 changes: 1 addition & 4 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
],
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
"**/packages/tools/bin/*": "shellscript",
"**/*.css": "tailwindcss",
"turbo.json": "jsonc",
"**/packages/typescript-config/*.json": "jsonc",
"**/packages/typescript-config/*.json": "jsonc"
},
"eslint.workingDirectories": [
{
"mode": "auto"
}
],
]
}
68 changes: 35 additions & 33 deletions apps/workers-observability/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,58 @@
import OAuthProvider from "@cloudflare/workers-oauth-provider";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpAgent } from "agents/mcp";
import type { Env } from "../worker-configuration";
import { registerAccountTools } from "./tools/account";
import { registerLogsTools } from "./tools/logs";
import { registerWorkersTools } from "./tools/workers";
import OAuthProvider from '@cloudflare/workers-oauth-provider'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { McpAgent } from 'agents/mcp'

import {
type AccountSchema,
CloudflareAuthHandler,
type UserSchema,
handleTokenExchangeCallback,
} from "@repo/mcp-common/src/cloudflare-oauth-handler";
} from '@repo/mcp-common/src/cloudflare-oauth-handler'

import { registerAccountTools } from './tools/account'
import { registerLogsTools } from './tools/logs'
import { registerWorkersTools } from './tools/workers'

import type { AccountSchema, UserSchema } from '@repo/mcp-common/src/cloudflare-oauth-handler'
import type { Env } from '../worker-configuration'

// Context from the auth process, encrypted & stored in the auth token
// and provided to the DurableMCP as this.props
export type Props = {
accessToken: string;
user: UserSchema["result"];
accounts: AccountSchema["result"];
};
accessToken: string
user: UserSchema['result']
accounts: AccountSchema['result']
}

export type State = { activeAccountId: string | null };
export type State = { activeAccountId: string | null }

export class MyMCP extends McpAgent<Env, State, Props> {
server = new McpServer({
name: "Remote MCP Server with Workers Observability",
version: "1.0.0",
});
name: 'Remote MCP Server with Workers Observability',
version: '1.0.0',
})
// TOOO: Why does this type need to be declared again on MyMCP?
// @ts-ignore
env!: Env;
env!: Env

initialState: State = {
activeAccountId: null,
};
}

async init() {
registerAccountTools(this);
registerAccountTools(this)

// Register Cloudflare Workers tools
registerWorkersTools(this);
registerWorkersTools(this)

// Register Cloudflare Workers logs tools
registerLogsTools(this);
registerLogsTools(this)
}

getActiveAccountId() {
// TODO: Figure out why this fail sometimes, and why we need to wrap this in a try catch
try {
return this.state.activeAccountId ?? null;
return this.state.activeAccountId ?? null
} catch (e) {
return null;
return null
}
}

Expand All @@ -60,23 +62,23 @@ export class MyMCP extends McpAgent<Env, State, Props> {
this.setState({
...this.state,
activeAccountId: accountId,
});
})
} catch (e) {
return null;
return null
}
}
}

export default new OAuthProvider({
apiRoute: "/workers/observability/sse",
apiRoute: '/workers/observability/sse',
// @ts-ignore
apiHandler: MyMCP.mount("/workers/observability/sse"),
apiHandler: MyMCP.mount('/workers/observability/sse'),
// @ts-ignore
defaultHandler: CloudflareAuthHandler,
authorizeEndpoint: "/oauth/authorize",
tokenEndpoint: "/token",
authorizeEndpoint: '/oauth/authorize',
tokenEndpoint: '/token',
tokenExchangeCallback: handleTokenExchangeCallback,
// Cloudflare access token TTL
accessTokenTTL: 3600,
clientRegistrationEndpoint: "/register",
});
clientRegistrationEndpoint: '/register',
})
62 changes: 33 additions & 29 deletions apps/workers-observability/src/tools/account.ts
Original file line number Diff line number Diff line change
@@ -1,85 +1,89 @@
import { z } from "zod";
import type { MyMCP } from "../index";
import { handleAccountsList } from "@repo/mcp-common/src/api/account"
import { getCloudflareClient } from "@repo/mcp-common/src/cloudflare-api";
import { z } from 'zod'

import { handleAccountsList } from '@repo/mcp-common/src/api/account'
import { getCloudflareClient } from '@repo/mcp-common/src/cloudflare-api'

import type { MyMCP } from '../index'

export function registerAccountTools(agent: MyMCP) {
// Tool to list all accounts
agent.server.tool(
"accounts_list",
"List all accounts in your Cloudflare account",
'accounts_list',
'List all accounts in your Cloudflare account',
{},
async () => {
try {
const results = await handleAccountsList({client: getCloudflareClient(agent.props.accessToken)});
const results = await handleAccountsList({
client: getCloudflareClient(agent.props.accessToken),
})
// Sort accounts by created_on date (newest first)
const accounts = results
// 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();
});
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",
type: 'text',
text: JSON.stringify({
accounts,
count: accounts.length,
}),
},
],
};
}
} catch (error) {
return {
content: [
{
type: "text",
type: 'text',
text: `Error listing accounts: ${error instanceof Error && error.message}`,
},
],
};
}
}
},
);
}
)

const activeAccountIdParam = z
.string()
.describe(
"The accountId present in the users Cloudflare account, that should be the active accountId.",
);
'The accountId present in the users Cloudflare account, that should be the active accountId.'
)
agent.server.tool(
"set_active_account",
"Set active account to be used for tool calls that require accountId",
'set_active_account',
'Set active account to be used for tool calls that require accountId',
{
activeAccountIdParam,
},
async (params) => {
try {
const { activeAccountIdParam: activeAccountId } = params;
agent.setActiveAccountId(activeAccountId);
const { activeAccountIdParam: activeAccountId } = params
agent.setActiveAccountId(activeAccountId)
return {
content: [
{
type: "text",
type: 'text',
text: JSON.stringify({
activeAccountId,
}),
},
],
};
}
} catch (error) {
return {
content: [
{
type: "text",
type: 'text',
text: `Error setting activeAccountID: ${error instanceof Error && error.message}`,
},
],
};
}
}
},
);
}
)
}
Loading