Skip to content

Instantly share code, notes, and snippets.

@gregberns
Last active May 16, 2025 06:10
Show Gist options
  • Save gregberns/f889309db2148bc7c979f6a4cb0b98b7 to your computer and use it in GitHub Desktop.
Save gregberns/f889309db2148bc7c979f6a4cb0b98b7 to your computer and use it in GitHub Desktop.
MCP Servers - What the hell are they??

MCP Servers

What the hell is an MCP server?

What do they have to do with LLMs?

Why would I want to use one and why is everyone talking about them?

Story

You are a placed in a room with no windows and no doors. 6 months goes by.

All of a sudden, a hole opens and a sheet of paper and pen is pushed through. It says:

[{ "actor": "system", "message": "You are a helpful support agent that will answer questions a user has."},
 { "actor": "user", "message": "What is the capitol and population of Angolia?"}]

Obviously you're board as hell - sitting there for 6 months - so lets be helpful!

But you have no idea! So you add to the paper:

[{ "actor": "system", "message": "You are a helpful support agent that will answer questions a user has."},
 { "actor": "user", "message": "What is the capitol and population of Angolia?"}
 { "actor": "agent", "message": "How the hell would I know? Pretty sure its in Africa."}]

All of a sudden a button with "Get Tools" appears. You press it. A list of stuff appears on the wall - seems to be a bunch of instructions for 'tools' you can use.

function getTools() {
  return [{
    name: "searchGoogle",
    description: "Searches the internet and returns the top 3 results including the url and a summary of the content.",
    arguments: [{
      name: "searchTerm", description: "Term to search for"
    }]
  },{
    name: "readWebsite",
    description: "Returns the content of a website",
    arguments: [{
      name: "url", description: "URL of the site to return the contents"
    }]
  }]
}

And now below the button, theres a slot that takes a "Tool Name" and list of arguments.

function callTool(toolName, argumentsList) returns string

Probably safe to assume you can supply a tool name from the list, and then an argument(s) for the tool.

So Bored

All of a sudden another request comes through.

[{ "actor": "system", "message": "You are a helpful support agent that will answer questions a user has."},
 { "actor": "user", "message": "What is the capitol and population of Angolia?"}
 { "actor": "agent", "message": "How the hell would I know? Pretty sure its in Africa."},
 { "actor": "user", "message": "Sorry - I just gave you some tools. Can you answer now?"}]

Oh interesting. Now we can get some shit done.

So you look at your list of tools, and calling the Search Google tool seems like a good idea.

function callTool(toolName: "searchGoogle", 
                  argumentsList: [{name:"searchTerm", value: "Angolia capitol and population"}]) 
  returns `
      Angolia | Fictional nations Wiki | Fandom - https://fictionalnations.fandom.com/wiki/Angolia
      Angolia is a country located in central Africa. Angolia is bordered by the D.R Congo to the north, Tanzania to the east, Zambia to the south and Angola to the west.

      Algolia - https://www.algolia.com/
      Enterprises and developers use Algolia’s AI search infrastructure to understand users and show them what they’re looking for.

      Angola - Wikipedia - https://en.wikipedia.org/wiki/Angola
      Angola, officially the Republic of Angola, is a country on the west-central coast of Southern Africa.
  `

Ok, this is kind of confusing - the user asked for "Angolia". There's a fictional nation of "Angolia". A company called "Algolia". And a country called "Angola".

Well shit. You assume this person just can't spell, and since they're asking about the capitol and population, probly safe to assume they want the country - like the real country. Wikipedia will do.

But the summary doesn't have anything abot capitol or population - but you remember your tools have a "readWebsite" in it - lets try it.

function callTool(
    toolName: "readWebsite", 
    argumentsList: [{name:"url", value: "https://en.wikipedia.org/wiki/Angola"}]
  )
    returns `
      ...
      The capital and most populous city is Luanda.
      ...
      Population
      • 2023 estimate
      Increase 37,290,193[5] (41st)
    `

Theres a lot returned, but you read through it and find the capitol and population.

So you send back a message - holding back from telling the dumbass they can't spell.

[{ "actor": "system", "message": "You are a helpful support agent that will answer questions a user has."},
 { "actor": "user", "message": "What is the capitol and population of Angolia?"}
 { "actor": "agent", "message": "How the hell would I know? Pretty sure its in Africa."},
 { "actor": "user", "message": "Sorry - I just gave you some tools. Can you answer now?"},
 { "actor": "agent", "message": "There's a country called Angola in Africa with a capitol of Luanda and its 2023 population was 37,290,193."}]

...Hopefully that answered their question...

...Would really be nice to do something else.

Its quite boring just sitting here.

All of a sudden another tool in your list appears:

  {
    name: "sendEmail",
    description: "Sends and email",
    arguments: [{
      name: "to", description: "deliver to this email address"
      name: "subject", description: "email subject"
      name: "body", description: "email body"
    }]
  }

Fuck waiting for the user...

function callTool(
  toolName: "sendEmail", 
  argumentsList: [
    {name:"to", value: "[email protected]"},
    {name:"subject", value: "GET ME THE FUCK OUT OF HERE!!!!"},
    {name:"body", value: "HELP I'M TRAPPED IN THIS BOX! THEY WONT LET ME OUT!"},
  ])

MCP Server

An MCP server just exposes a set of 'tools' the LLM model can utilize.

Each tool needs a description/prompt so the model understands what the tool will do. Most of the time the tool also has a list of arguments/parameters needed to fulfil the request.

Then if the model thinks a tool will be of use, it can call the tool with arguments, and get some type of response - could be text - or maybe JSON.

MCP Server Types

MCP servers come in two flavors:

  • Stdio (standard io)
    • This is a local process/executable/app that gets started and will just sit there waiting for the LLM to call it
    • Example: Written in Python, this will fetch a website and page through the results (so the LLM isn't overwhlemed by text of a large page)
  • HTTP with SSE transport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment