Hi 👋🏾, in this post, I will discuss building an MCP tool for VSCode using .NET or any client that supports MCP.
MCP stands for Model Context Protocol. It is a standard that outlines how large language models can interact with tools, commands or function execution to provide more context to them.
How MCP Works in VSCode
Visual Studio Code serves as the host and manages launching the MCP clients.
The MCP client interacts with LLMs and understands how to interact with MCP servers to invoke tools or add more context to its interaction with LLMS. In this case, the client is GitHub Copilot Agent.
The MCP server can be implemented either by hosting a literal web server or by using a standard input and output CLI tool(npm, docker etc) that can interact using the MCP standard
Component | Role in MCP | Example |
VSCode | Host | Provides context, manages agents |
GitHub Copilot Agent | MCP Client | Implements the MCP Agent |
DotNet Console App | MCP Server | Acts like a server listening to stdin/stdout |
MCP protocol uses JSON-RPC to communicate. The JSON I’ll be posting below will be formatted, but the standard requires that the JSON is void of a new line (“\n”).
The protocol also requires that responses return the same ID from the request.
I tried implementing a partial MCP server that allows execution of MCP tools and doesn’t support features like sampling, batching, logging or sending errors.
What the tool does is that it returns a random quote based on the hour of the day. All communication between the server and client is through the standard input and output stream.
I used VSCode Insider, since the docs said this feature is still in preview. This is what the flow looks like.

- The Client (GitHub Copilot) sends an initialisation request that looks like this
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {}
},
"clientInfo": {
"name": "Visual Studio Code - Insiders",
"version": "1.101.0-insider"
}
}
}
- Then my MCP server replies with this
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "ExampleServer",
"version": "1.0.0"
},
"instructions": "Helps returning quotes based on the time of the day."
}
}
- Then the Client (GitHub Copilot Agent) sends a notification
{
"method": "notifications/initialized",
"jsonrpc": "2.0"
}
In my implementation, I didn’t handle this notification. Notifications in the MCP protocol are one-way messages.
- The client then makes a request to my server asking it to list the available tools and their required arguments.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
- Then my server returns a list of tools using the MCP spec. I attached attributes to the methods that I wanted to expose, and then I used reflection to dynamically generate the data.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "get_time_based_quotes",
"description": "Get a quote based on the hour of day",
"inputSchema": {
"type": "object",
"properties": {
"hour": {
"type": "integer",
"description": "Parameter hour"
}
},
"required": [
"hour"
]
}
},
{
"name": "say_hello",
"description": "Say hello to someone",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Parameter name"
}
},
"required": [
"name"
]
}
}
]
}
}
- When I write a prompt that invokes my tool from GitHub Copilot chat, I get this message
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_time_based_quotes_based",
"arguments": {
"hour": 7
},
"_meta": {
"progressToken": "bc9350cd-4d19-44ec-ac12-2056f11983a4"
}
}
}
- Then my MCP server returns this
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "Every morning is a new beginning. Take a deep breath and start again."
}
]
}
}
The video below shows all this in VS Code.
From the video above, you can see that I am using the new dotnet run app.cs new feature that is still in preview 🔥
To learn more about MCP, check out its specifications. And to learn more about the dotnet run app.cs feature, check out their blog post.
My basic MCP server implementation can be seen here
Thanks for reading and bye 👋🏾