And Yela, it has been five years since I've been trying to invite you every time,
there is some reason, part of it is to blame to your British governments.
Part of it to yourself, part of it to me, I don't know.
Now let's blame the British.
I've been trying to get you on my stage for five years now, and it's finally happening.
Yay.
So glad to hear.
Thank you.
And this will be our actual first AI talk of the day when probably our only one.
Oh, wow.
That's rare.
Which is remarkable.
Nanna, you will work now at Google to make us of the amazing AI Gemini,
and you're talking about how to use MCP when you are writing go,
well, sorry, when your AI is writing go for you.
Excuse me.
Okay, everyone.
So, I'm the Nella Petrus Alayek.
I'm a developer-relation engineer.
It's kind of refreshing to see a conference that you don't have so many AI talks,
but as you can see, I need to talk about one.
So, before I get started, who here knows what an MCP is?
Okay, this will be so easy.
Amazing.
So, in this talk, I want you to first, I'll do a brief introduction,
just to get things started and talk a little bit about motivation.
I'll probably, because most of you are aware, I won't spend too much time playing
what MCP is.
That's not the important part.
And then I want you to go to the meetup feature, which is talking about this experimental MCP server,
which I call go doctor.
Discuss a little bit of results and best practices,
I learned along the way.
So, a little bit of all of myself, so I'm based in UK,
and the botanical origin from Brazil.
So, if you find my accent a bit weird, that's the reason.
That's also the reason why my brains have that this time of the year,
because winter.
So, anyway, previously before being in that row, as a back-end date engineer,
currently obsessed with AI, this might be an popular opinion in this room,
given the composition of this house.
But my reason is, I've been 20 years in industry,
and I cannot stand writing yet another crowd API.
That's the simple thing.
I find it super refreshing that I have different things to do now.
That's the reason.
So, if you want to talk about other stuff during coffee,
or anti-games and men cats are always my favorite subjects.
Okay, terms of introduction, it's very brief.
I just want to invite you to think about this for a moment.
We are entering the year of known deterministic software engineering.
I've been thinking this for a while,
because why is known deterministic?
We are asking Asians to do the code first.
And you might not get what you want.
So, we're using to have tools that say,
I will write this code, I'll compile, and yeah,
either works or doesn't work, but if you compile again,
either works or doesn't work again, the same result is deterministic.
But if you give the same prompt to a nation,
you do not have any guarantees that this code will be exactly the same.
This is what I'll talk about on the deterministic.
And there's a podcast from Martin Fowler,
and the pragmatic programmer. He talks a lot about this.
I recommend you to listen to that.
But I added a starter. There's a reason.
Are we really getting into the known deterministic software engineering now?
Or should remind us that human beings are known deterministic?
And we've been writing software for a hundred years now.
Yeah, probably not that long.
But so the point is, we as human beings,
without we have our teams, and sometimes they say, yeah, do this.
And then some people go, oh, build, go test.
Go link, deploy, and everything works well.
And then next time you do the same thing and go build,
forgot to run the test, deploy, and then test a broken.
So this is the known deterministic experience.
So we try to give tools to humans, like CICD,
to have deterministic outcomes.
When thinking about agents, that's the thing we need to do.
Agents are known deterministic.
How can we improve the response quality?
We need to give them deterministic tools.
That's the message here.
Other starter, yeah, there are a lot of exceptions
because I don't want, I'm very non-commitable to the things I say.
But the thing is, yeah, not necessarily all the tools
they're going to give to our agent will be deterministic.
But the idea is to reduce the degree of freedom of the agents.
So it don't derail that much.
If you know you're going to do go build, go test, go link, deploy.
Do not give the agent the chance to think.
Give the tool that does build, test, link, and deploy.
So that's the baseline.
So if you've got this from this talk, this is everything
you need to know.
But let's see a little bit more.
So model console protocol.
I will not spend too much time on this
because most of the people are aware.
It protocols, standardized, how to provide context
to tools and resources to LLMs.
It's a built by initially banned traffic.
Now it's on collected by some organization.
Building blocks, tools, prompts, resources.
Tools are the things we give to the models
so they can count, interact with the world.
Prompts.
It's a matter of you storing a prompt template
and server size.
So you don't need to remember that.
You can.
And depending on the client, they will access in different ways.
I use a lot of Jim and I say live.
Use cloud.
They usually map the slash commands.
For example, resources are for reading data.
So they have all the credits.
I'm going to only be focusing on tools for the stock.
And since this is the goal that we're only
doing, most important thing in each node.
There's an official GoSDK for MCP.
Honestly, I was thinking about what should they put in this line.
You're always good enough.
This is amazing.
It just works.
There's nothing to say.
It works pretty well.
So go doctor.
What is go doctor?
So we need to go back a little in the past.
So not to early 2000s, but just six months ago.
I was starting to learn about MCP.
And this was the generation.
I was talking about playing.
I just joined Google at that time.
I was playing with Gemini 2.5.
And I was actually trying to use Gemini CLI to create
MCP server.
And it was so frustrating.
Because so many things happen.
So yeah, use this.
And it gives you a row and it doesn't read your row.
I want you to use this package.
It doesn't read it.
Go do something else.
Oh.
And I want to use this package and say,
Oh, yeah.
Okay.
I'm going to start hallucinating all the APIs.
And say, I said, blow the hell.
What's going on?
So I started designing this.
We say, okay, we need to fix that.
And so the goal is to instead of having generacles like
write files, edit files.
I don't know.
Any other run shell command.
I want to give specialist goals.
I wanted tools that knew what goal was about.
And I also could add some intelligence to it.
So the goals, reduce hallucinations, improve quality,
talking efficiency, response time, out the good stuff.
And this was the first toy came up with.
Which might sound silly, because you're one shell command away to run
Goldock.
Like I wanted the model to have an easy access to your documentation.
So my hypothesis was, if you just read the damn docs,
you would not hallucinate this that much.
Right?
And actually this worked pretty well.
So I made a distinct wrapper in the Goldock and gave to
Gemini to those five at that moment.
And it started working well.
So that was very inspiring.
And notice, Gemini 3 is much better at doing this by default.
It doesn't really need this kind of tool.
Because if you try to do something in Gemini 3,
it will automatically think, oh yeah,
I need to read the documentation.
We will run the shell command with Goldock automatically.
So it got much better.
But let me show just a very quick demo here.
So show what is the kind of experience.
So I have docs here.
Let's call G3.
This is just an alias to Gemini's ally with a Gemini flash preview.
I'm using some model here.
And I can say, like here, read the docs for,
let's see, let's try something.
Goldock, Goldock,
Gemini, for example.
And this will call there.
So here it is.
Simple as that.
Call the read docs on the Goldock.
The recipe server.
And why is this, is this better than running a shell command?
It kind of is because if I do the same thing,
Goldock, Google,
GoLang.org, the GenNI.
It will complain that no module was installed.
And at that point, you need to say, oh, yeah, by the way,
I need to do go mod in it, docs.
And then I need to say, go get, you got the idea, right?
And then I can call Goldock.
So as soon as I tried to make a tool,
that it was more easy for the model to use.
So I've tracked all this.
I create a temporary directory.
And initialize a fake module, download the thing,
and then read the docs.
And this is where I'm going with the stock is,
the more you can automate those steps and make it
friendly for the model, the better it will be.
So I'm not going to double too much on this.
So this was the first tool.
And then it thought, oh, yeah, what else can I improve?
You know what?
The code quality is not where it is.
Not idiomatic.
We are a gold developer.
It's a love idiomatic, right?
And so I thought, and if I just write my code with the model
and say, review the code now, it's kind of like,
you're giving the key to the jail for the benefit.
Like, he just wrote the code, so it will say, oh, yeah,
this code is amazing.
So the idea is to give to a second model with zero context
and just like one problem and say, evaluate this.
And then you have like a more unbiased view.
And this was also fairly successful too.
And I say, oh, yeah, okay.
I feel like I'm into something.
So what else can I do?
What else can we improve?
And I got to start playing with it and say, yeah,
the replace tool, like editing file is very brittle in nations.
They hallucinate things that are not there.
They have white space problems.
They need to do typos when they write stuff,
like some weird formatting issues,
hallucinated dependencies, sometimes they build,
but they break the test or they fix the test,
break the build or whatever.
And so the effect of the code is called so many things.
The more I use the more I've seen those patterns.
So I start creating a tool for it.
And I made some early experiments.
And because you know,
the name came from GoDoc at R and say,
GoDoc, oh, yeah.
But I also have the figure of the doctor at all.
This is cute.
So let's create more tools that are deducted to teams.
So I created like scalpel, scribble,
because you know,
doctor writing is ungrittable.
Endoscope.
And this was very cute conceptually,
but it's terrible for the model.
Because it looked at the scalpel.
I don't know how to use that.
I use edit file.
So quick lessons learned is that you need to sell the tool to the model.
You know, you need to convince it to use the tool.
So and a scalpel was a very precise tool,
because I thought, you know what?
This replacing doesn't work.
I want to give you line and columns.
So from this line,
this column added this to this line,
this column didn't work.
It could not simply do simple column math.
The doctor time naming didn't work.
If the behavior is too similar,
I had a simple file edit tool.
It never used because, oh yeah,
I have replaced.
I don't need to use.
I'm building tool.
I'm familiar with my building tool.
So I'll not try a different tool to that.
And if you don't do much more than just running a show command,
this is very hard for the model to decide.
But this took me months,
because I would create a tool.
Now my Q10 CPU server and start coding and say,
oh wow.
And all this results were pretty empirical.
You know what?
I need to be more professional in this thing.
So enter this experimentation era.
And this is, in my past,
when I used to be a data engineer,
one of my favorite projects was a recommendation system.
And we did a lot of AB testing.
And the idea of how AB testing is like,
you'll have a massive amount of data.
So you can start comparing.
Oh, it's alternative A, better than alternative B.
Can I really say that if I add gold author to my agent,
is it better than not having it?
Remember, like the models are known deterministic.
Even if you give it,
and this is, I love doing this when I do the demonstration.
Because sometimes the time, if I hear,
I'm doing one demonstration.
If you choose that time to not do what I wanted to do,
then I'll leave you with a bad impression, right?
So I build this, which I call 10K,
is like in this experimentation framework, this open source.
And the idea is, I had building blocks
that I could compose and create my experiments.
And this experiment will run end amount of times.
So I can have a decent sample
and start doing a statistical analysis on top of it.
This is a bit more easier to see,
and I'm going to show the UI in a minute.
So the idea, everything started with scenario.
For example, create a hello world app.
This is my scenario.
Then I'm going to create, I have a few configuration blocks
that are, for example, this is an agent with Gemini tree.
This is an agent with Gemini tree, plus go doctor.
This is an agent with Gemini tree, plus go please.
And so on.
So these are the configuration blocks.
And I create the experiment and place with my alternatives.
And one alternative is associated with certain configurations.
For example, here, if I look, this is the UI.
Sorry, I'm not a front end developer.
This everything was bi-coded here, because I don't know.
I wouldn't know JavaScript.
So here I have a bunch of agents that have one is hard coded
for Gemini tree flash, the other hard coded for a pro.
This one is the original one with nothing.
You know, no model is specified.
I have a bunch of special system prompts.
If I want to add or remove, have some special context files.
Settings, if I want to disable the core tools.
If I want to enable preview features,
only show enable, no other tools and so on.
And based on this, I have a bunch of scenarios as well.
Like for example, the scenario I'm using the most is this
create a recipe server to official go SDK.
And this scenario has basically a prompt.
And it has some assets.
This one starts from scratch.
So it's just a prompt.
Some environment variables and I have validation criteria.
I cannot hear like I want a link.
I want to test. I want to run this commands.
And it creates this part of the acceptance criteria of the prompt.
So this is what I'm going to basically run the agent.
Run the acceptance criteria and validate.
If they have passed all the criteria, that's a success overall.
And if you look at the templates, let's get one that's this one,
go to the MCP server.
So I have alternative one is my control.
I have Gemini CLI, Original, no custom features.
But then I have the go to the MCP as a second alternative.
And this I have an option.
They're configuring the MCP server.
I can add other stuff here as long as it's configured in my library.
I can add an extension on another server.
Like go please for example.
And so on.
So this is the idea.
And whenever I run an experiment, I get this nice UI here.
So for example, this was an experiment
I was comparing go doctor with the default alternative.
And you see, the build of statistics is that I can probably see here that,
oh yeah, the default only was successful 62% of the time.
And go doctor was successful 76% of the time.
And I can say, oh, go doctor is more successful.
No, it's not.
Because it doesn't have statistical significance.
But the average duration has three stars of statistical significance.
This means that this is very unlikely.
This is due to random noise.
So in this case, yeah, it's 30 seconds faster, roughly 30% faster.
Using go doctor, this version of go doctor, which is an old one.
And here have some determinant analysis where you can see.
Oh, because go doctor uses marked edit with a significance of roughly 4%.
It's as likely faster because of this too.
So this is the kind of analysis you can do.
Yeah, so I don't tons of experiments.
And what happens?
So yeah, oh.
By the way, that, that, that, this architecture of 10,
I'll get the experiments back in a moment.
Or I would like to say that this is the architecture of 10,
but right now it only works in my machine.
And there's a reason for that.
It's because the front end and this one then I just show this running on cloud run.
This work amazing in the experiment that is called SQL works amazing.
Everything else is working on storage and go doctor is running as an MCP server in cloud run.
But I have running to a nasty bug on the runner part that every time I call go model needs it crashes.
I don't know why I need to debug this.
It will take a while, but the concept was really nice because you can have cloud run both for service and for jobs.
So the idea is for each run for, so you have an sample size of 50.
I just trigger 50 different containers and so do your job and collect the data.
So at the moment, if you go to the open source repo, you only find the local version.
This one is working progress, but I'm getting there.
Okay, so I showed one of the experiments that was just showing, oh yeah, go doctor is kind of faster,
but not necessarily more precise.
But the idea is, instead of just guessing what I do is, I analyze my experiments,
I'll serve it the model, I'm just typing some stuff and see, oh yeah, this model is struggling with go bond.
What two can I design to help with this go bond problem?
Then I develop my hypothesis.
I'll create the two, run the experiment and say, you know, run this 50 times and run away.
So I don't need to wait for two months doing this.
I'll just run this, then I analyze this experiment.
Did I find anything that statistically significant?
Did I actually improve the flow?
Yes or no, run it and repeat.
That's the whole point of this framework.
So a few results.
I end up coming up when a new generation of tools and remember the selling, the thing to the model is important.
So everything, I have a new tool, now I'm calling it smart.
Because, oh, this is not just me, this is smart read.
This isn't just edit, this is smart edit and so on.
So this is kind of, but also you need to tune the, the MCP instructions and the description of the tool as well.
Never do a simple operation.
So I'm always combining several operations in the same row.
I won't show a few of them in a minutes.
Return additional context every time you can.
So you end up spending more context window as a tradeoff for quality and speed, which end up leading to less context use.
So you kind of preemptively show doing things in one more thing is in one turn.
That's the goal.
On failure provide hints for self-correction.
That kind of like, you know, oh, you try to change this line.
But did you actually mean that line and you give the hint back to the model?
Or did you try to import this package?
But actually the packages you have available are these ones.
So lots of things like that you can do.
And yeah, and the whole point is reducing the degree of freedom.
So a few examples of tools, practically needs.
This creates a project and a path initialized folders, downloads out the dependencies,
and when it finished downloaded the dependencies,
return the goal doc automatically for the model.
So I kind of force, every time you get a new dependency,
I force you the documentation.
So you can, you have no opportunity for guessing.
It's much read.
The idea of smart read was to create a tool that will simulate the hover featuring IDs.
So you get the typing information as well.
There is no easy way to give typing information,
they treat everything as text.
So the idea was to show the file,
and then have additional context session in the bottom that says,
oh, by the way, if you have create user type,
by the type user is defined as X.
Again, add more context for reduce chance of destination.
It also added a syntax check with the goal parser just to make sure,
oh, yeah, this is a valid goal file or not.
Smart edit is the one that I added most things,
because this I was playing too much with the replays tool
in Gemini, Celli, and Scanality.
So first thing, because we have goal format and stuff,
I added a normalization of white space before matching.
You know, get rid of all the white space.
And match only the content, because if you are hallucinated tab or a space,
then you break everything.
I also added some tolerance for typos with edit distance.
So you use 11 time distance to up to two distance,
two characters you can replace at will.
And this is fine, because it will try to compile with breaks anything,
it will fail.
And a bunch of more things like to, yeah,
run automatically, go format and go in parts,
and prevent saving if introduced like a syntaxer,
and add this hints system or say, oh, by the way,
you did it.
I didn't find the thing you are trying to replace,
but the next best match is this one.
It means this one.
So it gives you, has some supports for line numbers,
a few other things as well.
And the last one is smart build,
which is just simplifies like the pipeline.
It does build test, linked in the same row,
and does a bit of magic with more tidings, so on.
So let's see if I can show some of this.
So I have a vanilla example here,
which this is,
the prompted by the way is this one.
So create a model context protocol server
that spells Hello World 2.
And the way I write prompts are usually like this,
so I have over our context what I want to do.
But then I break down to in a list of tasks
to make sure everything I want is done.
In this case, I'm already giving a hint to the model,
which is expected documentation of the SDK,
which most models,
model models will comply,
but the 2.5 generation of Gemini didn't,
all the time.
And the idea of having an acceptance criteria
is also super important, so you can give the model,
I'm actually done with the work.
So let's see.
It's running, so it's already in the link stages,
so it's running our check here, you'll see.
So yeah, it's doing kind of well,
actually, it's using goal list to discover the package.
It's great, it's hard to see.
But it kind of seems to be behaving well enough,
and just to show the difference with goal doctor.
So G3 is the same prompt, but this time I'm hard,
yeah.
This time it has goal doctor enabled.
So hopefully this will call the goal doctor in CP server,
so it's calling project it needs.
You can see, for example, here,
by calling project it needs,
not only created the module,
but also I fit the documentation right away,
so it doesn't have the opportunity to do anything.
File created is also,
it's the only tool I'm not calling smart create for now,
but it also has some magic happening under hood.
And yeah, in essence,
just running those two side by side,
yeah, this one is done.
It seems to be working because, yeah,
it's using Gemini.
So you won't see much difference in accuracy,
but you might see differences in time,
which is, again, hard to measure if it's one,
run like a, a guess each other,
but you can measure if you run this 50 times.
And this is my first try experimenting,
and here I'm also comparing with goal please,
which is the official MCP server we have.
It's just an experiment now,
but you can see the difference in success rate
in this case was a bismo,
like you have like 14% of success rate,
versus 48% and this is statistical significant.
Three stars, less than 1% chance of this being a random event.
But why is was this so significant?
I was running Gemini's ally with auto model,
and auto model, if you don't know Gemini's ally,
is like a mixet bags of models,
it will randomly decide the model which to use,
which includes Gemini 2.5.
So this was a big problem with this experiment.
So when I decided,
then I decided to first Gemini 3 flash preview
and I got this result.
In this case, I'm adjusting for success rate
to make sure every, I only count in the success,
so runs, but you will see default fail 12 times.
Go please fail 10 times and go doctor's station fail five times.
Still we have conservative indication
that the go doctor is better,
but it's not statistically significant.
I didn't have any stars there.
That means either I will increase the example size
and run this 200 times, maybe to get some difference.
But I'm considered an equivalent at this point
because the intelligence of the model compensates that,
the lack of tooling.
So the model in this case was much better.
But what was significant was the duration.
So roughly 30, like, yeah.
Instead of 200 seconds, less than 140 seconds,
so go doctor ended up being much faster.
And use less, although use more input tokens,
use less output tokens.
Yeah.
We have some other difference in internal protocols.
Big star here is that this is a single scenario.
It's just like create MCP service scenario.
Why it's just this scenario specifically?
Because the model is not familiar with MCP package
and I want some green field where it had to discover the API.
It could be any other project like it
with an unknown API that will work.
Future work is great more realistic scenarios
for refactoring, testing, and so on than
so it can do proper testing on those.
And, yeah, reaching out to the end.
Conclusions.
When the writer MCP service tries not to do
one-to-one mapping of your API as the case,
think about from the model perspective what is useful.
Documentation examples are gold variations.
Every time I have the opportunity to insert that in my context,
I will do.
I'll go into your tools with hints upon failures.
So instead of just saying, I failed, I failed because of X.
What about you try Y? It's a better approach.
And try to reduce the model degree of freedom,
example, build to test.
If you want to try to build your own MCP service,
this takes you to a code lab and you can
within some cloud credits when you do this,
so you don't need to pay anything.
And yeah, this is the same process to create
the gold author itself.
And that's it.
If you want to connect with me on socials
and the top materials, they are all there.
Thank you!