2026-07-25 08:00:00
I still vividly remember the day at the Halo World Championship 2025, when Halo Studios announced Halo: Campaign Evolved. New graphics, more missions, and a dive towards Unreal Engine instead of Slipspace. Lots to be excited about!
Naturally, when the game first became available, I just had to get it and start playing through the campaign. Now, despite the fact that some folks can complain about the fact that there is no multiplayer, this was not a major detractor for me - I’ve always been a campaign-first kind of guy.
But if you know me, you also know that I love looking under the hood of the released Halo games - just think of how much time I spent on random Halo API explorations. When I got the build installed on my local machine, the first question I had was “What can I tinker with in this game?”
You can watch the video if you want a more hands-on explanation:
The first stop was, of course, the install folder. Halo: Campaign Evolved sits in your Steam library under steamapps/common/Halo Campaign Evolved, and the moment you open it you can tell what you’re dealing with:
Halo Campaign Evolved/
├── Engine/
├── DigitalExtras/
└── Meteorite/
├── Binaries/Win64/HaloCampaignEvolved.exe
└── Content/Paks/
That Meteorite folder is the interesting part - it’s clearly the codename for the game, and it shows up everywhere (including the REST APIs, where it’s referred to as mtr). The build string baked into the executable spells the whole thing out, if you had any doubts:
5.5.4-2026.06.26.1097863.1-Rel-i343-Meteorite-2606-CU2
Unreal Engine 5.5.4 (I am pretty positive that’s what this is, but it’s conjecture), built on June 26, changelist 1097863, from a branch called Rel-i343-Meteorite. The i343 prefix is also unsurprisingly popping up everywhere - you’ll see paths like Engine/Plugins/i343/BlamEngine scattered through the binary, which is a delightful detail if you are a diehard Halo fan. The classic Halo “Blam” engine (or, whatever pieces of it remain - I have no clue) now lives as an Unreal plugin.
With UE, all the game content lives in Meteorite/Content/Paks, and there’s a lot to unpack (hah!) there. A keen eye will spot two file types:
.pak - the classic Unreal package format
.utoc and .ucas - the newer IoStore container format that UE5 uses for most cooked assetsFor my exploration, I started with .pak files only - that was more than enough, as it turns out. To extract content from it, I used repak from Truman Kilen.
This is a third-party tool, right? Is it OK for me to use it on my machine?
While these tools do what they were designed to do and I have no reason to believe they are in any way, shape, or form malicious, I cannot vouch for their safety and reliability! As with any external project (mine included, by the way), always exercise caution and define the trust boundaries where you want to run them. When I was experimenting with extraction using repak, I ran everything through isolated containers with mounted data folders.
repak needs an Oodle decompressor to do anything useful, since that’s what the containers are compressed with. You can often get the required decompressor library from Steam games that bundle it in the distribution themselves.
The file that I wanted to unpack first is pakchunk0-Windows.pak (roughly two and a half GB in size). Because I saw that quite a few settings in the game in %LOCALAPPDATA% and within its own folder uses *.ini, I decided to intentionally narrow down my search to those files.
One repak list later:
$ repak list pakchunk0-Windows.pak | grep -i '\.ini$' | wc -l
145
That means there are 145 configuration files, in plain text, inside the PAK. Including one that caught my attention right away:
Meteorite/Config/DefaultGame.ini
My hunch was that it contained some default game state that controls its general behavior. Because I have no intimate knowledge of how everything works here, this seemed like a reasonable starting point, so I extracted it.
$ repak get pakchunk0-Windows.pak "Meteorite/Config/DefaultGame.ini" > DefaultGame.ini
This resulted in 27 KB of internal settings. There’s a lot there that I won’t really list here, since it’s mostly irrelevant to what I wanted to talk about in this blog post. However, about two thirds of the way down, this came up:
[/Script/Meteorite.DebugMenuSettings]
bEnableDebugMenuBetaNonShipping=True
bEnableDebugMenuReleaseNonShipping=True
I wonder what this would do? Look at those two key names, but split them into logical parts:
A pretty good guess here is that there are different builds of the game available - Debug, Development, Test, Shipping. The retail copy you buy is a Shipping build. And the game’s own config only enables the debug menu for NonShipping builds.
Which raises the obvious question: if there’s a NonShipping variant of these flags, is there a Shipping one? You don’t need any special tooling to answer that - the flag names are sitting in the game executable as plain ASCII. Point PowerShell at it:
Select-String -Path "HaloCampaignEvolved.exe" -Pattern "bEnableDebugMenu\w+" -Encoding ascii -AllMatches |
ForEach-Object { $_.Matches.Value } | Sort-Object -Unique
That’s a bingo:
bEnableDebugMenuBetaNonShipping
bEnableDebugMenuBetaShipping
bEnableDebugMenuDefaultNonShipping
bEnableDebugMenuDefaultShipping
bEnableDebugMenuReleaseNonShipping
bEnableDebugMenuReleaseShipping
Every build configuration gets a pair - one for non-shipping builds and one for shipping. The config file sets two of them, both on the NonShipping side. The other four, including every single Shipping variant, aren’t mentioned anywhere in the shipped configuration, so they quietly fall back to their default of False. I can probably try and override that behavior.
Because the INI file I was looking at is packaged along other assets, it can’t be edited in place. Now, repacking the container to flip one boolean would likely be possible, but I wanted to exhaust all easy options first.
Wait, wait, wait… Hold on. Why not just repack the PAK? The files aren’t encrypted or signed, so nothing is stopping you from writing a modified DefaultGame.ini back into the container.
I mean - I guess you could? But we probably have a much cleaner path available. The config system is layered - the engine reads a whole hierarchy of .ini files in order, and later layers override earlier ones. The PAK-staged DefaultGame.ini is one of the earlier layers. The last layer, the one that wins, is the writable user directory on my own machine.
For this version of Halo, that location is the following:
%LOCALAPPDATA%\Meteorite\Saved\Config\Windows\
If you’ve launched the game at least once, that folder already exists and already has a GameUserSettings.ini in it holding some of the settings. The game reads and writes it constantly. Recall how I mentioned that I focused on INI files first? This is why.
I’ll call out an important INI formatting rule that I discovered in the process: an Unreal config class reads from the .ini file that matches its config= specifier, and its section header must be [/Script/<Module>.<Class>].
If you get either one wrong - the setting won’t be interpreted correctly and nothing will happen.Because I don’t have access to verbose logs, I couldn’t really tell if something is off until I tinkered with the files and got the setup right by restarting the game a million times.
DebugMenuSettings appeared in DefaultGame.ini, so it’s a Game config class, so the override belongs in Game.ini. Same folder as GameUserSettings.ini.
To make the change, close the game first. Then, create %LOCALAPPDATA%\Meteorite\Saved\Config\Windows\Game.ini and put this in it:
[/Script/Meteorite.DebugMenuSettings]
bEnableDebugMenuDefaultShipping=True
bEnableDebugMenuBetaShipping=True
bEnableDebugMenuReleaseShipping=True
bEnableDebugMenuDefaultNonShipping=True
bEnableDebugMenuBetaNonShipping=True
bEnableDebugMenuReleaseNonShipping=True
Right-click on the file and mark it as read-only, to make sure that the game doesn’t stomp over it.
That’s it - the magic is in. Let’s launch the game!
When you go past the launch screen, you will now see the option to get the debug controls:
See that G Toggle Debug Options at the bottom? That means the configuration took effect. And now, you can do a whole bunch of really fun things.
And of course, you can do some more fancy fancy things, like testing campaign missions or some maps/game variants, that are somehow inaccessible (I haven’t spent enough time digging through this, maybe there is another secret flag).
Now that’s an Easter Egg!
2026-01-26 08:00:00
For the past year, Model Context Protocol (MCP) has done a lot of maturing - starting as a small open source experiment, it now became a full-fledged protocol that is broadly adopted by the industry at large. You can throw a rock and hit something that somehow integrates MCP.
That being said, one of the more peculiar limitations of MCP has always been the fact that you can’t really do a lot with it beyond text on the wire (which is still extremely useful, to be very clear) - JSON-RPC is a nice little abstraction to ferry a bunch of text-based requests and responses. Anything interactive was usually done with the help of, what I would say, hacks, like sending the URL that a user would have to go to to see a visualization of their data or results of some action (think - Playwright MCP post-test reports).
Starting today, though, the landscape is changing - MCP took another leap by adding support for its first official extension, MCP Apps, a project built on the foundations of the work that the awesome folks at MCP-UI and OpenAI have been carefully nurturing.
You can catch up with my demo video to see it in action:
What’s cool about MCP Apps is that you can already tinker with it in Claude and Visual Studio Code Insiders, with more clients on the way!
Here are a few places for you to check out if you want to get building:
API Documentation QuickstartAnd of course, I would be remiss if I didn’t call out the blog post announcing the release as well as the extensive collection of samples that will show you how to get started quickly.
MCP Apps are nothing other than HTML layered on top of the existing protocol abstractions, so the changes for both server and client implementers are fairly surgical. This will also hopefully make it much easier to adopt within the ecosystem.
For those reading who are a bit more security conscious, I got you covered - because apps run inside a sandboxed iframe controlled by the host, developers don’t have to worry about them escaping their container, accessing the parent page, or doing anything nefarious with cookies.
But - and that’s a big one, the real magic here is the bidirectional flow of data. An MCP App can invoke server tools and receive live updates without developers having to spin up separate infrastructure or deal with transport plumbing themselves. Neat!
The MCP Apps extension is, of course, still under active development. If you are still on the fence if you want to help shape the direction of the protocol, now is the perfect time to get involved.
For bugs or feature requests, the team is tracking everything through GitHub Issues.
For broader discussions about where the project should go or how it fits into existing workflows, there’s a dedicated space in GitHub Discussions.
And hey, if you want to take my biased opinion, this is one of those rare moments where the extension setup is still malleable enough that community feedback can genuinely shape its direction. Come help!
2026-01-17 08:00:00
As an open source project maintainer, one of the things that I often need to do, to the surprise of no one, is triage issues. When doing so, I try to rely as much as possible on automation; however, it’s not always available out-of-the-box for some edge cases.
One such edge case is setting issue types in GitHub. If you are not familiar with it, I am not talking about issue labels, but specifically types.
Typically, I’d use the GitHub CLI for this kind of toil, but as it turns out there is no argument available that allows me to set the type. So, I had to look for creative workarounds.
Issue types are entirely owner-managed. For example, in the PowerToys repo (where I maintain Awake), a maintainer can flag something as a Bug, Feature, or Task.
Now, if I’d ask anyone how they can set types for a given issue, they’d probably guess that they can use gh issues edit, but alas that’s not something I can do. Luckily, the GitHub CLI allows me to also talk directly to the GitHub GraphQL API, which offers way more capabilities than the command line tool.
So, I’ll start by querying the available issue types for the aforementioned PowerToys repository:
gh api graphql -f query='
{
repository(owner: "microsoft", name: "powertoys") {
issueTypes(first: 20) {
nodes {
id
name
description
}
}
}
}'
This will yield a JSON blob like this:
{
"data": {
"repository": {
"issueTypes": {
"nodes": [
{
"id": "IT_kwDOAF3p4s4ACCgE",
"name": "Task",
"description": "A specific piece of work"
},
{
"id": "IT_kwDOAF3p4s4ACCgH",
"name": "Bug",
"description": "An unexpected problem or behavior"
},
{
"id": "IT_kwDOAF3p4s4ACCgK",
"name": "Feature",
"description": "A request, idea, or new functionality"
}
]
}
}
}
}
Not bad. I now have the unique id associated with each issue type. But I don’t just need to get the issue types. I need to be able to set them. To do that, I’m once again going to lean on the GitHub GraphQL API, with the help of mutations. The GitHub GraphQL API uses global node IDs and not the issue numbers (what you see in the web UI) for mutations, meaning I need to retrieve the issue’s node ID first.
Here is the GraphQL query that I need to execute from the GitHub CLI:
gh api graphql -f query='
{
repository(owner: "microsoft", name: "powertoys") {
issue(number: 44644) {
id
title
issueType {
name
}
}
}
}'
If all goes well, this is what I’ll get:
{
"data": {
"repository": {
"issue": {
"id": "I_kwDOCv6UO87iZtnQ",
"title": "Bug report run logs",
"issueType": {
"name": "Bug"
}
}
}
}
}
The id value is all I need. Now, I can use the updateIssue mutation to set the type.
gh api graphql -f query='
mutation {
updateIssue(input: {
id: "I_kwDOCv6UO87iZtnQ",
issueTypeId: "IT_kwDOAF3p4s4ACCgH"
}) {
issue {
number
title
issueType {
name
}
}
}
}'
Notice the issueTypeId - this is where I use the relevant issue type ID from the very first step to set the type.
A successful type assignment operation will result in this JSON output in your terminal:
{
"data": {
"updateIssue": {
"issue": {
"number": 44644,
"title": "Bug report run logs",
"issueType": {
"name": "Bug"
}
}
}
}
}
To remove an issue type from an issue, pass null as the issueTypeId in the GraphQL query above.
It’s a bit more work than I’d like for something this basic, but wrapping these queries in a shell script or a custom CLI extension (that’s for another blog post) makes it easy to integrate into your triage workflow. Hopefully native gh issue edit support comes soon.
2026-01-11 08:00:00
Just a few days ago I wrote about wrapping up my latest Microsoft chapter. I’ve spent the past three years immersed in security, and as of last year alone, quite a bit of Model Context Protocol (MCP). That last part is probably eye-roll-inducing to anyone who’s been following me on LinkedIn.
This work serendipitously led me to what comes next. My next chapter is joining Anthropic (yes, that Anthropic) as a Member of Technical Staff.
Before we go further, I just wanted to mention how much I love the work behind Calvin and Hobbes. This particular strip from the very last installment of the comic (published on December 31st, 1995) feels especially fitting for this moment. There’s something different about stepping into a new role at the start of a new year - a blank canvas, much like a coat of fresh snow (which, apparently we’re not getting much of in the PNW this year).
The switch to Anthropic was not super-spontaneous. After a year working on MCP as a member of the MCP Steering Committee and then a Core Maintainer focused on auth and security, I really grew to appreciate the effort that Anthropic was putting into organically scaling what has now become an industry standard for connecting data and applications to Large Language Models (LLMs). I also had a few informal conversations with Anthropic folks, learning about their roadmap, culture, and aspirations.
Then, a chance to work closely with the Anthropic MCP crew came up. The opportunity to help build MCP from inside felt like such a surprisingly natural fit that I did a double take and asked my wife, “Is this even a real job?” As it turns out, it was! It also helps that I’m already a huge fan of the Claude family of models (my go-to for all engineering work), so the decision to go work with folks whose product I am already using practically daily was easy.
Ultimately, the decision to join was grounded in a few core beliefs that I hold:
At Anthropic, my immediate focus will be, you guessed it, on MCP. If you’re already part of the contributor community, I’m sorry, but you’ll be seeing more of me. If you’re part of the broader MCP ecosystem, I am excited to collaborate with you on making the protocol even more mature!
As the world moves to agent-first workflows, I realize that there is so much more to be done to nurture and grow MCP for this paradigm shift. I strongly believe that Anthropic is the place to do it - not just because they created MCP, but because they’re deeply committed to building AI with safety in mind. As agents gain more autonomy and connect to more systems, that commitment becomes non-negotiable.
This career change is a calculated bet on the impact of AI on the world, and specifically on something near and dear to me: software engineering and the need to connect systems to make them work well together (which, as you know, is the whole idea behind MCP). As models become ubiquitous “appliances” in modern software, it will be more important than ever to make sure they interoperate safely, securely, and in a scalable way with other systems, services, APIs, and applications. My mental calculus here was simple: even if I can contribute just a tiny bit to accelerate MCP adoption, help improve its security posture and readiness for more real-world scenarios, there is no better place to do that than at its birthplace.
I am also excited to work more closely with David Soria-Parra, Jerome Swannack, Paul Carleton, Basil Hosmer, Inna Harper, Weynab Maher, and quite a few others at Anthropic who are building out the protocol and the broader agentic AI ecosystem.
It’s hard to put into words how I feel about this change - I am nervous and excited, cautiously optimistic and yet ready to jump in and start contributing. I am positive that working at Anthropic will be transformative, and I am looking forward to both learning from some of the most talented folks in the industry as well as helping steer us to a future where AI is safe, accessible, and beneficial at scale.
Let’s shucking go!
2026-01-09 08:00:00
Three years and a quarter ago, my hiring manager asked me - “How do I know you’re not going to leave Microsoft again if we hire you?” It’s not an unfair question to ask, especially considering that I was going for my third stint at the company. My answer to that was pretty simple, at least from my vantage point - I can never guarantee this, but I will give it my all to build the best product imaginable because I live and breathe developer experience.
Three years and a quarter - that’s how long it took me to decide that it was time to close this chapter of my Microsoft adventure. Today is my last day at the company, and next week I’ll be diving headfirst into a new challenge.
It’s more than a bit of a bittersweet moment, because the team and the role I was in were fantastic. After being there for the past year (the previous two I spent working in Microsoft Security), I can tell you that Developer Division, or DevDiv as folks called it before it got folded into CoreAI, is an extremely fun place to work. I’m not just saying this to be nice - it really is the place to be at Microsoft to ship fast, learn fast, and be on the cutting edge of what developers use every day.
This was my dream org since I joined Microsoft. We’re talking about the birthplace of Visual Studio, Visual Studio Code, C# (and the .NET platform), TypeScript, Visual Basic (that’s what I started with way, way back), and so much more. Could an absolute engineering geek ask for a better place to be?
It’s something I always aspired to be a part of, and through a mix of luck and a whole lot of very much unrelated and very much unexpected stress, this dream became reality in the very first weeks of 2025.
Since January of last year I had the privilege of tackling many interesting problems, like helping figure out the adoption blockers for GitHub Copilot, charting out the path for better authentication and authorization integration in our IDEs (I guess I put my Entra ID knowledge to use here too), building quite a few conference prototypes and demos, training the internal Model Context Protocol (MCP) security muscle, and most recently - launching GitHub Spec Kit, which blasted past 61,000 stars on GitHub. Like I said, this org is lots of fun, and I had a lot of agency to do things that are impactful.
Oh yeah, and did I mention that GitHub Spec Kit is the second most starred repository in the entire GitHub org? Talk about a little experiment getting out of hand.
But as with any career step, sometimes the chutes and ladders drop us in wildly unexpected directions. That’s exactly what happened here. The timing is a bit odd, considering that just this fall I shifted roles, but I knew deep down that the change was something I had to do - at least to try and apply my skills at a different scale. I’ve done moves like this in the past, but this one feels particularly poignant - and yet, very exciting.
I wanted to take a moment in this somewhat long-winded blog post to express my immense gratitude to a few folks who were absolutely instrumental to my career in the past few years and even way before then.
It would be a grave disservice to not first call out just how impactful the work of Amanda Silver is on everything that I did at Microsoft and even outside of it before coming to DevDiv. People might not know just how big of an influence she is on cultural, technical, and product direction in Microsoft’s developer ecosystem - she truly is second to none when it comes to understanding developers. In my eyes, Amanda is the Developer Division. I owe her my position in DevDiv and CoreAI as a whole - she did the most for me of any managers or mentors in the past half decade, and I know a lot of folks who feel the same way. My biggest reservation about leaving Microsoft was that I won’t get to work with Amanda on the same team.
A few other folks that I want to individually call out for all they did to help shape my latest Microsoft tour of duty:
Also, very special shout-out goes also to some of the most amazing folks that I had the privilege of crossing paths with, who more than once helped me beyond what one could even ask for: Julia Kasper, Annaji Sharma Ganti, Tyler Leonhardt, Mandy Whaley, Scott McMurray (Halo Studios), Diviyan Matheendran (Halo Studios), Nancy Anderson, Jeff Carnahan (Halo Studios), Toby Padilla, Mike Kistler, Lutz Roeder, Josh Free, Peter Marcu, Peter Maytak, Gladwin Johnson, Neha Bharghava, Keegan Caruso, Josh Lozensky, Kelly Song, Bogdan Gavril, Ray Luo, Travis Walker, Adrian Frei, Iulian Cociug, Chris Mann, Christopher Scott, Saeed Akhter, Stephen Halter, Stephen Toub, David Fowler, Joe Binder, Paul Yuknewicz, Shayne Boyer, Maddie Montaquila, Pierce Boggan, Maria Naggaga, Ernie Booth, Cassie Breviu, Eric Hollenbery, Hemory Phifer, Matt Ellis, Matthew Reyermann, Martin Woodward, Mario Rodriguez, Chuck Lantz, Tim Heuer, Denizhan Yigitbas, Evan Boyle, and a massive fleet of other Microsofties and Hubbers who I learned from every day.
And of course, shout-out to the Microsoft-internal MCP Security Core Crew - the “deep into everything security” people I’ve been collaborating with in the past year to make sure that we improve the MCP security posture inside Microsoft and outside of it (I think we did a pretty solid job): Barry Dorrans, Alex Sklar, Matthew Henderson, Nazmus Sakib, Stuart Schaefer, Tolga Acar, Diana Smetters, Pam Dingle, and David Parks.
It also wouldn’t be a farewell post without a stereotypical “badge on the laptop” photo - I always found the implied tradition somewhat funny, as if we’re cops handing in our badge and gun.
If there’s one thing I’ve learned in my career - the tech industry is a ridiculously small space. If we worked or otherwise collaborated together, I am sure that we’ll run into each other again many times in the future. Guaranteed.
Will share more on the next adventure soon!
2025-12-14 08:00:00
Well, well, well - as 2025 draws to a close, I thought I’d resurrect an old trend and start writing yearly summaries again. I also went ahead and picked a theme for the past 365-ish days. I can’t help but call this the year of Model Context Protocol (MCP).
Remember when I said that June was the month of MCP? How naive! Little did I know that for me personally this entire year became almost entirely consumed by all things MCP. That was, hands down, one of the highlights of 2025. Not the only one, to be clear, but probably the most significant and impactful.
This blog post is a bit of a reflection on the past twelve months, so if you’re looking for some groundbreaking MCP developments, you will have to check back in January.
What’s funny about this kind of “looking back” post is that I used to do yearly reflection posts just shy of a decade back, and then kind of… stopped. What’s old is new again, and now that the work dies down before the end of the year, I can sit down, brew some decaf, and get my thoughts together.
I am writing this post just having visited San Francisco. I was there for three reasons, all obviously related to MCP.
First and foremost, to catch up with MCP Core Maintainers about transports. Then, to join my friends at Anthropic for the celebration of MCP joining the Agentic AI Foundation, and after that - to deliver a lightning talk at MCP Night 3.0, hosted by WorkOS, who graciously invited me to speak about some new spec developments.
The MCP Core Maintainer meeting was spurred by a strong desire to discuss the future of transports within the protocol. Believe it or not, just because we have STDIO and Streamable HTTP doesn’t mean that the work is done. More on this in a future discussion, but I will just say that there is a lot of work happening behind the scenes to make MCP scale better in production scenarios.
You might’ve noticed from some past musings that when there is a major topic that warrants a debate, MCP Core Maintainers just meet to talk about it in person. Does this remind you of any other open-source project that operates at scale? Jokes aside, we did actually have a fairly productive discussion that I think will be reflected nicely in a future update of the MCP specification (the last one was this November).
Can’t complain about the sunny views we had from the office either.
It’s also worth mentioning that the discussion we had comes on the heels of the protocol maturing quickly over the past year. If you’ve been looking inside our Discord server, you might’ve noticed that there are groups of folks with very extensive expertise in various domains who are deeply impactful when it comes to the MCP design and architecture. That’s a good thing.
We ended up with a handful of “knowledge niches” - pockets of the community that have a strong influence on protocol direction from very specialized vantage points. They help shape such aspects as transports, extensibility, security (this includes authentication and authorization), SDKs, and much more. The high-level maintainer groups are then tasked with shepherding the set of proposals rather than come up with them all alone. That task would be untenable for a project that picked up as much steam as MCP did in the past year.
In between all the maintainer work, a few of us made our way to the Anthropic HQ to celebrate the launch of the Agentic AI Foundation. You can check out the announcements from Anthropic, David Soria Parra, and GitHub to learn more.
Yours truly was also part of a mini-documentary run by GitHub related to this very occasion!
Anthropic HQ is also where I got to meet the famous Claudius, and it’s as cool a concept as you can imagine.
Now, on MCP Night during the same week, I somehow ended up being together with people who are much (much) smarter than me. I mean, just look at this line-up and tell me I am wrong.
My little five-minute talk focused on the introduction of Client ID Metadata Documents (CIMD) into the MCP specification and how it reflects in actual product usage, with Visual Studio Code as the example client. Despite that we only have two well-known MCP servers testing CIMD, it’s so exciting to see it light up in a real app.
Frankly, though, being there was not just about the talk - I got to catch up with so many community members who contributed to the protocol throughout the year. Informal chats like this are a great opportunity to learn about what excites and worries people about MCP. As it turns out - moving away from Dynamic Client Registration (DCR) is what excites people. Go figure, it’s not as intuitive to implement as one may think.
In hindsight, I am so thankful that I got involved with MCP earlier this year. From a little effort to update the authorization specification to becoming a Core Maintainer, it turned into one of the most fulfilling collaborations and project contributions I’ve had in my decade-long career in tech.
MCP, by virtue of its sheer gravitational pull, brought together a massively talented group of people in record time. I’ve never seen anything like this. As I look forward to 2026 and all the MCP things we’ll be building then, I am sure that we’re in for some exciting new developments. And as a neat bonus, I get to spend more time with these folks!
I am also excited to see the adoption and volume of MCP servers grow - we’re at 2,728 indexed MCP servers at the time of me writing this blog post.
One goal that I set for myself for this year is to speak more in public about the projects that I work on. I wanted to join at least two events. Yep, just two - start small. I think I ended up blowing past that by a good margin.
I had a talk at MCP Dev Summit, I presented at Build with James Montemagno and with Amanda Silver, talked about MCP at AI Engineer World’s Fair, gave a couple of talks at Visual Studio Live, went on stage twice at GitHub Universe, was part of MCP Dev Days, joined James Montemagno again for AI Dev Days, gave a talk at MCP Night 3.0, and had to decline a few other opportunities that I couldn’t quite squeeze into my schedule (my apologies if you are one of the organizers - let’s try again next year).
That’s aside from a bunch of YouTube presentations I had the privilege of joining, along with a short interview with folks at The Pragmatic Engineer. Not too shabby for a small aspirational goal.
Earlier this year, I had a somewhat serendipitous change of responsibilities - I went from working in security and authentication/authorization SDKs to working on AI (it’s no longer the Developer Division - just CoreAI). Albeit unplanned, that was a change that opened so many doors for me (hello again, MCP).
This change reinforced my belief that the more often I push myself out of the comfort zone, the better. And you know what, any large-scale change may seem scary in the moment but in retrospect it is the right thing to do.
Through my career, I’ve had several of these moments - quitting Microsoft to join Amazon (although arguably that’s a low-risk jump), going to a startup during the pandemic, and then coming back to Microsoft right as hiring was slowing down.
The change from security to AI was a bit uncomfortable, but nothing like rolling up your sleeves and jumping in to get rid of any remaining jitters. That bet paid off handsomely.
You know how you can do everything for a viral hit and then get crickets? But then sometimes you have a little experiment that you want to get some community feedback on because you don’t want to incubate it internally for too long, and it absolutely destroys your expectations? You know, kind of like my “Seinfeld in Tech” memes?
As it turns out, this year I had an unexpected hit on my team’s hands - GitHub Spec Kit. When John Lam and I launched this project in August, our intent was very much not to create the next big trend in AI-based software engineering. And yet, here we are.
And I know that I will be talking about vanity metrics, but the number of stars acquired per day for that project is still staggering to me, even if it slowed down a bit since launch.
If you prefer to look at repository stars in aggregate, here is what it looks like, all in less than four months:
GitHub Spec Kit also is now the second most starred repository in the entire GitHub organization. Breaking all sorts of internal records with a little “Wonder what would happen?” project.
Aside from the unexpected success of GitHub Spec Kit and the myriad of videos I created for it (you can read about it on the GitHub blog or the Microsoft blog, whichever you prefer), I also:
My podcast, The Work Item, despite being on the backburner in 2025 because of other higher-priority projects still pushed me to release a few excellent episodes. I have bigger plans for it in the coming year.
Despite the busyness with the day-to-day, I very much tried to keep my hands on the keyboard as much as possible - the stuff that I am building is not just about material for blog posts. I find it super important to carve out time to try out new tech, experiment with different programming languages, and feed my curiosity by continuously finding new things to reverse engineer.
I always had this idea in the back of my mind that the best lessons come from either direct experience or someone that is believable and can explain their takeaways in the shape of a reusable framework. An epiphany I had recently, however, is that sometimes this model doesn’t fit the cases where important lessons are gifted to us from some of the sources we least expect, unbeknownst to us until much, much later.
This year, I learned to recognize the growing importance of endless curiosity, unconditional courage, and unshakeable resilience.
Curiosity to me is all about the acknowledgement that there is a lot more out there that I simply don’t know about, but it’s totally within reach if only I get out of my comfort zone. And by the way, it’s not about just tech stuff, which is easy to zero in on as someone that works in the field. It’s about the environment and opportunities around us. People’s perspectives, places, food, hiking paths, books, movies, games, and so much more. Living life in a perpetual comfort zone, within the same constant routine, is not what this is all about.
Courage boils down to doing the right thing and standing up for what is right. This is not always the easy choice, but it’s a choice that must be made to push boundaries. Don’t be afraid to take that next career step you’ve been mulling over. Don’t hesitate to join your friend on an adventure building something because the outcome is not yet known. Don’t sit silent when you see someone bullied or talked down upon. The first step is scarier than the actual possible outcome.
Lastly, resilience to me is about being able to withstand the absolute deluge of unexpected curveballs with grace. This is not about avoiding struggle or pretending that struggle doesn’t exist. For what it’s worth, we all have our moments, but giving up is just not an option for me.
I am looking back at this past year with an enormous amount of gratitude. The opportunities and projects that came my way did so because at some point, someone put their trust in me, and I am incredibly thankful for that. The more time goes on, the more I recognize that it’s always, always about people. Tech changes, trends come and go, but you’d be surprised by just how often you’re going to cross paths with people you worked with a decade ago.
2026 is around the corner, and I am positive it will carry its own bucket of changes and unexpected detours, but that’s to be expected, right? Here are a few things that I look forward to:
And, as my favorite piece of swag from Anthropic says, keep thinking.
May 2026 bring you nothing but all of the best from your list of aspirations!