Loading

    Master MCP: Ramp up to Cloudflare MCP Setup

    Kent C. Dodds
    Kent C. Dodds

    If you've been following the MCP Workshop series, you're probably familiar with the Epic Me Journaling app we've been building. Starting from simple tools that add numbers together, we've evolved it into a full-featured journaling MCP server through the MCP Fundamentals workshop.

    When you transition to MCP-UI, the next workshop in the series, you might expect everything to change. After all, we're moving from a standard I/O server to HTTP streaming with Cloudflare Workers. But here's the surprising truth: most of the MCP-focused code doesn't change at all.

    The Core Philosophy: MCP vs. Infrastructure

    The key insight is that MCP concepts are separate from the infrastructure that hosts them. Whether you're running on a standard I/O server, Cloudflare Workers, Netlify Functions, or Express, the MCP protocol and your server logic remain fundamentally the same.

    This is why there are no exercises to transition between these approaches in the workshop. The infrastructure changes are handled for you because they're not central to learning MCP concepts.

    What Actually Changes

    1. Database Architecture

    The most significant change is moving from a local SQLite database to a separate application that holds all the data. Instead of having a database file in your MCP server, you now have:

    • A separate Epic Me app running on port 7787
    • HTTP calls to communicate with that app
    • A database client that abstracts these calls

    This mirrors real-world scenarios where you have an existing application and want to build an MCP server that communicates with it.

    // Before: Direct database access
    const entries = await db.getEntries()
    // After: HTTP client (same interface)
    const entries = await db.getEntries()

    The interface remains the same, but the implementation now makes HTTP calls to your separate application.

    2. Package Dependencies

    The package.json changes to support Cloudflare Workers:

    • Add @cloudflare/workers-types for TypeScript support
    • Add wrangler for local development and deployment
    • Add @cloudflare/agents for MCP integration with Cloudflare

    The MCP SDK itself doesn't change - you're just adding Cloudflare-specific dependencies.

    3. Server Structure

    Instead of a main() function, you now export a class that gets wired up by the Cloudflare Worker.

    4. Removed Features

    Some features are removed to keep the focus on MCP learning:

    • Video processing: Removed FFmpeg video tools (not relevant to MCP learning)
    • Subscriptions: Removed database change subscriptions (parallel topic to MCP)
    • Elicitation: Disabled (not yet supported in Cloudflare environment)

    These removals keep the workshop focused on core MCP concepts rather than platform-specific features.

    What Stays the Same

    The good news is that most of your MCP code remains unchanged:

    • Tools: Same tool definitions and logic
    • Resources: Same resource structure (minus video resources)
    • Prompts: Same prompt definitions
    • Database operations: Same interface, different implementation
    • MCP protocol: Identical across all platforms

    The Real-World Parallel

    This architecture mirrors what you'll encounter in production environments. You typically have:

    1. An existing application with its own database
    2. An MCP server that communicates with that application
    3. HTTP APIs for data access
    4. Platform-specific hosting (Cloudflare, Vercel, etc.)

    The MCP-UI workshop prepares you for this reality by separating concerns between your application and your MCP server.

    Looking Ahead

    The MCP-UI workshop continues to evolve this architecture:

    • UI Framework: Adds React Router for displaying UI components
    • Authentication: The auth workshop adds authentication layers
    • Platform Features: Each platform (Cloudflare, Vercel, etc.) has its own optimizations

    But the core MCP concepts remain consistent throughout.

    Key Takeaways

    1. MCP is platform-agnostic: The protocol works the same regardless of hosting
    2. Infrastructure changes are minimal: Focus on MCP concepts, not platform details
    3. Real-world architecture: Separate applications communicating via HTTP
    4. Consistent interfaces: Your MCP code can remain largely unchanged

    The transition from MCP Fundamentals to MCP-UI is less about learning new MCP concepts and more about understanding how MCP fits into real-world application architectures. The core skills you've developed remain valuable and transferable across different hosting platforms.

    Remember: MCP is about the protocol and the tools you build, not the infrastructure that hosts them. Focus on the concepts, and the platform details will fall into place.

    Share

    Hey, so if you've been going through the MCP Workshop series, then you might have gotten used to the app that we're building through MCP, the Epic Me Journaling app. We started out here in the MCP Fundamentals. We start with some really simple tools with adding numbers together and stuff. And then that gets upgraded to a full journaling MCP server. And we continue with that through MCP Fundamentals, and it just continues to evolve and adding more and more features.

    In MCPUI, which is the next workshop in the series. We stick with that as the concept. So we're still doing the Epic Me journaling app, but we kind of changed the way that it's structured. Both of these workshops use a standard I-O server, But when we get over to MCPUI, we're using HTTP streaming. And so the setup is a little bit different, and I wanted to show you what some of those differences are.

    The good thing is that most of the MCP-focused stuff doesn't change at all, which is why we don't actually have any exercises to take us from the standard I.O. Over to the streaming. Instead, I just kind of do that for you because it's not actually all that relevant as far as the MCP side of things is concerned. And even the way that we do it with MCPUI with Cloudflare is going to be a little different than if you do it with another hosting provider or with an express server or whatever. And So, because of that, it's a little like it's parallel to MCP.

    We're not going to have any exercises about that. But I'll take you through the diff so you get an idea of what this actually looks like. So this is the subscriptions version of the workshop. So it's this right here, the version of the workshop at the solution of the very last exercise, and we're taking that as a diff to the very first exercise, the problem of the first exercise of the MCPUI workshop. So, that's what we're comparing here.

    You'll notice we delete a bunch of things, or we move a lot of things. So, before we had, of course, a SQLite database. That is now moved completely, and instead we have, I think it's 7787, or something like that, yeah. We have this new app that's running right alongside the rest of your workshop app experience and so when you start the workshop app this app gets started automatically and it holds all of the data. So we've got these entries, we've got Kelly, and this app is really cool because you can come over here and click Reset Database and KB Store, and now We've got five entries.

    And so you can always just come over to this app and get your data exactly where it needs to be. You don't need to worry about seeding the database or anything like that. And all of your exercises, everything is going to be pointing to this app. So this is actually, I think, what most of you are going to experience as you apply MCP in the workplace, is you've got an existing application and you want to build an MCP server that communicates to that application. So that's why I structured it like this.

    Here's our existing application, and now we're going to make an MCP server that talks to that application. And so, to that end, we get rid of the SQLite database from our MCP server, because all of that lives in that separate app, in the Epic Me app. We also get rid of this font that was for the FFmpeg videos. We remove that tool entirely. That is, yeah, we no longer use that.

    The package.json changes as well because we are now using Wrangler for our server and all of that. Let me bump this up a little bit. And Wrangler is the CLI for Cloudflare for running things locally and even deploying onto Cloudflare. Most things don't really change. It looks like the SDK, I updated that.

    So I should go back and update that in the advanced thing. But nothing really changes with the SDK. We add agents as a dependency. This is coming from Cloudflare, and this is how you use the SDK for MCP with Cloudflare's technology. And yeah, for the most part, like, not significant changes there.

    We get rid of everything that's in the database and instead all of that has been moved over to the Epic Me app and we're going to be making HTTP calls to make database calls and stuff like that. And let's see, yeah, so The resources actually changes significantly enough that get things we just deleted it, but we actually move it and we change just a little bit. There's not really a lot that's changed as far as the resources are concerned. The reason probably that it thought we changed a lot is because, actually, I'm really not sure why. We don't change a ton.

    We do remove the video resource, but we keep the entry resource. We keep the tag resource. We don't really change a lot about resources. We remove subscriptions entirely. We also remove video entirely.

    And part of the reason for that is it's just an extra thing that I would have to add to the Epic Me server to support database subscriptions and stuff. So I don't bother doing that. Whatever app you're building, they're going to have data subscriptions or they're not. And that is kind of a parallel topic to MCP, and so we're leaving that out. So I delete that.

    Also, the video stuff, we are not going to be doing that. I'd have to do a whole separate thing on Cloudflare to make that work. And it's not relevant to your learning of MCP. So we do get rid of some of the tools associated with that. TS config is going to change that.

    I don't think it's relevant to you. We now have a worker DBTS file. This is going to be the database client that communicates to the Epic Me app. And so this server address is going to be running alongside your application as you're running it, and we create a new instance of that DB client. This DB variable is effectively the exact same as what we had in the previous workshops.

    And so as you've been doing db.getentries and stuff like that, all of those things will be the same. I did, it turns out, I discovered as I was making this video, that I did change a couple of the things that went from getentries to listentries or vice versa or something like that. But For all intents and purposes, it's basically the same, and it's all fully typed, and it's nice. You can dive in to figure out how I made that work. It is kind of hacky, but it works, and it works great.

    And at whatever app that you're building, you probably have some mechanism for communicating with your downstream services, for making API calls. So just do whatever that does. Okay, and then our index changes. So this is how you set up a Cloudflare worker. It's just export default, a fetch function that accepts a request, the environment stuff, and execution context.

    This is not relevant to MCP specifically. This is just Cloudflare worker stuff. If you're hosting on Netlify or Vercel or wherever else, It's all going to be those specific platform will have their own way of doing this. The point here is that when we make a request to slash MCP, we're going to be using the Epic Me MCP durable object. If you don't know what a durable object is, that is just fine.

    You don't have to understand what a durable object is to be able to learn everything you need to know about MCP. Feel free to dive into that topic a little bit later. But yeah, we're going to just leave that as an exercise for you. And then, yeah, we have our Wrangler config, and here you can dive into that if you're curious about what that's all about. But the most important stuff is all of what's inside of the source directory.

    So This was the file that had the most number of changes. So we no longer have the database. We now instead have a DB client. We're using the agent's MCP to create our MCP agent. A big part of why I structured things the way I did in the standard I O exercises is because I really like the structure of the CloudFlare MCP API with the durable objects.

    And so we structure it in a similar way so that we can just kind of continue with that. And so you'll notice in here, like, we're still initialize prompts, initialize resource, initialize tools. We get rid of the subscription stuff. It's still a class. It has a database.

    But here we're going to say that Our database is the DB client. And then we extend the MCP agent. We create our MCP class here. I changed the title for some reason. I don't know why, but all of this stuff is exactly the same.

    We no longer need a constructor. We initialize the database as part of the init. Our database is just the instance of our DB client, and so we just set it here as a convenience thing. So anywhere the agent is, you can say agent.db. We've got all the initialization is the same.

    We no longer have a main function. We instead export this class, and then that gets wired up by our worker index right here. So not a ton of changes there. Like fundamentally, it's all very, very similar. And then if we look at something like prompts, instead of assigning the prompt to a value so that we can do the update prompts thing, we did that with the list change.

    We got rid of database subscriptions and stuff like that. You can still definitely do that in a Cloudflare worker. And so if you want to, feel free to do that. But I removed that to reduce the amount of extra code that's in here that's not entirely relevant. And also, yeah, for some reason, I changed it from list tags to get tags in here.

    Don't remember doing that, but I guess I did. And so, hopefully that doesn't throw anybody for a loop. And then with sampling, same sort of thing. Yeah, just that. I probably, I regret doing that now because it would be like, look, nothing changed.

    But now it looks like a lot of things changed, but it really didn't change a whole lot. Again, this is very similar. I'm kind of surprised that Git decided that this was such a significant change that it said we deleted one file and added another rather than moving it. And then yeah, tools had probably the most changes, but like again, it's all just, we're no longer assigning these values to anything. We just register the tool.

    We don't disable or enable them. That's what Most of this is. A couple of whitespace changes here as well. This is set up for the first exercise of the MCPUI workshop. Yeah, for the most part, all the same.

    We did delete the create wrapped video. And yeah. Oh, also, as of this recording, Cloudflare does not support elicitation. And so we just disable it here. There is an issue that's being tracked on that, because the way that elicitation works in the SDK doesn't work in the Cloudflare environment.

    So they're working on that, and that will eventually not be a problem. So that's that. That's pretty much all you need to know about the differences between what you've been working on so far in the workshop series, and what you can expect from MCPUI, as well as the auth workshop. Auth workshop does a very similar thing to this, adds a bunch of authentication stuff. MCPUI actually gets relatively complicated as we get further on.

    We'll get to this part, where we add in an entire framework for displaying UI. It's a React router. And I take you on a tour of this later in the exercises, but yeah. So there will be yet another slight change to this, and our worker index will have to change to add the React router support and all of that stuff. So you'll be eased into that when we get to that point.

    And then when we go to the auth stuff, we actually remove a bunch of that. We remove all the UI stuff just to focus purely on auth, but it's all still Cloudflare sort of thing. So anyway, I just wanted to make this video really quick for you to get yourself familiar with the way that things are and how things change between MCPUI and the other workshops that you've been doing before this. I hope that is helpful to you and I look forward to working with you