📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

I Built an MCP Registry Tracker with GitHub Spec Kit

Den Delimarsky47:30

Transcription

I had an idea, and that idea is related to the fact that I'm involved with the MCP ecosystem, and the MCP ecosystem recently had this new addition called the MCP registry. It's basically an index of all MCP servers out there in the world. Then they can be remote MCP servers, it can be local MCP servers. And I thought, like, wait, Dan, like it would be nice to take a look at some kind of dashboard that tells me the growth of the number of those servers, and especially growth of local versus remote. And I thought, how would I actually do this? And then I actually reminded myself that I've been rambling about specit for the past couple of days, and we can use specit to try and build out this experience. So, it's trial by fire. We're actually going to put this to the test with a real project, a real scenario, and see what we get. So, let's dive right in.

And I have a GitHub repository here. It's called MCP Registry Growth. It's open by the time this video goes live. You will see it in GitHub as well. I'm on my main branch. So, nothing special here. I'm going to minimize this, and I'm going to go to Firefox, and you'll see that this registry is empty. I'm going to just refresh it. Yeah, the repo has nothing. There's a readme, there's a gitignore, and I literally have not bootstrapped anything here, and we're going to be using specit.

Now, I mentioned the registry. So, the registry, if we go to the actual registry repo in GitHub as well for model context protocol registry, we can look at documentation. The documentation is going to tell us how to consume the content of the registry through the REST API, which is also kind of neat because it doesn't actually require any. And I can look at this neatly formatted JSON here and see the structure, right? So, we have some uh server definitions and schema descriptions, which is nice, and because there's also a lot of them, I just keep scrolling. We also have this metadata. This is next cursor. So, we have some pagination logic here, which is also kind of cool. All right. So, it's not going to actually flood the the response with just a bunch of JSON data.

Now, I want a web UI. I want a web UI that regularly provides me a view over the growth of MCP servers. Now, let's use specit for that. I'm going to go here and copy the command that I use all the time. All right. So, we're going to look at the folder in the explorer here. So, again, this is just the empty repo. I have my git, gitignore, and readme. So, it's inside documents. All right. Let's go to terminal. Okay. Let's go to documents, GitHub. Okay. Let's do cd MCP registry growth. And I can use init. And then here, and that means that I'm just going to be using the current folder for the initialization. I don't need to do any fancy custom project um init logic. So, all right, we will be using the existing files. Yep, that sounds good. We're going to be using C-Pilot with PowerShell. All right, great.

Now I can jump into VS Code. Let's take a look. So, we have our. Let's trust the authors because it's the author is me. Of course, I trust myself. We have our blank readme, the gitignore. We have the github and the specify folders that we've seen before. Now, the first step we're going to do is we're going to go and update the constitution. And for this, I want to use the LLM to go and write this for me. But I have some idea of what the principle should be. So, um, let's update the constitution. The following principle should apply: static site, responsive design, minimal dependencies unless required. That sounds like a reasonable set of constraints, right? Like if we're looking at non-negotiable pieces here, and these are the things, again, refer to the previous videos. Um, these are things that you should embed into your project, and these are the things that the specify toolkit or the the kind of the spec kit core is going to be using to make sure that they're followed all the time.

Now, I also used ask instead of agent. So, I'm just going to swap back to agent and then say this. And let's just rerun the prompt. It's just easier that way. This this is how you know this is happening right now because I'm actually tinkering with this and seeing the output that this is going to produce. So, let's see how far we get. And I'm using Sonnet 4, which can be a little bit overeager, but for just the definition of our specs, it should be great. It should work just just right. Uh, and by the way, if you didn't know, John Lamb, when he initially started this project, a lot of this came on the heels of the fact that he wanted to put guardrails around Sonnet models because they're so overeager. They want to write so much code that you had to put some kind of limits, and the documentation in the spec kit is essentially a response to how do you encode those limits into the process. So, we're going to keep this. Let's take a look. So, core principle: static site architecture, responsive design, minimal dependencies, performance first, and accessibility and standards. That sounds reasonable. Yeah. Build and deployment. Yep. Environment-specific development workload governance. All right. That sounds reasonable. All this sounds pretty good.

So, now let's go and build out the specification. And this is the PRD. So, we're going to use the specify command. And here is where I define the what and the why. And in this case, we are building a one-page web app that is going to list the MCP server analytics. We'll be using the existing registry API to aggregate data regularly and then present it to the user on one richly formatted page with graphs. Page should be dark themed. We're not actually going to include the response on this part because it's for the the actual technical decision. But, um, it should be dark themed. It should follow a modern color scheme: purple, blue, pink. That's what I envision as a modern color scheme. Now, you you can decide to use something else. Of course, this is just my choice right now. And modern color scheme. There are also ways to filter the servers by local or remote because, as I said, servers can be local or remote. And if we were going to be tracking some analytics and counts, we want to make sure that those are presented properly on this page. Remote. And that will reflect in charts. And the charts are essentially, how do we put this? They're timelines, uh, time charts. I'm just going to say the charts are time charts. Date on the x-axis, counts on the y-axis with hourly granularity. Also, here's the thing that I want to encode in the experience as well. I want to make sure that as we look at the data, we have the ability to switch granularity. So, I can switch between hourly, daily, weekly, monthly. Granularity can also be switched. All right. And because the counts are actually snapshots, we can always rely on the latest value. And I'm going to say that the site should also have an about page because I'm going to write, you know, what's the motivation for this and who I am and all that stuff. Okay. So, this I think is a good starting point for us to stop and just have it go and create the spec. It's going to use the specify prompt file. So, it's going to go ahead and run the script, and we're going to allow it to run it. I did not enable yolo mode here because with the latest npm changes, uh, or breaches that we see, I do not trust npm packages to come in clean. So, I'm I'm putting some guardrails, and of course, all of this is running inside a VM. So, I'm not really worried about my uh data being accidentally exposed to those malicious packages. That's very, very important. So, as you you're experimenting with a lot of these things, security should be top of mind. And for me, as a security person, that's one of the things that I I always keep in mind. You just you have to make sure that your machine is not going to get compromised because you're running an npm package. Um, so we're going to be waiting for the spec to be created here.

So, we see that it actually added the feature that we're looking at. And let's see, is this reflected? Yep, it's reflected in the actual GitHub desktop client. I use GitHub Desktop because I like the diffing and I like just the view that's entirely focused on my files. I I know I know I could use it from VS Code. I know I could use it through many other ways, but I just like I like the UI. I like the experience. So, we see that all the files get added here, which is nice. It's all good. We have the spec. Let's take a look at the spec. I want to keep the file as is. All right. So, we have the description. We can just scroll right past that. So, as a user interested in MCP ecosystem growth, compare local store usage and gain insights on the ecosystem's development. Okay. Yeah, that makes sense. Yep. Yep. This makes sense. We have acceptance scenarios. Then we have some edge cases. Okay. Some requirements. Okay. All right. Key entities: remote time scene data for analytics. Yep. Analytics data point. Yep. Filter state time period. Yep. That sounds good. And we have all the acceptance checklist. Remember in previous videos, I talked about the acceptance checklist. So, nothing needs clarification. It's a fairly straightforward project, right? So, uh, that makes sense just at a at a glance. A lot of these things are fairly reasonable for the project that we're creating because we're following a standard template. It also makes it very easy to just encode a lot of these things and change them if we see something that stands out. But so far, nothing really stands out and says single page. You know, all all the stuff just makes sense for exactly what I am building here.

Now, it's time for us to define a technical plan. So, we're going to say plan. This is a Next.js-based JS-based application. Rely on shadcn for UI components. Okay. And what I also want to do here is we are using GitHub actions to run this every hour. Right. So, we're going to for GitHub actions, we're going to run this every hour. So, we're going to just copy-paste this. The data aggregation. Okay. So, now we're specifying the endpoint. And also, because I want to be very specific, there is a metadata here. So, I'm just going to look at the raw data. And you know what? I will I will go ahead and take this and go into my old version of Postman. The version of Postman you can actually use without a subscription before they went uh a little bit downhill there. Uh, but we're going to send this, and we'll see this neatly formatted JSON here in my view. And I'm going to scroll all the way to the bottom here. We see that this response should have this metadata block. So, we're going to go back to VS Code here. So, response should be JSON with this metadata block, and this is your cue to continue paginating, getting more data, right? Like this is this is the sign, basically. Like if you see this, there's an next cursor count 30, that means you can go on and paginate this. And then what we can also do here is we can refer to the API documentation. So, there's interactive API documentation, and we're going to look at servers and list MCP servers, right? Like there is there is this. So, query parameters, you can pass cursor directly as a query param. So, I would have like the registry model servers, and I can probably add cursor equals to whatever, right? So, I can just do that. And then we we're going to encode this to request the next page. Use the same endpoint. Just use the cursor query parameter with the cursor value. Go to the next page. All right. So, that that makes sense.

Now, we also probably it's a good idea to get, you know, maybe we can look here at the servers and I wonder if I can get a limited set. So, I can have limit and maybe I can do something like, let's say 10. Actually, let's go to Postman and we do limit equals 10. And so here, what I'm going to do is I'm going to copy this and give it an example of a full response. Like this is what the full response looks like. So, we're going to go here and say, full response looks like this. Okay. Now, you might argue that my prompt here is not optimized because I repeated the metadata part and I've explained it separately, but it's fine. It's whatever. Also, I also want to make sure that I clarify what constitutes a local MCP server and what is a remote MCP server. So, if we look at the JSON here in Postman, right? Like we have a Kubernetes server here that I'm not entirely sure has a repo. I think it's a local server, but it has no indication. So, we're going to skip that. So, there's one that says remotes. So, if there's a remotes, that means it's a remote server. If there's packages, that means it's a package server or it's a local server. Let's see, there's another one that is AI power recipe generation with cookw with, but there's no indication. So, let's take a look here at this repo and see if it's uh remote or local. So, I'm just going to copy this URL. Go here. We have the the server. I'm just going to scroll. Okay, it's it's local. So, I'm going to assume I'm going to make a bold assumption here and say that if there is no indication, there's no packages, if there's remotes for a server, it's a remote server. If there is a packages, it's a local server. If there is neither, it's a local server. If there's both, count as both local and count towards both local and remote. And by the way, I don't know if it could be both. So, for example, GitHub has an MCP server that is both local and remote. There's two versions of it. I don't know if they're packaged as one, but let's assume that if there is the possibility that they're packaged as one, then we're going to keep them like that. Okay, so we have some definitions. So, this logic should aggregate servers through GitHub actions in a CSV file that is then picked up by our web app at build time and used to construct the charts on the landing page. And I do wonder here now, there's a constraint here. So, we have next cursor equals this, right? So, we have we have a good, let's say I can limit 100. This is probably going to return a bunch of stuff. We have the next cursor. If what if I do and cursor equals this good? See what happens. Am I getting another 100 servers? Yes. And I get another goid here. And I'm going to paste that here. I actually do not know how many servers are. There might be a lot. There might be a lot. So, we see packages. Okay. I'm going to keep scrolling. There's a lot. And there's another next. This is going to be the last one. So, we're just going to assume that look count represents the current number of servers that we have on the page, right? So, okay, we actually reached the end of the page. If there is no next cursor, that means you've reached the end. That's that's a good piece of information we need to encode. If you reach a JSON response without next cursor, you've reached the end. Okay. And then the indexing process should be done via a, let's see, should we do a shell script in GitHub actions? Yeah, maybe. Should be done through a PowerShell, PowerShell script because we can we can test it easier on Windows. PowerShell script. Okay, because we want to make sure it's a Windows runner. All right. So, I think we've encoded a number of requirements here that I think is fairly decent. We have some information about because the the bulk of the information really is about the like how do we do the data aggregation from the the endpoint. Uh, and the rest is like it's an X.js based app and with Chad CDN components, we already encoded the fact there should be a static web. So, that should be enough. I think let's try it.

So, let's do this. Let's have it use this context to bootstrap the technical plan for us. It's going to run the script to validate the information we have. We're still operating on our branch. Great. It's going to read the spec. Fantastic. And the constitution is going to ground it, which again, it's it's nice to see these references pop up here because that means it's using all the available context to go and build out the requirements. So, it's going to use the plan template. All right. It's exactly what we needed here. It's great. I love it. I I love the fact that I can just hand off a lot of these instructions and then have the agent go and build this out for me. So, remember, the whole beauty of specit is that it provides the scaffolding. Specit itself for the specify CLI doesn't do anything. You only have the the actual prompt templates. You have the templates for the spec, plan, and tasks, and you have the helper scripts and the constitution. That's kind of it. That's the gist of what the project is all about. The rest is done by the coding agent.

Now, also here, I'm using again CloudSonnet 4 because CloudSonnet 4 is pretty good about writing good docs. Um, I've noticed that again, it could be overeager with code, but when it comes to documentation and putting together the specs, the requirements, the plan, it's actually excellent at that. It's it's a fantastic, you know, tool to keep in your developer toolbox. Now, let's take a look at the plan here. So, it's it's fleshing it out. You have a summary. Let's take a look at the summary. So, it's going to build a single-page analytics dash for showing MCP server growth trends over time. Users can filter between local, remote servers, and adjust time granularity. Data aggregation happens via GitHub actions calling the MCP registry API every hour, storing results in a CSV format for static site consumption. Dark theme with purple, blue, pink color scheme using X.js and shadcn components. That kind of captures it. That really does. It's it's neat. And now I have my language and version dependencies. It looks like it wants to use recharts for charts and tailwind CSS. Let's assume that that is that is right. Uh, let's take a look at what recharts are. So, I've actually never used recharts. I've always used D3, but recharts. Okay. I mean, it's interesting that it recommended recharts. Let's take a look here at installation. And we have recharts from looks like it's from npm. I'm sure just installing random npm packages is fine. Nobody ever worries about that. Um, yeah, there there's there's a lot of contributions here. So, yeah, it's a pretty large project. I've never used recharts. Again, this is going to be an exploratory avenue for me as well and see how well it works. So, but I guess it's a chart library for React. I I know enough about React to build some of the applications, but I do not keep track of all the new libraries that pop up. Like if you you're using a stack and you're comfortable with it, uh, I'd say use that instead of whatever the AI recommends. So, and also, by the way, you again, as I mentioned in other videos, you can change the choices. Like the choices that you see here, it's a markdown file. If you don't want to use recharts, use something else, right? Maybe D3.js is the thing that we want to use. So, I I'll I'll defer it for now. Like recharts is fine. Let's let's see how well it performs and then see what the output will be. So, storage CC files by generated by GitHub actions consumer build times. Yep, makes sense. All these things make sense, and it actually limits you to a thousand data points, which I guess is reasonable. Yeah, you don't want to overload the page and then slow down the browser, and of course, it does a constitutional check. So, static site, responsive design, minimal dependencies, Perf, accessibility, and standards because these are the the the two amendments to the constitution that it created by itself. We did not ask for Perf and accessibility, but it did, and I'm glad it did because something that you have to think about when you're building websites is Perf and accessibility. I think those are important points. So, then it has all the details about the source code structure and the decision rationale. Yep, makes sense. A lot of this is actually fairly reasonable. Now, it we also will notice that it did some research, right? So, it because it did not go outside the box of the LLM itself, it actually just researched within from the training data that it had. So, it's it should probably be enough here. So, it's MCB analytics dashboard. Let's take a look. What's what's what's the research? Static site export. Okay. Some implementation patterns. Alternatives considered: vanilla React. Mhm. Okay. Astro rejected due to additional learning curve and framework complexity. That's a bold statement to make about Astro when we're using Next.js here, but sure. All right. If it it really thinks that the Astro learning curve is higher than using Next.js, really, that's that's the choice it makes, man. All right. But sure. Okay. Let's assume that that's that's the research. So, it maybe thought that like, hey, you asked for Next.js. Clearly, you're not capable of learning anything else. So, okay. So, it has some examples of how the charts are going to work, some PowerShell API pagination patterns for how it's going to encode it in the the script we're going to be using in GitHub actions. And I mean, all this sounds okay, like every hour, like I I'm I'm doing a very brief gut check on this to see if there's anything that stands out that is just like, oh, dear lord, this is bad. And it's it's reasonable. I think for a prototype application that we're building, it's okay. So, this looks good. Area labels for accessibility. Yep, that makes sense. So, it has a research. It has an outline of the data models, right? And use the fields. Okay. Right. For the MCP server that it gets from, I'm assuming it just pulled it directly from the API structure that I gave it there. Server type: local, remote, both. So, okay. It has some also code snippets that it gives an example, and an analytics data point timestamp. Yeah. Total code, unique code. Yep. Yep. Yep. Yep. Yep. Makes sense. Okay. I'm actually curious how it's going to structure the uh actual CSV file because we did not define that layout. We did not define the columns and how it's going to be separated. So, there might be something that we'll need to tweak, and I suspect that the moment you start getting into the CSV parsing, you might end up with tricky situations where the the file isn't parsed correctly. You end up with things where the columns are not properly delineated because a string has a comma and the comma gets misinterpreted. But, okay, it has this. It has a quick start for us that tells us how to actually test this. Install for local dev. Good. Okay, that sounds okay.

So, we we looked through this. Now we need to break this down into tasks. So, we're going to go ahead and use tasks and then break this down into tasks because now we are at the stage where we want to go in and say, hey, agent, go and take all the work that we've done with the spec, the plan, and break this down into manageable chunks that the AI agent can go and implement. All right. So, the agent is breaking it down into the work that it itself will have to go and do. So, we're going to wait for the task to complete. It's going to use a task template again because we have this. We are living on the edge here with our own little branch where we can do whatever we want. It's completely completely not touching any of the main stuff, the empty repository that we have though. So, the damage is contained if things go wrong at a task planning stage. Um, although it shouldn't because the scripts are fairly predictable and the template is predictable. So, we'll see where this actually lands us because there there probably are going to be quite a few tasks that we'll have to tackle. And the thing about it is, once you get to the task stage, once you actually get to the point where the agent breaks this down into manageable chunks, you might notice that certain things stand out. It's like, oh, like you're doing way too much about testing. You're creating way too many tests. For those things, like if if you spot this, you need to go back to the template and then figure out why did it create that many tests? So that next time you run this, you don't have the same problem because again, you might end up in scenarios where the agent is just overeager to do way more than you asked for, and you have to tinker with different models, and because it's Copilot, you can choose those models. You're not bound necessarily to just one specific vendor. So, let's go back here to our task generation process. Looks like it just completed it, and it has some phases. I just keep everything here because this is like a mix of vibe coding and spec-driven, but we just have a spec. Now, let's go to tasks and take a look here. What a generator. We're going to skip the the heading. So, we have the project setup, right? Okay, so the project setup. We have some tests first because again, this got defined in the template. So, we are using tests, which is good to have. Then core implementation. Mhm. Components. I'm curious if it actually has the component for actions. Where is that? Aha, there we go. Create GitHub actions workflow and GitHub workflows. Okay. Yep. And collect MCP data PS1. So, the the beauty of having a PS1, a PowerShell script here is that because I want to run it on my box, and because I'm testing this on Windows, I want to run it on Windows. So, that that's a life hack. If I really wanted to, I could just do a shell script and an Ubuntu runner and GitHub actions, but Windows is fine. And let's see, end-to-end pipeline. Okay. Playwright ET testing framework. Again, this seems like overkill, but sounds good. We are building a web app. Let's do everything that a web app developer would do.

Now, we're ready. I think now we just have to ask it to go and implement this and see where we land. So, we're just going to tell the model, implement the project now. And ideally, it should just pick up the tasks and go from there. Okay, it starts with phase 3.1. And from now on, we're just going to wait for the agent to go and build the initial implementation. There we go. All right. So, the agent finished the work. We use GitHub Copilot. It's time to take a look at the results. And I'll caveat this by saying people make the assumption that when you work on a spec, it's a one-shot process. That you write the spec, you toss it to the agent, the agent produces the results, and there you go. You have the the right output. The reality is trickier than that. You still have to nudge the agent to do certain right things. In our case, it did not parse the CSV file properly that got from the data. Maybe it initially hallucinated how it uh talked to the endpoint that it needed to get from the MCP registry to get the servers, right? So, a lot of these things require nudging, and that actually highlights that the spec process has gaps, right? Like when you initially put the prompt together, when you put the spec together, that means these are the things that were underspecified that you were not necessarily thinking about those. And that's okay. Like it's not that big of a deal. It's not a problem with your workflow or your thinking. It's just that at the time, you did not know that this is the thing that needs to happen. But as you go through the development process, you identify these gaps and then you can encode them back into the spec. So, then when you have the output from the agent, you say, "Aha, now I know that the CSV parsing needs to be encoded properly in the specification so that the next time this specification can be rerun," you get the right output.

But nonetheless, let's take a look at what we have here. So, we have a bunch of stuff that got produced, right? We have our source with uh the application itself, a bunch of uh TypeScript files, CSS files, our about page, all fine. And this stuff that we asked for, we have a data uh CSV here with some of the real data and mock data that we created here. So, this is not necessarily the data that we want to uh rely on just yet, but it's there. It works. I already am running the server here locally. So, let's go to Firefox. And you'll notice that the site looks kind of modern. This is this is nice. Very, very dark theme and right color scheme, and everything is exactly how I wanted it to be. We have a selector for server types, local and remote. We have a time period selector that allows us to tweak the granularity. We have a date picker. We can reset the changes. And we have a very modern graph. This is very nice. I I like this. This is This is neat. Look at this. It It only took us like an hour to build this out. This is This is super impressive. And it has some of the header things that, you know, I might need to change here or actually the footer that, you know, MCP Registry Analytics is not a thing, but it created it anyway. So, we'll need to uh build this out and maybe fix some of the the layout changes. But, let's see if we change the granularity from hourly to daily. Uh-huh. Nice. What if we do monthly? Nice. We have August and September. Okay. And then we go back to daily and we have the results. This is This is really, really, really nice. And if we do a date picker from the 20th. Yeah, look at that. It works. It works. It does exactly what it's supposed to do.

I think it is time for us to go and commit the changes. So, we're going to go and say, commit the functioning website, right? Because now it works. We can publish the branch. We can push these changes and we can seam light up. So, we're going to go and we're going to make sure that we create a pull request here and go ahead and make sure that this merges into main. Commit the functioning website. Yes, create pull request. You're going to see me deploy this live to GitHub pages. Um, so we'll see how this works. It says deploy to GitHub pages. And let's see. I'm going to just going to merge the pull request because I'm going to go ahead and do that. It's fine. And we're not going to delete the branch just yet. But we'll take a look at the code here. We're going to see actions and see what actions do we have here. Deploy to GitHub pages. And one of them is cancel on the branch. One of them is on main. Let's take a look at the logs here and see what's happening. Running tests. So, it's downloading a bunch of stuff. Install the Playwright browsers to run them, I guess. Oh, right. And it's going to run the end-to-end test. This is by the way the most time-consuming part of this entire saga of building this out is making sure that the tests are properly running because what I've noticed is that the the spectrum development process, the templates that we have provided are templates that are very much test-driven. I'm going to cancel this workflow and I'm going to rely on the one that goes on the main branch uh because that's the one that we actually want to work here, which is our latest commit. So, test-driven stuff, not for every project. You don't actually need it in a lot of the scenarios, right? Like if you're building something that is a lightweight prototype, you do not need to build a whole bunch of like TDD scaffolding that exists around your application. For production services, for services that require very much like a monitored environment, you want to make sure that everything is there, everything is correct. Tests work. So, as you start building out your kind of muscle with spec-driven development, you can go back and tweak the templates, edit them out, make sure that things that are working, things that are not working, you can just remove them and add them on an as-needed basis. It's as simple as that, right? So, uh, here we're going to have our website deploying to GitHub pages. Uh, let's take a look back here uh at what we have. And I mentioned that we now have an automated data collection script. So, if we go to workflows, we see data aggregation. So, we have a GitHub action that is supposed to just run the collect MCP data script that we have here. It's a PowerShell script. We're going to just scroll right over to let's see where's scripts. There scripts collect MCP data, which is going to be talking to the registry endpoint. It has all the information that it needs for things like pagination. So, we have all the the logic here, which is kind of nice, right? It has all the the cursor-based page-based parsing, and you can just use this locally to embed the site. So, we can run this, right? So, if I go to uh, let's see, cd scripts, let's go to the scripts folder and let's see what's here. And then we have our collect MCP data. So, I'm just going to do collect MCP data PS1. And notice that it's going to go and collect the data and insert the data into the analytics file. Uh, and then I can, let's see, potentially rerun it again. Uh-huh. And it has the it inserts the data, but notice that it has a bug. We just spotted it. The fact that it just overwrites the file. It overwrites the content and inserts the data, but I just overwrote everything I have. And as I mentioned, because when you work in a spec-driven process, you notice things that just do not work properly sometimes. And that's okay.

So, here we're going to go ahead and ask the LM to go and fix the script, fix the data collection script to not overwrite the CSV file and instead append another line to it, right? Because that's what we want to do. That once new data points emerge, we append them to the file. We do not overwrite the file. And we'll we'll test this out in a second. We'll see if the change works. In the meantime, we can look here and see if our GitHub action is still working. We have the dependencies. It's still working through the installation steps for Playwright. It might take some time, but that's okay. Certain builds can take longer than usual. All right. And then it's going to look at this. And let's take a look. It's going to parse this out. And let's run the script again. It ran into an error, and it found the source of the issue, which is also kind of nice. It that's the part about debugging this. Once you have access to your terminal, the LLM is actually really good about being able to read the terminal output. And now we have the script properly working. It actually appends the data as it should. And as I mentioned, because we spotted this error, we now know what the problem is. So, we got to make sure we need to make sure that this requirement is reflected in the specification. Spec'd for the future, right? Because, and this is where folks might think like, well, hold on, you're talking about a script file. Isn't this a how, not what and why? And kind of, but because we're explicitly talking about the fact that we are relying on GitHub actions, right? Like we we talked from the very beginning that we're relying on GitHub actions to aggregate the data. We also need to be very explicit about the fact that whenever a script is used, the data is appended. It's not overwriting. So, these are the kind of things where uh, right, like now we have a new functional requirement: system must preserve historical data by appending new data points rather than overriding existing analytics data. Great. So, now whenever somebody comes in and tries to essentially add more uh information to this to the spec or tries to rebuild the spec again or build a variation of this feature, this is going to be encoded in the knowledge of that spec document, which is very, very important. It's again, it's an iterative approach. It's an iterative approach. You're not going to get this in one shot.

Now, it's running end-to-end tests, and we have about 190 of them that it created, which is like again, it's okay. It's I certainly wouldn't do it for a prototype like this, but I let it run wild a little bit and say like, yeah, go go do this, and uh, it will go and do this. It it actually is pretty pretty good about being very extensive, and as I said, CloudSonnet 4 can be a little bit overeager about a lot of these things. So, uh, we'll take a peek here in a second and see how it progresses. But in the meantime, I'm going to go ahead and push my script changes, right? Because we changed the analytics data, we changed the script, and we updated the specification with new requirements. So, we're going to commit these changes to our existing branch. So, update spec and script, and we're going to push these changes, and we're also going to have a pull request and merge this into main because, uh, this is the kind of stuff that is important to have. So, we want to make sure that we're tracking accurate data. And we're going to dismiss this. We're going to say create pull request. And because this is a demo and I can do this, I can just merge this and not wait for things to complete. Right? So, I'll just merge. Let's go do that. And one of the things that I want to test here, it's super important, is the ability for me to run the script for data collection because I will run through tests and make sure that it all runs in GitHub actions and tweak that if there's errors. But the most important part is that the data is actually accurate and runs regular. So, if we look at GitHub actions here, you'll notice that I have my MCP registry data collection job. And here I can just run the workflow on the main branch and let's see if it does the job. Let's see if the the workflow that was created for us is actually executing properly. So, let's look at the collect registry MCP data. It's going to check out the repository. It should work fairly fast. It doesn't take that long to run in the script, and then it should just commit that analytics data into the repository, and we should see a new commit in our history. So, very straightforward, not a lot of complexity, and this is a Windows runner, so we're using a PowerShell script, and let's see, commit and push data. Aha. So, now we have an error, right? And we can use this error as a starting point to go back to the LM and say, this is the error in data aggregation. Uh, yeah, in data. Yeah. Yeah. Yeah. This is the the context data aggregation. And see what I'm doing. I'm I'm iterating. I spot things that do not work. And now I go and tweak these certain things, like in this case, data aggregation YAML. Like I'm not going to be necessarily repeating this over and over, so I don't need to encode this in the spec. It's more of a the LLM itself did not produce the right output, and it's fine. So, we're going to go ahead and just recommit this file, the change. We're going to push this, and we're also going to open a pull request because we're operating from a branch, as we always should. And we're just going to create a pull request. And once again, because I'm being reckless with a demo, I'm just going to go ahead and merge it. Right. I'm going to close all these different tabs here that we have for testing. We don't need them. We just have one tab. So, I can go to actions now. And now I can go here and just run the workflow again. It succeeded once because we reran it as a test. And then you'll see that the data collection actually works. So, we have the MCP registry data collection. So, this is great. It is here. The job is executing. Fantastic. It's running, and we'll see the success once we refresh this. I'm just going to go ahead and see what happens. It's bootstrapping our PowerShell script. Our PowerShell script, as always, is the superpower. You just do not write all of that in the YAML file. Do not put every single executable piece in the YAML file. I've seen people put like shove a bunch of bash and PowerShell things into the GitHub workflow file, and that's just a mistake. Just just have them in a separate script so you can run it locally and easily test and validate it without having to go back and forth. Now it succeeded. So, if I look, collect MCP server data, it has all the logs like fetching page 7, page 11, page 12, 30 servers, 15 servers. All right. But let's look, let's take a look at the data, right? So, do we have a commit? Aha, GitHub actions user. We have a chore for update MCP registry data. Let's take a look at the commit. And it did. It inserted the data in the CSV file that we now have and we're able to use for GitHub actions and for our statically rendered site. We see these jobs here now. Uh, along all of the other jobs, we see that the pull request for the actual execution of the site is still running through the end-to-end tests, which can take some time. But the this works, the data works. It is exciting because I can actually see the site that we we we saw, right? Like if I go to our um executable part here. So, let's take a look and I run npm run dev from my terminal. Now outside of VS Code, I can go to my localhost page and I can see the site uh running locally. This is not real data because I have not pulled the main branch. I'm still in my test branch that has dummy data. But you see it works. It looks modern. it has all these servers and uh or I can actually like look, I can split this. I can I can just look at a select graph. I can select these things. I don't have to look at all of them at once. And uh all all of this has been built like within the hour. Like I would have spent at least a few hours putting this together, and with the help of Copilot, CloudSonnet 4, however verbose it is, it actually produced a really nice output that now allows me to very easily track the MCP registry growth and see how the server uh volume changes over time, which is uh what I wanted to do in the first place, and I just did not want to deal with Next.js and all the complexity that comes with it out of the box. I just wanted to build a neat experience, a static site that I can throw in GitHub pages, and it's just going to be there. And by the time this video goes live, you will see it in GitHub pages. You'll be able to click there for yourself and just give me your feedback, right? Like this this is a process that, as I said, it evolves with time. There's no one-size-fits-all. Like, as you are trying this out for your web apps, desktop apps, CLIs, you're going to run into things that don't work. Let us know. Go to github.com/github/spec-kit and give me all the information about what works and what doesn't work, and we'll fix it and we'll make it better. And I will make sure to see you in the next video where we're going to be talking about more development practices. Specs or not specs, we'll see. Until the next one.