Skip to content

Commit cc9d9da

Browse files
committed
feat: add new exercises for middle section without and with React Router, including worker setup, MCP integration, and various utility functions
1 parent 4e1377e commit cc9d9da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+36050
-68
lines changed
Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,17 @@
1-
import { type DBClient } from '@epic-web/epicme-db-client'
2-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
3-
import {
4-
SetLevelRequestSchema,
5-
type LoggingLevel,
6-
} from '@modelcontextprotocol/sdk/types.js'
7-
import { McpAgent } from 'agents/mcp'
8-
import { db } from './client.ts'
9-
import { initializePrompts } from './prompts.ts'
10-
import { initializeResources } from './resources.ts'
11-
import { initializeTools } from './tools.ts'
12-
13-
type State = { loggingLevel: LoggingLevel }
14-
export class EpicMeMCP extends McpAgent<Env, State> {
15-
db!: DBClient
16-
initialState: State = { loggingLevel: 'info' }
17-
server = new McpServer(
18-
{
19-
name: 'epicme',
20-
title: 'EpicMe Journal',
21-
version: '1.0.0',
22-
},
23-
{
24-
capabilities: {
25-
tools: { listChanged: true },
26-
resources: { listChanged: true, subscribe: true },
27-
completions: {},
28-
logging: {},
29-
prompts: { listChanged: true },
30-
},
31-
instructions: `
32-
EpicMe is a journaling app that allows users to write about and review their experiences, thoughts, and reflections.
33-
34-
These tools are the user's window into their journal. With these tools and your help, they can create, read, and manage their journal entries and associated tags.
35-
36-
You can also help users add tags to their entries and get all tags for an entry.
37-
`.trim(),
38-
},
39-
)
40-
41-
async init() {
42-
this.db = db
43-
this.server.server.setRequestHandler(
44-
SetLevelRequestSchema,
45-
async (request) => {
46-
this.setState({ ...this.state, loggingLevel: request.params.level })
47-
return {}
48-
},
49-
)
50-
await initializeTools(this)
51-
await initializeResources(this)
52-
await initializePrompts(this)
53-
}
54-
}
1+
import { EpicMeMCP } from './mcp/index.ts'
552

563
export default {
574
fetch: async (request, env, ctx) => {
585
const url = new URL(request.url)
596

607
if (url.pathname === '/mcp') {
61-
const mcp = EpicMeMCP.serve('/mcp', {
8+
return EpicMeMCP.serve('/mcp', {
629
binding: 'EPIC_ME_MCP_OBJECT',
63-
})
64-
return mcp.fetch(request, env, ctx)
10+
}).fetch(request, env, ctx)
6511
}
6612

6713
return new Response('Not found', { status: 404 })
6814
},
6915
} satisfies ExportedHandler<Env>
16+
17+
export { EpicMeMCP }
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { type DBClient } from '@epic-web/epicme-db-client'
2+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
3+
import {
4+
SetLevelRequestSchema,
5+
type LoggingLevel,
6+
} from '@modelcontextprotocol/sdk/types.js'
7+
import { McpAgent } from 'agents/mcp'
8+
import { db } from '../db.ts'
9+
import { initializePrompts } from './prompts.ts'
10+
import { initializeResources } from './resources.ts'
11+
import { initializeTools } from './tools.ts'
12+
13+
type Props = { baseUrl: string }
14+
type State = { loggingLevel: LoggingLevel }
15+
16+
export class EpicMeMCP extends McpAgent<Env, State, Props> {
17+
db!: DBClient
18+
initialState: State = { loggingLevel: 'info' }
19+
server = new McpServer(
20+
{
21+
name: 'epicme',
22+
title: 'EpicMe Journal',
23+
version: '1.0.0',
24+
},
25+
{
26+
capabilities: {
27+
tools: { listChanged: true },
28+
resources: { listChanged: true, subscribe: true },
29+
completions: {},
30+
logging: {},
31+
prompts: { listChanged: true },
32+
},
33+
instructions: `
34+
EpicMe is a journaling app that allows users to write about and review their experiences, thoughts, and reflections.
35+
36+
These tools are the user's window into their journal. With these tools and your help, they can create, read, and manage their journal entries and associated tags.
37+
38+
You can also help users add tags to their entries and get all tags for an entry.
39+
`.trim(),
40+
},
41+
)
42+
43+
async init() {
44+
this.db = db
45+
this.server.server.setRequestHandler(
46+
SetLevelRequestSchema,
47+
async (request) => {
48+
this.setState({ ...this.state, loggingLevel: request.params.level })
49+
return {}
50+
},
51+
)
52+
await initializeTools(this)
53+
await initializeResources(this)
54+
await initializePrompts(this)
55+
}
56+
}
57+
58+
export default {
59+
fetch: async (request, env, ctx) => {
60+
const url = new URL(request.url)
61+
62+
if (url.pathname === '/mcp') {
63+
// can add this as request headers once https://github.com/cloudflare/agents/pull/426
64+
ctx.props.baseUrl = url.origin
65+
66+
const mcp = EpicMeMCP.serve('/mcp', {
67+
binding: 'EPIC_ME_MCP_OBJECT',
68+
})
69+
return mcp.fetch(request, env, ctx)
70+
}
71+
72+
return new Response('Not found', { status: 404 })
73+
},
74+
} satisfies ExportedHandler<Env>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Without React Router

0 commit comments

Comments
 (0)