Video summary
Leslie and Stefan from the .NET and ASP.NET Core teams introduce Model Context Protocol (MCP) as a standardized framework, often described as the "USB-C of AI," designed to provide large language models with context and access to external data across various clients like OpenAI or Anthropic. This protocol offers significant advantages such as reusability across different environments including Visual Studio Code and Copilot CLI, fine-grained control over tool activation to optimize token usage, and the ability to authenticate into private resources. The presenters advise developers to initially utilize skills for natural language processes before transitioning to MCP servers when specific needs arise, such as requiring external authentication or deterministic tooling. They highlight popular implementations like GitHub, Azure DevOps, Context7, Playwright, and Aspire, which empower Copilot to read repositories, access documentation, automate browser testing, and retrieve dashboard logs effectively.
In a live demonstration, the speakers leverage multiple MCP servers to assist Copilot in resolving a weak password validation issue within an ASP.NET Core application. This process involves reading GitHub issues, consulting API documentation, automating form filling using Playwright, and drafting a pull request, showcasing the seamless integration of these tools. The discussion also covers strategies for improving token efficiency by enabling only necessary servers and disabling unused tools within them. Stefan further details the C# MCP SDK 2.0, which supports the latest protocol revisions, session migration over HTTP, and attribute-based tool definitions. He explains that while standard I/O is suitable for local development and debugging, streamable HTTP is essential for distributed scenarios like Docker or Azure Container Apps, alongside features such as prompts for reusable workflows, elicitation for user input, and tasks for long-running operations.
The presentation then shifts to building MCP servers using HTTP transport via the Web Application Builder, contrasting this approach with standard I/O modes and highlighting technical considerations like configuring routes after `builder.Build()` and handling specific HTTP errors. A key advancement discussed is the transition from stateful sessions in legacy protocols to stateless multi-roundtrip requests in the new SDK, which resolves scaling issues by returning `InputRequired` results instead of awaiting continuations. This architecture also introduces improved elicitation patterns where missing parameters are requested via error responses rather than session-based metadata. To streamline development and debugging, an Aspire-based MCP server template is introduced, offering built-in observability dashboards and the MCP Inspector tool for visualizing raw JSON responses, while client ID metadata documents help simplify authentication without requiring dynamic client registration.
Read the full video transcript
So, um, nice to see y'all. I'm Leslie. I
work on the .NET team and I also host
the Visual Studio Toolbox show on
YouTube and Twitch.
>> And I'm Stefan. I work on ASP.NET Core
and the C MCPS SDK filling in for Mike
who retired early. So, that's my excuse.
No. [laughter] Couldn't get him out of
retirement to do this for me.
>> Yep. and we're here to talk about
everything that you need to get started
with building and using MCP servers in
Visual Studio. So, just to get a sense
of the room, show of hands. Who knows
what an MCP server is?
>> Okay,
>> it's the is are you awake question?
[laughter]
>> Who's used an MCP server?
>> All right, cool. So, um yeah, this is
basically going to be a bit of a crash
co. So, if you've never used an MCP
server before or don't really understand
why you should use one in the first
place, we're going to talk a little bit
about that and we're also going to talk
about how you can get started with
writing your own. So, curious, has
anyone written an MCP server? Okay,
cool. Handful of you. Awesome. So, we're
going to start from like ground zero and
we're all going to get on the same page
and hopefully by the end of this talk
you'll feel rare up and raring to go to
write your own.
So, just a little agenda for what we got
going on. We're going to start by
talking about what MCP servers are just
so we're all on the same page as well as
why you should consider writing one.
We're going to do some demos about how
to use MCP servers in Digis Studio
because BS in particular makes it pretty
easy to get started with MCP servers in
my opinion. And uh we're also going to
talk of course about writing MCP servers
specifically using the MCP car SDK
as well as talk about some of its new
additions in 2.0 which fresh out of the
oven as of yesterday, right?
>> Yep. Yesterday afternoon, like 24 hours
old.
>> Yeah. So, still super new. Go try it
out. And uh finally, we'll wrap it up
with some resources for you. Uh so you
can catch up on anything that we talked
about or maybe didn't talk about. And if
we have time or even if we don't have
time, we'll be around to help answering
questions that you got.
So, starting from the top, what is an
MCP server? Do you want to kick it?
>> Sure. Yeah. Um, MCP stands for model
context protocol. So to, you know, a bit
of triviality, it provides context to
the model. Who knew? So it's all about
context engineering these days, right?
Or I mean, we're several was prompt
engineering. We're now in Tuckwin
reduction. MCP can help you with a lot
of this. Um, so there's a lot of
strategies to basically um add custom
functionality to your agentic um, you
know, programs, operating systems,
whatever you want to call them. And um,
MCP is a standardized way where you can
um, write a server in a programming
language of your choice like C and have
it work not just with OpenAI, not just
with Anthropic, but with a whole suite
like basically the entire ecosystem,
right? supports MCPs. Like most people
don't even say servers anymore.
>> Yeah, [laughter]
people get it. And um yeah, because the
before times before there was MCP, it
was kind of a hassle to be able to
connect to a lot of those external
resources and data because you'd have to
know the exact connection between the
client you're going to and the resources
you're trying to connect with. And that
could be different for every single
connection you're trying to make. So
that's not really fun. It's like a bunch
of wires to use the metaphor because of
you've probably heard this metaphor
before. It's like the USBC of AI. And I
know it's super cliche at this point,
but honestly, I think that's the best
way in my opinion to describe it. At
least that's how I remembered what an
MCP server is. Because USBC, it's meant
to be that universal charger that just
works for everything. You only need to
travel with ideally one cable and not a
bunch of different types. With MCP
server, same thing applies. So one port
or one protocol to rule them all. It's
the one ring. So
as for why you should use an MCP server,
there are a couple reasons. Of course,
the biggest one is whenever you want to
attach to external data with your LLM or
co-pilot. This is when you might want to
invoke an MCP server in the first place.
Um especially when it's information that
your LLM isn't necessarily going to be
trained on, such as your personal
sensitive information. Um, but it lets
you use natural language descriptions in
order to access in order to have the
agents discover those capabilities. So,
no additional wrappers or SDKs required
to learn. It's reusable everywhere. So,
regardless of where you write your MCP
server, um, it's really compatible with
most places at this point that support
MCP server. So, if you're writing your
MCP server in Digital Studio, but you
want to use it in VS Code, should work
over there. should work over in uh like
the copilot CLI wherever you want to go.
A lot of the times if you're trying to
install an an existing NCP server,
there's going to be like five different
sections regarding the uh the client
location that you want to install it to,
each with their own pretty
straightforward copy paste instructions.
So, uh very reusable. And finally, you
get a lot of fine grain control over the
tools that make up that server. So you
can choose to enable or disable a subset
of them depending on what you're doing,
which is especially good if you're
trying to save tokens, which we'll talk
more about later because tokens are a
very precious commodity these days.
>> And you don't just yolo all the command
line tools like you actually enable them
individually.
>> I mean, you can, but um that it's going
to cost you.
>> Good. Yeah. In more ways than one.
>> Yeah.
>> All right. So, one of the big elephants
in the room, especially with AI,
anything nowadays, is when do you use
one thing over the other? When do you
choose to write one thing or the other?
So, here's a nifty chart uh with some of
the three main things that tend to
overlap a lot, especially when it comes
to writing or figuring out what to
write, that being MCP, server, skills,
and CLI apps. So,
>> yeah, like this is a question that I've
gotten asked a lot. I read that MCP was
dead about 18 months ago and yet the
usage keeps going up and I keep getting
more bug reports. So, first of all,
consumers are looking for MCPs,
especially um if you're um trying to
distribute internally or externally. Um
the tooling, which we'll demonstrate
soon, makes it very easy to integrate.
Um and um it also offers some features
um similar to Signal R. raise of hands
who who knows what signal is that um
yeah allow you to integrate with the
harness in ways that uh skills and CLI
apps uh cannot and I'll show you that uh
via like maybe if you've heard of
elicitation spoiler we we'll get there
so there are things like that that's not
to say that skills are are bad right
like they're great um when uh you know
it's well suited when you're trying to
describe in natural language um a
process that you want to follow but it's
not as deterministic as an MCP um CLI is
great when you want to script if you
want to pipe output to another you know
agent can write a script using CLI tools
especially if it's something that it's
already trained on but MCP really
increases the discoverability um agents
are well trained on finding using and
discovering the tools available in MCP
servers
>> yeah and I'd say if you're trying to
write something and you're not sure
especially if you should start with a
skill or an MCP server my advice has
always been start with a skill
And if you find that you're reaching a
point where it's unable to do something
that you need it to, such as like
authenticate into a source where you can
get that external data, then maybe it's
time to transition into writing an MCP
server. Scales are usually a lot easier
to write. So just I think it's good to
start there first and then expand later.
as a real world example. Um, one my team
were currently working on a Nougat MCP
server and there was a lot of debate
initially as to whether we should make
it a skill or if we should make it an
MCP server. We opted to go the MCP
server route because ultimately we
wanted to authenticate into people uh
enterprises private marketplaces in
order to be able to handle uh package
updates or security issues,
vulnerabilities, all that. So, one
example,
here's some popular MCP servers. If
you're not sure where to start, um,
here's some that I use on a regular
basis. Um, we're going to talk about
three of these in a demo that's coming
up. But, uh, GitHub's a big one. If
you're an ASDO fan or Azure DevOps fan,
there is an MCP server for that as well.
MSLearn, which lets you access, uh,
MSLearn docs. Azure, which is huge. It
has a ton of tools. Again, a great
example of uh just checking the ones
that you care about. But for Azure, I
love it. Especially as somebody who has
to write custoto queries a lot for
telemetry purposes. It's not a fun time.
That tool literally uh erases days of
work that I'd normally spend trying to
write this crazy query. So, love that.
And if you don't know what custo is,
good for you. [laughter]
Um, Playright, it's a interactive
browser-based automation experience that
is really cool that we're going to show
off as well as Context 7 which is able
to access um API docs and Aspire even
has an MCP app now or MCP server that I
recently tried out. So that's really
cool. If you've ever had to copy paste
console log information from the Aspire
dashboard of your Aspire app before to
give it back to Copilot, you don't need
to do that really with the MCP server
because it just has access to that stuff
now. So that's really cool. So just to
name a couple, but um yeah, they're
sprouting out sprout sprouting up. So if
you feel like there might be an MCP
server available for a given uh like
software that you use or experience that
you use, Google it cuz it might pop up.
So now let's do a crash course on how to
get started with using NCP servers in
Visual Studio.
And we're going to swap over to VS.
Right. Uh hopefully everyone can see my
screen. It's all right. Great. Cool. So
um getting started with MCP servers.
First thing is we want to actually
install some. So fun fact, you can go to
the extensions tab now and select MCP
registries. And this gives you a window
that's similar to the extension manager
if you've used that in Visual Studio
before except it gives you a bunch of
different MCP servers you can install.
It's not perfect. I have filed a couple
issues such that I hope we have the
ability to one day sort these by um
popularity. But if you know what you're
looking for, you can search for whatever
such as like Azure ones and things like
that. Uh, so this is the same registry
as the GitHub MCP registry. So if you
were to Google that right now, that's
the exact same catalog, but not every
MCP server that exists out there is in
this registry. So, um, worst case, if
you can't find it here, just Google it
and it should pop up with its own GitHub
repository with all the instructions
that you need to either install it
yourself or get copilot to install it
for you. But once you find what you
want, so like for example, Context 7,
which I was going to demo in a few,
you'd click install. And when you
install it, that server is going to end
up in a file called the MCP.json file.
And you can see that if you click on the
little wrench icon with all the tools in
your chat. And I mentioned contact 7. So
I can click on the three little dots
next to this one and choose edit. And so
that's what this file looks like. It's a
JSON file that stores all of the
information needed to have Copilot
attached to the different MCP servers.
>> Where is that file? Yeah. So, by
default, this one is in your entire VS
workspace. So, any MCP server that
you're installing like from that
registry window is going to end up
available for every session of VS from
there on out. But if you want to have um
servers be exclusive to a given
solution, you can um two ways, you can
create the MCP.json JSON file manually
and just put it at the root of your
repository. Or you can do uh click on
the tool icon again. You can hit plus
and you can choose to add an MCP server
this way where uh you also have the
ability to choose between it being a
global server or a solution-based one.
So pick your poison. There might be
cases where you want it just for your
the rest of your life or you might just
want it for a specific solution for
whatever reason. So whichever you need
and I think what's also cool about VS
and it's something that VS Code doesn't
really have is that it makes it really
easy to configure your MCP servers
especially if you don't want to engage
with the JSON directly. So, uh, Context
7, for instance, if we clicked on those
three dots, you can choose configure,
and then you get this nice little window
of information such as the general
overview about what the server is. Some
servers are going to need like an API
key or additional environmental
variables in order to connect properly
like this one does. So, there's an
inputs tab where you can put in your API
key there instead of um having to
manually add it in the uh JSON file.
You can also view all of the tools that
make up the MCP server here. And you can
also choose how much you actually trust
the MCP server. You know, authors like
authorization and security is a big
thing with MCP servers in general,
especially because they are essentially
accessing external information that's
most likely going to be sensitive in a
lot of ways. So, we wanted to make it so
that um you're in the know about both
when the MCP server is about to be
accessed and how much you care about
getting those notifications. So, you can
choose to always trust the server if
you're in full-on trust mode if you
want.
So, once you have all of your NCP
servers that you want, then you can
actually use them. So, let's see three
of them in action. So to do that, I have
got this.net web app. Um, it's pretty
basic. It's one page. It's like Finish
Fidget Spinner the game. Or if you've
ever played uh one of those clicking
games like Cookie Factory or something
where you just spam a button over and
over because you're bored at work and
you want to see some fun ASMR pop up on
screen. It's like that. So
>> you'll see.
>> Yeah.
The fun thing about demos live is that
demos are like I don't know. We're going
to take our time.
>> I hope we'll see.
>> We're go really slow.
>> You guys know those idler apps,
>> right?
>> Oh my goodness.
>> It's so so much dedicated to idleness
that it's choosing to be idle when it
boots up.
>> It looks like it's
>> I think it might have. Well, or it's
trying to Oh, yeah. Yeah.
>> Did it do it?
>> Oh, okay. Oh, there we go. Oh, do we
have another monitor hidden somewhere?
>> I don't think so. Oh, wait. No, it's
>> halfway off the screen.
>> I think it was because I was practicing
on multiple monitors.
>> Like alt space, left arrow. The who?
[laughter]
>> Alt space m left arrow.
>> It's fun. Yeah. Let's see if we can
>> Oh, there we go.
>> Okay, here we go.
>> Yay. Success. We only need one of these,
though. All right. So, this is what I'm
talking about. You literally just spam a
button and you get fun little
achievements for however much you click
on it. So, I got one for 10 clicks and 3
seconds. So, I'm a speed demon now. So,
>> pretty impressive. Yeah,
>> you need a macro.
>> Oh, yep. Macros are That's cheating.
>> That is cheating.
>> Yeah.
>> And um now obviously it might take a
while to get a 100% on all these
achievements. So, there might be a point
where we want to save our progress and
come back to it later. So, I've added a
little form down here where you can set
up an account to save your progress.
However, I have an issue where for the
password, I'm expecting it to be a
secure one. So, one that's at least
eight characters, has a capital letter,
has a number, that sort of thing. But
I'm noticing that I can get away with
using one of the worst passwords ever,
and I'm rewarded for it for some reason.
So, as an example, I'm going to use the
password password.
>> Yay. Oh, wow. Isn't that awesome? That's
so cool.
>> Do we allow that by default in identity?
>> Oh,
>> maybe not back compatible.
>> The one password they tell you not to do
in your very first computer class in
grade school. So, obviously, we wanted
to address that. And I already have an
issue in my GitHub repo that's set up to
address this one. So, uh involves weak
passwords. My expectation was as I
mentioned earlier eight characters one
digit one uppercase letter at the very
least and it has to do with a class that
I have in my project called signup
validator which is using an API called
fluent validator.
So it is over and I'm going to stop
debugging.
It's over here. Fluent validation. And
so I'm probably going to need to add
some code here in order to make that
password a little bit more secure.
So, there's a prompt that I've set up
and I'm going to walk you through it
because it's pretty long, but it's going
to use a several different MCP servers
to address this problem. The first thing
it's going to do is uh take a look at
that GitHub issue that I just shared
revolving around the leak passwords.
You'll notice that because I'm using the
uh it's going to call the GitHub MCP
server. I don't even have to link to it.
It just has access to my repository. And
even if I didn't have it open right now,
I could just say go check out my
achievement unlocked repository and look
at that issue and go uh help me address
that issue. And even if it was a private
repo, this one's public, but if it was
private, the um MCP server could also
access that as well. So um that's one
good example. And you'll notice, I can't
highlight it unfortunately, but my mouse
is next to the tool call that it just
did, which was
Oh, I just lost it. But it basically
said issue read. And the second thing
I'm having it do because I want the
co-pilot response to be a bit more
grounded. I want it to go take a look at
that fluent validation API documentation
to make sure that what it's adding is
correct and up to date. And
>> that's the context 7 server. Yeah,
that's the context MCP server or context
7 MCP server. So, it made a call there
and you can see one of the calls here.
It's MCP context 7 resolve library ID.
And so, it just added two more lines.
And then finally, the uh last MCP server
that I'm going to be using is Playright,
which is a browser automation, and it's
a fun way to be able to test out
functionality. So in this case, I'm
telling it to run my app again and then
try that same form fill out behavior and
see what happens. And hopefully the
password is handled. So I didn't uh
click on anything. I'm not touching the
keyboard. I am now because I want you to
see the the progress that it's going to
do. But playright is now going to do its
thing and uh act like it's the user in
this case and fill out the form. So, I
can see next to in the copilot chat that
it's filling out the form and it chose
to use a password that doesn't work.
So, that's good. We're not automatically
getting rewarded with a bad password.
Not that capital P password one is any
better, but it's a step in the right
direction for sure. Uh, so it just
entered that stronger password.
>> Here's where I'll promote ASP.NET Core
in 9. identity added pass key support.
Pass keys uh prevent fishing password
one. So you could uh maybe try that.
>> Pass keys are the new password
>> next iteration.
>> We should file an issue on that.
>> I will.
>> So once it's done that um you can see
it's making a lot of tool calls related
to playright right now. And it's also
really cool because the playright MCP
server can take a screenshot of
everything that happened and send it
back to co-pilot who can then tell me
what's up and what what the status is.
And finally, once it's done all that,
I've also asked it to draft me a PR
based off of this off these changes and
everything that it did.
So, it's doing its thing.
So, it says that the good old password
was rejected. Capital Password one was
accepted. We got some more work to do
after that. And then it's going to draft
the PR.
But pretty cool, right? Very cool. And
yeah, I mean it shows you kind of some
of the more popular MCP servers like
GitHub, Context 7, and Playright in
particular. I normally run that
>> headless so it doesn't interfere with
me, but it's great for the demo.
>> Yeah, I I use Blot because I'm I'm a
very visual person, so I like and I
don't always trust Copilot to be doing
what it says it's going to be doing
behind the scenes. So I like that it can
call the playright MCP server to
actually run the behavior I'm telling it
that I want to check. Um cool. So in
that case it looks like the PR was also
created. I can link to that. Yes I do.
So there it is. And I like having
Copilot make my PRs because they're a
lot more detailed than I could ever come
up with sometimes and it's
[clears throat] a lot faster. So there
we go. That is three MCP servers in
action. Pretty cool stuff. I love my MCP
servers. So, now we got to talk about
the other elephant in the room before we
proceed into writing MCP servers, and
that is how to use MCP servers
efficiently. Also known as how to save
your freaking tokens because my
goodness, they are they're going away so
fast. Um, so MCP servers, they can take
up tokens, which is why I think the
biggest things to remember, especially
if you're just using MCP servers, is to
enable the servers that you need. So if
you're working in a NVS for a given
session and you know you're going to be
spending a lot of time in a repository,
probably want to turn on your GitHub or
your Azure DevOps one. Um, if you know
you're not going to be using Azure in
any way, shape, or form, maybe disable
the Azure MCP server. The reason for
that is because um Copilot anytime you
give it a prompt, it's going to be
looking through all of the enabled tools
and NCP servers that you've got, which
eats up a lot of tokens, even if 98% of
them are uh irrelevant. So, you don't
want it to do that. So, uh on top of
that, when you do have the servers that
you need, if you find that some servers
have a ton of different tools, then you
might want to consider turning off the
ones that you don't plan on using. So,
for example,
GitHubs does have a lot. It has 47
tools. So, if this is a time where it's
fun to explore and check out all the
different tools you can use, and if
there's ones that you don't foresee
yourself using anytime soon, then it
might just be good to disable them. The
good news is is that with each new VS
update, a lot of NCP servers are being
added by default, but they are disabled
by default. So, you're not going to be
hit with a surprise token bill um if you
choose to go that route right away. But
it also means that you need to go
through that to uh that tools window and
make sure that the ones that you want
and the ones that you don't want are
enabled or disabled accordingly.
Um other than that, I think just the big
picture beyond that is again make your
prompts as specific as possible.
Ideally, it's better to get a specific
list returned than a list of everything,
which again can eat up a lot of tokens.
So, those are just some good ground
rules to use when you're uh using MCP
servers, especially, but also goes with
writing MCP servers. It's definitely
something to think about. Like for
instance, if you're writing an MCP
server where you have one tool that
returns all the data, it might also be
good to have a tool that has that
returns a subset of the data. So yeah.
All right. So that is using let's talk
about writing.
>> All right. My section I saw the hand
though. Um, we will have questions at
the end, but if there's anything
interest
like so you're saying
to like
future earlier like
select
like these Please.
>> Okay. So the question being can you have
a scenario where MCP servers are
accessed for just like a given workspace
instead of
>> like sub solution.
>> Is there a way for your tips to save
tokens not be such a manual process?
>> Oh I see. Yeah. So can some of that uh
selection be automated? Yeah. Good
question. Um, currently not really. I
that is a deep wish in my heart and I
hope it happens soon. I know like stuff
like auto the auto tool is coming into
place on like the VS code side as it
relates to models and stuff and I hope
that can get extended to other tools
like the MCP server because yeah, you're
right. That is very annoying to have to
go through and uh enable disable for any
given situation. And I wish it would be
I wish it could get kind of smart about
knowing what's relevant and what isn't.
So, good question. And also, I think
that's worth sharing in the developer
community. Um, just like as an as an ask
yet, which that's going to be my if you
guys give um good suggestions for
things, a lot of my advice would be to
write it in the developer community. I
promise real people, including myself,
look at it and tell your friends to
upvote it. Like, I'll upote them. Like,
email me after this and I will upote
that idea especially. So,
>> stop brigading if your friends are real
and they want it. Um, [laughter]
>> sweet.
>> All right, so on to writing MCP servers.
So now we're gonna talk about how to
write MCP servers in Ruby. No, I'm just
kidding. C. I am the lead developer of
the MCP C SDK. Not the C MCP SDK. Oh,
sorry.
>> Oh, I just wanted to full screen it
again.
>> Oh, yeah. Make sure we're full screen.
>> There you go.
>> So, um, yeah. So, we're just going to
give you some brief intro as to what it
is. Um and uh as we mentioned just
yesterday we released 20 of the SDK that
corresponds with the 20260728
protocol revision which is the biggest
protocol revision MCP has had to date.
Not many servers or clients support it
yet but our SDK does by default as do
the other tier one SDKs um right now. C
is one of three um or I think Go might
so it might be four. So there's Python,
TypeScript, C and maybe go probably go
and uh that's based on a conformance
suite that um you know the protocol
maintainers work on. Some of you might
have heard that Anthropic made the
protocol originally convinced a bunch of
other companies like Microsoft and
Google to jump on board. So it has broad
compatibility and then um donated the
project to the Linux Foundation. So now
it's the Agentic AI Foundation. um we
have representation on like the core
maintainer um board. I'm in the
transport working group. Um so uh we're
involved in like shaping this protocol
to a lot of extent um partly because
they want to make sure that SDKs have
good support for these uh new features
and the focus um recently um with both
the SDKs and the protocol itself is to
move from a kind of stateful
sessionbased model which is um you know
very um designed for like a single
process lifetime. One of the common ways
of uh using MCP servers are standard IO.
Um and the other common way is HTTP. Um
Leslie just demoed both of those for
you. So when you want to use standard
IO, right, that's council right line,
council read line. This is where Visual
Studio is launching the server for you
as your user. So, Playright standard IO
only way it's going to work unless you
know Playright wants to spend money
running browsers in the cloud or
something and then it might have a tough
time uh accessing local host without a
dev tunnel. Just easier if you run
things like that locally. Um on the flip
side like context 7, if you're going to
access an external resource anyway, um
you don't want to have to download
everything locally. Um you might as well
just go straight to the source. That's
an HTTP based u server. Um, for the most
part they have similar capabilities. But
one thing that was really dogging MCP
server developers using HP transport
particularly at Microsoft was um what
happens if like in the middle of the
session a server gets recycled um and
you want to continue working now like do
you know in the C SDK we had some
features which would allow session
migration but that required extra work.
it requires like an external store. Um,
and HTTP which uh this transport is
based on um is generally known as a
stateless protocol. Like one request uh
doesn't affect the other even if they're
on the same TCP connection. Windows off
notwithstanding. We pretend that doesn't
exist. Um you know obviously um you know
there are some things where you might be
using like client certificates where
there might be some state share between
your requests but generally not. And now
MCP built on top of HTTP um has no
protocol association between requests
which means that if a request gets uh
like roundroined uh to another server
sorry went backwards. Um things will be
dealt with pretty well. So we'll get
more into that later. I have a fancy
diagram but let's just start with like
the most basic thing you can do with an
MCP server. And this would be a tool. um
a tool you can think of a lot like
controller action, a minimal endpoint.
It's a request response um like a post
request for the most part. Um unless you
um mark your tool via metadata as like
readon and item potent um you should
expect that tool calls might do
something um destructive.
>> And a lot of the time it really can be
as simple as just a method that you'd
write in any other program. Like in this
example, it's just a basic echo method.
But the C SDK for MCP is very
attributeheavy. So you can literally
just add an MCP server um MCP server
tool attribute to the top and it's a
tool. Voila. So
>> yes, and um we're going to get to a
Visual Studio naturally and show you
this in a project and we'll show you how
you can wire these all up. But the
attributes are definitely the primary
way for specifying this kind of
metadata. But um C offers very low-level
APIs as well. So you can call um MCP
tool.create with uh whichever metadata
you want. So it's very good for writing
dynamic tools and stuff as well. Though
client support tends to be a little so
so if you know tools start changing
underneath you and so forth. Um some
people have tried it but unless you're
writing your own client which you can
also write with the C# SDK not part of
this. Um maybe don't rely on that. So
tools um so here you see um a
description is a pretty important part
of each tool and normally um we infer
the name uh a lot like you would in a
controller action or whatever from the
name of the method for your tools. Um,
but you can specify that via
>> Yeah. Um, and and I know descriptions,
they're technically optional, but we're
going to tell you they're mandatory.
Like if you if you want co-pilot or
whatever um LLM client to do what you'd
want it to do, which is invoke that tool
like the way that you want most of the
time and you want it to be more
consistent, it's really important that
you come up with a good description. You
can even have co-pilot write it for you,
which probably makes it even stronger
because now it knows what you're talking
about. But if you leave out the
description, you're kind of playing with
chance a little bit, unless your um
title of the tool is really freaking
good and you're looking out that day.
So,
>> all right. Um and then also um aside
from tools, it's not the only thing in
MCP. Um you can also support prompts and
resources. So resources are like what's
used by context 7. um instead of taking
arbitrary parameters that can be JSON
serialized and objects and whatnot um
where you're parsing a URI string um and
then you're just returning the resource
often from a file system you might have
a mime type so you could return you know
an image
JSON Excel document whatever um and then
prompts are um parameterized um kind of
uh workflows that you often give to the
LLM and they're in the clients that
support it um often invoked via slash
command um and then you can select your
prompt and then um much like tools it
takes parameters but instead of um
giving you just like a a result it tells
uh the agent like how to do you know a
common workflow you can kind of think of
it a little bit like mail merge in a lot
of cases um and then elicitations um I'm
curious has anyone used elicitations
does anyone know what they are. All
right. So, this this is where we're
starting to get into advanced MCP. Um,
this is now the only fully supported
server to client request. So, we're
doing something that HTTP normally can't
do. Um, so normally when you're trying
to take input from an agent, you just
specify a parameter. You can supply
descriptions for those parameters via
attributes and then the agent will give
you the parameters you need. But
sometimes um for things that are
important um you don't want the agent to
guess what the user might want. Um you
might want to give the user a specific
set of options or prompt them with a
text box. Um so you know that they
entered that detail. Um and that's what
elicitation is for. Um in the past um
since this was built um on standard IO
uh or stateful uh HTTP requests which
had a session um the responses to an
elicitation request um would basically
just come as a JSON RPC response um as
uh from the client to the server over
the standard I IO transport um or just
you know we would send a response in an
issue request, which was like really
unwieldy. Um, and it would have to um
come to the same server, and we'll get
into that in a second, but I made this
uh macro a while back. Um,
kind of shows you um how I think uh most
people look at MCP
>> like it's a lot. When in doubt, you're
98 99% of the time it'd be writing
tools. I think prompts are nice from an
enduser standpoint because you probably
best know the best ways that your MCP
server and its tools are going to get
invoked. So if you figured out the
magical unicorn prompt that works for
you every time, why not share it as a
prompt for your end users to use too?
But
>> y and I didn't go into sampling or
roots. If we have time, I am more than
happy to just know that it is obsoleted
as of yesterday. You're on a 12-month
clock. Um and not many things is
supported to begin with. So it
>> it's really run away there.
>> Proves the point I was trying to make.
Um and then yes, HP versus standard IO.
Um I kind of um ran this a little. But
yes, um the big benefit of standard IO
is it's simple to set up. You don't need
to have a process that you manage
running all the time. Um but and it
allows access to local resources. Um but
it can be harder to distribute. Um and
it's a more difficult threat model
especially if you like don't fully trust
the MCP server. Um also off um if we
have time for that we'll show the ooth
flow. Um but um either way um you know
streamable HTTP basically means that you
know compared to a CLI where you might
have to manage tokens and stuff
yourself. You can just rely on Visual
Studio to manage the access tokens and
stuff for you. Um,
>> I I'd say with uh standard IO versus
HTTP, I think back in MCP's early days,
it was pretty easy to just say start
with standard IO, but honestly nowadays,
like between some templates, one of
which we'll show you in a sec, and just
MCP m starting to mature a bit, it's a
lot easier now to get started straight
up with streamable HTTP as your option
of choice. Um, so don't feel intimidated
by HTTP, um, like I was back in the day
because I think it's gotten a lot more
accessible since. And I think as you
alluded to, Stephen, like, um, it's
really great for scaling to a lot of
clients. When you start to think about
publishing your MCP servers in
particular, standard IO is great if you
want to publish to like Nougat. Nougat
has its own MCP server section and
that's also the main pipeline if you
want to attach to the GitHub MCP
registry in particular. Um, but if you
want it to be in a Docker container or
in an Azure container app or something
like that and um scale it that way, then
streamable HTTP is your go-to.
>> All right. Um, and then talking about
some more MCP features, um, there are
also extensions. Um, two of the primary
extensions are known as tasks, which are
for super long running tool calls.
Basically, we won't focus on that too
much for the VS perspective, but maybe
for more of your longunning agents that
could be cool. And then MCP apps, which
allow your tools to basically return
HTML. Um, and it can be interactive. You
can have JavaScript. Um, and this can
um, help you visualize the output
instead of just having the agent
summarize it text or hope that it
produces a good visualization for you.
Um, you can produce the visualization
that will be shown directly to the user.
Um, this is something that's supported
in VS Code. We um, but we think it will
um, be added to VS uh, if you give us
enough feedback maybe if you like it.
All right. Um, but in the meantime,
let's just do some demos.
Writing
some C# MCP servers.
>> Nice transition.
>> Super good. All right.
All
right. So, I have this VS Live MCP demos
thing ready for us. But the first thing
that I want to show you is just how
simple uh the project uh new template is
for MCP. So Visual Studio, if you have
uh the .NET workload installed um
provides an MCP template out of the box.
You can see that I've tried this a few
times. We're going to create MCP server
3. Sounds good to me. um and um gives
you a nice little readme that shows you
how you can edit that MCP file. So, I'm
going to start building
and trying to find where this executable
ends up. But in the meantime, here is uh
the entire um program CS
and um this is using the model context
protocol package on uh Nougat and uh I
updated it at some point. Oh, this is
the template. The the rest of the
project is uh updated to use the 20
release. Um fortunately, um all this
code works. uh most for the most part we
retained backwards compatibility
um even if we do upgrade to 20 um but
not if you use some esoteric features
I'll say like tasks um which I mentioned
is for those long running tool calls
previously so this is a uh using the
hosted package so you can see that it's
um depending on you know extensions
hosting which is where host create
application builder is this gives do a
web application like builder so DI and
logging uh in particular but uh it
doesn't have you like host ASPET core
web server um with Kestrel and um but if
you don't like DI or logging which I
mean how how could you um then you can
also use the core package and you know
there's an alternative flow where you
can go um MCP server factory um
create async um
or this is using an old package but it's
MPC MCP server.create async. So um with
this
server I'm going to copy that path right
here and I'm going to use the
uh
add custom MCP server. So that was the
other option, right, when Leslie was
showing you how to add a thing from the
registry. So here I'm just going to call
this random. I haven't even shown you
the tool yet, but you can guess what it
looks like. It's in random number tools.
Um, and uh, for the command line, I'm
just going to pass in this path and it's
MCP server 3.exe.
So Visual Studio is going to launch
this. So
>> global,
>> one thing to note, what about that being
global?
>> Or you're keeping the MCP server global?
Yeah, for now. Um, so like you can
launch this MCP server under a debugger.
Um, it's not going to be that helpful.
So like all this output, right, you can
say all right, the server is reading
messages. Um, it's expecting me to
basically send like the tool listing
calls and the tool request via the
command line here. Um, and you can see
there's some logs about the, you know,
server stream transport reading
messages. Um, but if I actually want to
load it in Visual Studio and debug
this tool, which is very uh exactly what
we showed you before, right, where you
have the MCP server attribute. Um, here
we're just allowing you to optionally
support uh minimax parameters. Um,
defaults work. Um, and then we're using
our shared random number generator. So,
if we load it, which it did fail to load
um probably because I put in the wrong
path,
which is a common thing um when I start
with the
>> I do like that it has the um error icon
though
>> like on the actual tool to tool icon so
you know.
>> Yeah. Um,
so if we go to edit instead of
configure, um, you can see that I just
copied twice, which was my mistake.
All right,
there we go. AI actually figured that
one out hopefully. Um,
all right. And then we can just re hit
that and it's like, all right, perfect.
Now it's running but it's not under
debugger. So what do you do? Um well one
is you can use the HTB transport which
we'll get to later. But second um you
can attach to process. Um these days we
actually you know can have that
executable there that you can search
for. Um so we don't have a million. Um
but you do have to run it. So is it
enabled?
>> It looked like it was. Yeah. All right.
Oh, I need to zoom way in on this. All
right. Give me a random number from
100 to 200 to show that I didn't use the
defaults, for instance, but it would.
Uh, and at this point, Visual Studio
will say it's calling this and it needed
to get the the listing. Um, now I'll
zoom out again.
should have maybe set that to uh trust
so I won't have to click that every
>> I don't know I mean random numbers are
pretty untrustworthy
>> dangerous yeah I mean was that actually
um you know resistant to quantum
computing it's like the same thing
>> 103 is a pretty thorough number I don't
know
>> all right so and then of course you can
now see that it's running and if we were
to add break points and stuff you can
see what the parameters are and so
forth. So go again.
So that's one way to do it. Um
and breakpoint. Cool. And if you've ever
used attached to process, that was not a
big surprise to you. And then of course
I
will go back to the demos that I had
before.
>> All right. And um yeah, so like it is a
little tedious to set up debugging with
standard IO. I mean, attached to process
has gotten a lot better over the years
and VS um if you've been around with VS
for a while, you probably seen that
window evolve positively in my opinion.
So uh yeah, because it used to be like
half the processes were all just called
net exe and
>> yeah.
>> Yeah, good luck. Yeah, I found that
reattached a process typically attached
to the most recently launched one that
that was kind of a crapshoot.
>> Um, all right.
>> So, we could talk about the HTTP Yes.
>> route a little bit.
>> Yes. So, this is what we're showing with
this Fireworks demo um which combines
the HTV transport but optionally still
supports snare standard IO. So, it's
possible to support both in the same
app. This is just reading uh the command
line parameter. Um when you're using web
application create builder by default, I
don't know if you know this, but um one
of the configuration sources is the
command line parameters. Um so MCP
transport which I have defined in a per
solution here. Um I have both standard
IO and HTB. And in standard IO, you
know, you pass the arguments and you put
in that mode. But for this purpose, um,
to make debugging easier, I'm just gonna
launch the Fireworks server under
debugger. Um, gonna make sure that once
it's going, we have a
uh Oh, yeah. Okay. We'll see what that
is.
>> My popcorn ready.
>> Yeah. All right.
What's What's a demo without some side
byside browser windows and single art?
Okay. So, this is running in the default
HTTP mode since we didn't pass an
argument in for that. And it's listening
on this 5399 URL. Um, this primary URL
is of course serving regular HTML. But
if you're going to the MCP endpoint, you
can see that's not a normal 404. That's
a a 405.
Um, which means uh does anyone know what
a 405 means actually? Okay, I I'll
answer for you. It's method not allowed.
Um, so MCP expects post request and the
browser is sending a get request. So
that's what's going on there. Um, so
we're added some signal R. Uh, and you
know, we're adding singleton static
state, you know, like you do in demos.
Um, and then, um, you know, this server
shows you, um, kind of more of the
features. We'll make this public in a
second but um unless you do like add
tools from assembly um this with tools
is important. So even though you are um
using the attribute um for fireworks
tools here MCP server tool type um
unlike say MVC controllers we don't
automatically scan the assembly for
everything with the attribute and this
is primarily due to native AOT. um we're
trying to make sure that if you're not
using some of the tools, we properly
trim them and this uh reduces your
executable size and so forth. Um but if
you do want to scan everything from your
assembly, you can call with tools from
assembly and we'll do that. Um that's
not a trim safe API.
>> So it's pretty similar to like when
you're registering components like in a
web app, right?
>> Very similar. Yeah. Yeah. So this is
just you know building on top of
builder.services. Um this time we're
using a web application builder instead
of a host application builder. Um, but
we're running the MCP server in some
app. So, if you're running in standard
IO, you call with standard IO server
transport like we did in the project
template you just saw. I might have
brushed over that a little bit. Um, but
in this mode, we're running with the
HTTP transport. And then the last thing
you have to do um is it's not enough in
HTTP mode to say that's the transport
you're using. You also need to configure
the route. And typically in an ASP.NET
Core app, you configure the route after
you call builder.build. build and that's
what's happening right here. So you can
call mapmc um if you want to you can add
route parameters there and stuff and
read that in your MCP server tools with
the HTB context accessor. Um but yeah so
let me
make sure
>> also you just used a bunch of HTML
to get like this result right?
>> Yes. So, I mean this of course um or
maybe I shouldn't say of course, but um
when we're viewing the website directly,
this is using our normal um static files
middleware um that you know returns this
index.html. Um it's using signal r so it
knows when the um fireworks start and
it's uh actually written using raw
websockets. AI is pretty good at reverse
engineering the signal protocol. So I
could just inline everything into um one
HTML file. But this also makes it
easier, right? Because this is an MCP um
app as it's called. It used to be called
MCP UI. Um which this tool um returns
the HTML as a resource. So let's go back
to full screen really quick. So you have
this UI colon resource that's um you
know returned over whichever MCP
transport you use. This as noted can
work in standard IO. So even though this
is returning HTML um it can return HTML
as a resource over standard IO. And um
on the chats that support it like VS
Code it will show in line. Um and here
you can see that we're setting a special
man. Do I need to use like magnifier
there with for the tool tip?
>> Oh gosh.
>> Um
let's see. I'm really bad at using
magnifier.
>> Wait, I think I know it though.
>> Oh, there.
>> All right. See, so you can almost see
it. Text HTML profile MCP app, right?
So, this is specifically for MCP. And
then our implementation of this is just
a resource instead of a tool. Let me X
out of that. Hopefully that will just
zoom out once I do. Um,
this is instead of an MCP server tool,
it's an MCP server resource that
responds to requests for the fireworks
stage and then returns all the HTML
text. Um
so and then the tool which launches the
fireworks
is uh using a API that is in an
extension package um which is the um
model context protocol extensions.app.
So if you look at the dependencies
whereas before we had uh model context
protocol
period which depended on like ancient
versions of core and stuff you remember
the sounds was like zero points only uh
that here um we have uh you know model
context protocol.aspnet ASP.NET Core. Um
so if you're doing the HTB check based
transport um you are using ASP.NET core
uh for the server. Um in very very early
versions of the SDK we had an HTV
listener based API and Steven Toe made
us remove it. He's like Kestrel um has
the the hardening which is true. It's
certainly um if you're running an edge
server you want to be running Kestrel
and not HTB listener. Um though HTB
listener can be useful for some local
scenarios. Um and it would be possible
to write your own transport using the
transport pluggability using that. Um
but it's not built into the SDK. All
right.
Firework show.
All right. Might be able to get some
text. Let's make sure we have this
loaded because I probably do not. I'm
going to do the HTTP one since we're
running that under debugger. Um,
zoom in again.
And the agent might be smart enough. It
might know why it's launching fireworks
because I am in a VS Live demo project.
>> So spectacular. So here it's showing me
since I still have it prompting me for
every single tool invocation. Maybe
that's a little unnecessary exactly what
the parameters are going to be to my
tool that's returning this HTML site.
Um, one thing to note about the tools,
right, is I'm injecting a single iHub
context. That's like one of the benefits
of using like the host and model is you
get the I so you can include any
services in the parameters. Um and if I
service provider is service says that it
exists that's where we'll get it from.
Um otherwise um we'll deserialize the
parameters that are passed to it. Um so
in this case we have the title, the
theme, the intensity and the finale
message um all seen here. All right,
we're gonna build something brilliant.
Go and then boom. Y. Okay, so [snorts]
and that's using SignalR to um so
everyone sees the same thing. Um if this
had MCP app support, you might see two
of those. Um all right. And then one
other really cool feature in
this
BS live demo thing is elicitation. So
you guys want to see what elicitation
is? Let's go. Um, so this one is another
standard IO only server. No web
application builder. I'm not going to
bother trying to debug it. Um, but in
the past kind of the way you would think
about elicitation is I'm just going to
show you the legacy first. Um, so inside
your server tools, you can add all the
metadata. This is the readonly item put
in open world. These are all
standardized as part of the MCP
specification. So this will help the
host know like maybe what to prompt
users for. Like if they allowed readonly
um stuff only then you know it wouldn't
have to ask before um doing this release
planning. It's going to help us plan a
blue green deployment of source. All
right. Um so in this case um this takes
two parameters directly from the the
host or the agent or the client which is
the application we're about to release
and the version of that application. But
for some important questions like our um
target environment roll out strategy
um how much we want to initially roll
out the percentage and um at what error
rate would we want to roll back um that
I want to ask the user. I don't want the
agent to just guess at that. So um we're
going to make sure we have this server
loaded. This is already in the
repositories like local nougat uh or
sorry not nougat.mcp.json.
So I'm just going to load the stateless
release planner. So in this particular
scenario since we're using the 20 SDK
which is stateless the thing that breaks
is this await. So, we're in the middle
of the tool and with the um latest
2026728
protocol that was released yesterday,
um
as an SDK maintainer, I can't make this
code work anymore because for this code
to work, I need to have the elicitation
response come back to the same server
that made the request to to run the
continuation. Um, and with the new
version of the protocol, there's no
longer an MCP session ID to basically
track um, you know, which requests and
response go together. So, elicitation
will show you quickly what it is. Um,
is
yeah,
help me release.
All right. And since I don't have that
many tools loaded, I think we'll figure
that out. Who uses source.net? You guys
all net developers. There's been some
recent.
[laughter]
>> Yeah, Tanner has done some great work.
Um, you know, including more of our
libraries, Aspire and stuff all in that.
All right, so it found my tool. It's
applied only those two parameters that
are actual parameters to the tool
method. And I'll allow that again. And
then the next step is kind of the
interesting part, right? So, this is
where it's asking me, not the agent. Um,
how do I want to do this? So, I mean, I
always go straight to broad. I don't
know about you. I hear blue green is
pretty good. Um, fortunately, I don't I
don't deploy services. I work on
libraries. Um,
>> and then initial roll out percentage
like 1% that seems like pretty tame. Um,
but I have no bugs. So if there's like
more than 1% of errors.
>> Uh
>> do you did you have copilot submit the
PR2?
>> Yeah.
>> Yeah. [snorts]
>> All right. So um in the legacy version
of the protocol this is what that did
and this response. So this is response
would be sent um with a new HTTP request
if it was using HTTP. Um and uh boom and
it planned released and that actually
did update source.net. No, I'm just
kidding. Uh, it just responded with some
text that said it would, but that was
mostly to show you, um, you know, you,
you saw as I shared the, you know, uh,
multiple choice questions that it gave
from your, uh, single select, you know,
enim schema. There's also the number
schema that takes the the numbers. So,
basically allows you to, um, provide a
specific form with specific, uh, inputs
to the user. Um,
>> we just decided to use an SAT word for
some reason. Elicitation.
>> Yeah,
>> this is like followup or
>> I don't think I knew what I barely knew
what elicitation meant. Yeah, I don't
know. It does sound like an SAT word.
All right, so I said this was the legacy
way of doing that and that this doesn't
work anymore. So, okay, what's the new
way of doing it? So, the new way of
doing it is called multi- roundtrip
requests, and that's the code we're
really running um with the 20 SDK, and
it still worked with Visual Studio. Um,
and basically the key insight here is
that if you're in a stateless server and
you don't know if the server that asked
the question is actually going to get
the response, maybe if you ask the
question, you should just return an
error and say, "Come back to me with the
the full request plus this extra
information I need." If it's another
server that ends up getting the new
request, it has the original request
copied to it, so it effectively knows
what to do. And um so in this particular
case
um instead of awaiting an elicitation
async um
you
send a oh there's me trying to put in
vin things. Um
okay so you basically return an input
require result. So in this case you have
the same schemas right that we saw
earlier and I'm too zoomed in but
instead of awaiting that as part of an
elicit async request we return it
basically as an error. So you see that
we have this result or alternate and uh
until we have basically all the input
that we need um we return an error
result which is like send us this
request again with these inputs uh and
then no matter where that goes um we um
can handle that. And then there's also
the ability within these multi-roundrip
requests to provide a string
um that
basically carries state between those
requests. Um I will say that in this
particular case we're just doing like B
64 uh encoding and decoding like from B
64 string. Um, this is fine if you
understand that a user can like modify
the state naturally. Um, if you don't
want to allow that, I recommend using
data protection if you know what that
is. That's what underlies like
authentication cookies and stuff so you
can encrypt the payload. Um, and it's
pretty easy to use in ASP.NET Core. Um,
all right. So, we that that's the the
end of the the demos I needed to give.
So, I can go back to the slides. Oh, I
well I have one more demo actually.
>> Oh, of course.
>> Aspire.
>> I needed to get and and the inspector,
which is very cool.
>> Yeah. So, I don't know how many Aspire
talks happened uh at VS Live yet, but uh
here's another blurb about Aspire
because Aspire is cool. And um Maddie
will be mad at me if I don't talk about
Aspire for five minutes. But uh I'm
talking about Aspire because we talked a
little bit about um the kind of tedium
that comes up with setting up debugging
especially for a standard IO based MCP
server. Um and I feel like HTTP is
certainly better to hook up, but it
still requires
some steps. And I got frustrated one day
and thought maybe it would be good to
like aspire my MCP server uh one for
that reason to make it easier to debug
too because I get access to all of that
good um orch orchestrating stuff. So in
the event I want to expand on it later
like adding a database or a cache or
something that's easy to hook up. and
three, because it comes with the lovely
observability dashboard that I can use
to view pretty much every metric and
console log happening while I'm in
development mode. So, I then turned that
Aspire MCP server into a template, which
I will link, which I've linked at the
end of this talk. But here's what this
looks like in action in case you're
curious. And I did not even Oh, well, I
have it right there. So, it's just
called the Spire MCP server app.
And I'm gonna keep the name as is.
>> Is this built into Visual Studio?
>> This is not built into Visual Studio. So
go to the I have a link to my GitHub
repo for this. Uh, and it's pretty
straightforward to install. It's just
and then it's just like a net new
command after that. But once you have
it, it looks a lot like the existing MCP
server templates that we have except
there's an appost. And again, you can do
this manually. So I before I did a
template I just added an at post um
class and that contains a couple main
components that we're talk about. One of
course is the MCP server itself and
we're also attaching um telemetry using
open telemetry to it which is why we
have the HTTP health check and also
something called the MCP inspector is
the other thing. The MCP inspector has
its own Aspire integration. However, you
can use this completely separate from
Aspire. Um, it's an npx call. It's like
npx at model context protocolinsspector.
But if you don't want to do that,
understandable. It's like outside of
your net mode. Um, that's the other
reason why I wanted to make this
template. Um, and I'll show you what
that does in just a second. So, um,
first things first, if you're unfamiliar
with Aspire, it is a really nice way.
It's a polyglot framework that lets you
easily orchestrate all the different
components that make up your application
without needing to know how to attach
each one individually. And with it comes
its own observability dashboard where
you can view um console logs, a
structured version of those logs,
traces, metrics, etc. Um in addition to
that in this template, it comes with two
main resources that we put together. The
first being the MCP server which is
currently running in 7200 and that
inspector that I was talking about. So
if I click on that, this is I think a
great way to debug your MCP servers um
not just with breakpoints but also
visually like if you just want to
quickly see what raw text is being
returned by your MCP server across your
tools, your prompts, your resources,
whatever else is making up your server,
this is a great dashboard to use. So
you're saying you don't just wait for
the agent to make the right tool call
like we were doing in the demo.
>> Yeah, that's sometimes it can take a
while, right? And sometimes you want to
skip that middleman. You don't care
about the formatting just yet. You just
want to see the raw footage and this
lets you do that. Now, if you were to
use this inspector by itself, like
outside of Aspire or outside of this
template, you'd have to manually set up
this connection by yourself. It can be
kind of annoying, especially if you
don't know the uh the URL in this
example right away. But with the
template, it automatically sets that up
for you. So you don't have to configure
anything. You can just hit connect and
then you get access to your tools. So
because I didn't do anything to this
template, by default, it comes with the
random number method that we showed
earlier and you can run it and just get
some good old raw JSON. You can check
out the history of the tool call. Let me
expand this up a little bit.
Can zoom in. Yeah. And you can see
exactly what's being returned
without needing to worry about
formatting and things just yet because
maybe you don't care about that.
>> So the real reason to subh prefer the
HPV transport you get to use it with
this Aspire template.
>> Exactly. Not to I guess
>> the Aspire to launch it Visual Studio
launches a
>> Yeah. And again what's great about this
is like it's set up through Aspire. So
you got the app post that it's
connecting to. Hate your break points.
go go for it as you're playing around
with um this NCP inspector. And um
there's also different categories. So
we're using tools right now, but if you
have a um like elicitations as we demoed
earlier, prompts, resources, you can
check all of those out here in addition
to all of the built-in Aspire tools and
Aspire functionality. So really cool. Um
yeah, and I've linked the template at
the end of this talk, which speaking of
which, we are reaching the end of this
talk. Thankfully, [laughter]
>> it was been a long day. So, um Oh, did
you want to
>> Yeah, you know, if I had thought about
the order more, I would have shown this
slide when talking about why we went
stateless. Um so, this is the problem
that um a lot of hyperscalers run into.
Amazon, Google, Microsoft, everyone was
clamoring to make MCP stateless because
um being forced to basically make all
your clients reconnect just because uh
you know you scaled your servers or you
took one down is a bad experience. Um so
by making the uh HP transport stateless,
right, by doing the multi-round trip
request thing that I showed you, which
is a little harder, it's a little easier
just to be able to away instead of like,
you know, B 64 encoding your state. The
upside is that it's way more reliable.
Um, it's way easier to scale. No matter
whether or not the request goes to
instance B or C, you're never going to
get a session not found error, which was
a big problem. Um, with any older MCP
server that wanted to do elicitation in
particular, um, I think that is or or a
lot of us think um, who've been working
on MCP that's a reason elicitation
hasn't been as popular um, as it might
be. So now that um this can work
reliably um without session affinity
which is always kind of a best effort is
is a huge win um
so yeah um
kind of the spark notes version on this
one.
>> Yeah.
>> Yeah. So I mean 2.0 is out in the wild
as of yesterday. We talked a lot about
the stateless core which is probably the
biggest addition right
>> and um yeah we also talked about multi
roundtrip request um off
>> yeah so in off the big new feature um is
uh client ID metadata documents so one
of the things that make off hard with
MCP is that you have native clients um
connecting not to just the server
they're designed to connect with but any
server um and if any of you have ever
set up OOTH with a native client, you
know that there's typically a a client
ID and a client secret and then you have
to configure the application in Entra to
um register it and this ends up uh being
hard when you're trying to support any
uh client that supports MCP. Um so with
client ID metad uh metadata documents um
doesn't require your authorization
server to support what was previously
required which is dynamic client
registration which was this whole flow
to basically get a unique client ID um
and client secret. Then you could do
what's known as like the authorization
code flow with PKC. Um now um we can uh
easily support um basically any client
um with any server as long as you um
follow the provided um client ID
metadata document and
um how much time do we have?
>> We've got like two minutes. That's why I
was like Spark knows version.
>> Yeah. So there's a Sparks version.
>> I love going deep. Um so anyway um this
is supported by the C# SDK and Visual
Studio. So and VS Code. This is not
something that like you need to go to VS
Feedback for. Um it will pop open a
browser um ask you to log in and then
Visual Studio will manage the access
token for you. Um one thing to note is
um anyone can naturally impersonate any
client. They can't impersonate any user.
So, and this is kind of true with native
clients in general, like um there's, you
know, we can't ship Visual Studio with
like a secret. Um, and with the client
ID metadata document, there's no secret
that says like I for sure Visual Studio,
but you do know whoever's connecting to
you is like really that person. They
just might be using their own hacked
client or whatever. But, um, that tends
to be good for most scenarios.
Um,
cool. Um,
>> all right.
Yeah. So, that concludes our talk. We
talked about a lot of stuff and some
that we briefly touched on but didn't go
into full detail. So, uh we've compiled
a bunch of links uh for you to check
out. If you scan the QR code, um it
takes you to a website called URList.com
and it's got all of those links just um
concentrated in one spot so you don't
have to hop around to remember where all
these are at. Um, otherwise you can just
type in the URL.combs-mcps
servers to get access to all this. So
this includes the stuff that we demoed
um or demo apps that we use,
documentation, the official anthropic
documentation, the C# SDK for MCP and
more. So uh please do check out those
resources.
And um last but not least, um I hope you
enjoyed this talk. We um and if you
enjoyed it or if you didn't enjoy it,
[laughter]
please complete the survey. Thank you.
>> Thank you.