Skip to content

Commit 1c96ad9

Browse files
committed
add API routes for an external mcp server
1 parent 1a57d84 commit 1c96ad9

File tree

4 files changed

+128
-0
lines changed

4 files changed

+128
-0
lines changed

app/routes/api+/blog-post.$slug.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { json } from '@remix-run/node'
2+
import { downloadMdxFilesCached } from '#app/utils/mdx.server.js'
3+
4+
export async function loader({ params }: { params: { slug: string } }) {
5+
const { slug } = params
6+
const { files } = await downloadMdxFilesCached('blog', slug, {})
7+
8+
if (!files.length) {
9+
throw new Response(`No blog post found with slug: ${slug}`, { status: 404 })
10+
}
11+
12+
return json(files)
13+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { json } from '@remix-run/node'
2+
import { getSeasons } from '#app/utils/simplecast.server.js'
3+
4+
export async function loader({
5+
params,
6+
request,
7+
}: {
8+
params: { seasonNumber: string; episodeNumber: string }
9+
request: Request
10+
}) {
11+
const seasonNumber = Number(params.seasonNumber)
12+
const episodeNumber = Number(params.episodeNumber)
13+
14+
if (isNaN(seasonNumber) || isNaN(episodeNumber)) {
15+
throw new Response('Season and episode numbers must be valid numbers', {
16+
status: 400,
17+
})
18+
}
19+
20+
const seasons = await getSeasons({ request })
21+
const season = seasons.find((s) => s.seasonNumber === seasonNumber)
22+
23+
if (!season) {
24+
throw new Response(`Season ${seasonNumber} not found`, { status: 404 })
25+
}
26+
27+
const episode = season.episodes.find((e) => e.episodeNumber === episodeNumber)
28+
29+
if (!episode) {
30+
throw new Response(`Episode ${episodeNumber} not found`, { status: 404 })
31+
}
32+
33+
return json({
34+
title: episode.title,
35+
description: episode.description,
36+
transcript: episode.transcriptHTML || null,
37+
})
38+
}

app/routes/api+/find-content.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { json } from '@remix-run/node'
2+
import { getDomainUrl } from '#app/utils/misc.js'
3+
import { searchKCD } from '#app/utils/search.server.js'
4+
5+
export async function loader({ request }: { request: Request }) {
6+
const url = new URL(request.url)
7+
const query = url.searchParams.get('query')
8+
const category = url.searchParams.get('category')
9+
10+
if (!query) {
11+
throw new Response('Query parameter is required', { status: 400 })
12+
}
13+
14+
const categoryMap: Record<string, string> = {
15+
Blog: 'b',
16+
'Chats with Kent Podcast': 'cwk',
17+
'Call Kent Podcast': 'ckp',
18+
Workshops: 'w',
19+
Talks: 't',
20+
}
21+
22+
const searchResults = await searchKCD({
23+
request,
24+
query: category ? `${categoryMap[category]}:${query}` : query,
25+
})
26+
27+
const domainUrl = getDomainUrl(request)
28+
29+
if (searchResults.length) {
30+
return json(
31+
searchResults.map(({ title, route, segment, metadata }) => ({
32+
title,
33+
url: `${domainUrl}${route}`,
34+
category: segment,
35+
...metadata,
36+
})),
37+
)
38+
}
39+
40+
return json([])
41+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { json } from '@remix-run/node'
2+
import { addSubscriberToForm } from '#app/kit/kit.server.js'
3+
import { getErrorMessage } from '#app/utils/misc.js'
4+
5+
export async function action({ request }: { request: Request }) {
6+
if (request.method !== 'POST') {
7+
return new Response('Method not allowed', { status: 405 })
8+
}
9+
10+
const formData = await request.formData()
11+
const email = formData.get('email')?.toString()
12+
const firstName = formData.get('firstName')?.toString()
13+
14+
if (!email) {
15+
return json({ error: 'Email is required' }, { status: 400 })
16+
}
17+
18+
try {
19+
await addSubscriberToForm({
20+
email,
21+
firstName: firstName ?? '',
22+
kitFormId: '827139',
23+
})
24+
25+
return json({
26+
message: `Successfully subscribed ${email} to Kent's newsletter! If you're not already on Kent's mailing list, you'll receive a confirmation email.`,
27+
})
28+
} catch (error) {
29+
return json(
30+
{
31+
error: `Failed to subscribe to the newsletter: ${getErrorMessage(error)}`,
32+
},
33+
{ status: 500 },
34+
)
35+
}
36+
}

0 commit comments

Comments
 (0)