Smart Home MCP Server with VSCode Copilot

What is MCP? My short definition is: A protocol that lets LLMs talk to your code. For example, if you have an API that returns a list of warehouses, how could you get Copilot to call your API and return a list of those warehouses? Or use the list internally to answer your questions about your warehouses? The answer is MCP. These clients can use it https://modelcontextprotocol.io/clients VSCode is in that list. They have added support for MCP https://code.visualstudio.com/docs/copilot/chat/mcp-servers What can I write my MCP server in? Python SDK TypeScript SDK Java SDK Kotlin SDK C# SDK Using CSharp I followed this tutorial, I will simplify here and adapt for my Smart Home https://devblogs.microsoft.com/dotnet/build-a-model-context-protocol-mcp-server-in-csharp/ Create a .NET app: dotnet new console -n SmartHomeMCPServer dotnet add package ModelContextProtocol dotnet add package Microsoft.Extensions.Logging.Console dotnet add package Microsoft.Extensions.Hosting dotnet add package RestEase (http client helper https://github.com/canton7/RestEase) I am using a Hubitat with an API plugin https://hubitat.com/. This is what the API plugin shows me: I used Copilot edit mode to generate my app after feeding in the API spec above. I also fed it the RestEase docs which is just the entire README.md. This is the HTTP client it generated with RestEase: public interface IHubitatApi { [Get("apps/api/60/devices/all")] Task GetAllDevicesAsync([Query("access_token")] string accessToken); [Get("apps/api/60/devices/{deviceId}/{command}/{secondaryValue}")] Task SendDeviceCommandAsync( [Path("deviceId")] string deviceId, [Path("command")] string command, [Path("secondaryValue")] string secondaryValue, [Query("access_token")] string accessToken ); [Get("apps/api/60/devices/{deviceId}/{command}")] Task SendDeviceCommandAsync( [Path("deviceId")] string deviceId, [Path("command")] string command, [Query("access_token")] string accessToken ); } public class Device { public string Id { get; set; } public string Name { get; set; } public string Label { get; set; } public string Type { get; set; } public string Room { get; set; } public string Date { get; set; } public string Model { get; set; } public string Manufacturer { get; set; } public List Capabilities { get; set; } public Attributes Attributes { get; set; } public List Commands { get; set; } } // ... After that, I wrapped the client around an MCP server: [McpServerToolType] public static class HubitatTool { [McpServerTool, Description("Fetches all devices from the Hubitat API.")] public static async Task GetAllDevices() { const string baseUrl = "http://192.168.1.120"; const string accessToken = "YOUR-TOKEN"; var api = RestClient.For(baseUrl); return await api.GetAllDevicesAsync(accessToken); } [McpServerTool, Description("Send a command to a specific device.")] public static async Task SendDeviceCommand(string deviceId, string command, string secondaryValue = null) { const string baseUrl = "http://192.168.1.120"; const string accessToken = "YOUR-TOKEN"; var api = RestClient.For(baseUrl); // Ensure secondaryValue is handled properly if (string.IsNullOrWhiteSpace(secondaryValue)) { await api.SendDeviceCommandAsync(deviceId, command, accessToken); } else { await api.SendDeviceCommandAsync(deviceId, command, secondaryValue.Trim(), accessToken); } } } I "vibe coded" the above, in a real world scenario id have a .env file for tokens and URLs. Finally, you can ask the LLM to list your devices!

Apr 16, 2025 - 19:27
 0
Smart Home MCP Server with VSCode Copilot

What is MCP?

My short definition is: A protocol that lets LLMs talk to your code.

For example, if you have an API that returns a list of warehouses, how could you get Copilot to call your API and return a list of those warehouses? Or use the list internally to answer your questions about your warehouses?

The answer is MCP. These clients can use it https://modelcontextprotocol.io/clients

VSCode is in that list. They have added support for MCP https://code.visualstudio.com/docs/copilot/chat/mcp-servers

What can I write my MCP server in?

  • Python SDK
  • TypeScript SDK
  • Java SDK
  • Kotlin SDK
  • C# SDK

Using CSharp

I followed this tutorial, I will simplify here and adapt for my Smart Home

https://devblogs.microsoft.com/dotnet/build-a-model-context-protocol-mcp-server-in-csharp/

Create a .NET app:

  1. dotnet new console -n SmartHomeMCPServer
  2. dotnet add package ModelContextProtocol
  3. dotnet add package Microsoft.Extensions.Logging.Console
  4. dotnet add package Microsoft.Extensions.Hosting
  5. dotnet add package RestEase (http client helper https://github.com/canton7/RestEase)

I am using a Hubitat with an API plugin https://hubitat.com/.

This is what the API plugin shows me:

Hubitat Makrer API Endpoint List

I used Copilot edit mode to generate my app after feeding in the API spec above. I also fed it the RestEase docs which is just the entire README.md. This is the HTTP client it generated with RestEase:

public interface IHubitatApi
{
    [Get("apps/api/60/devices/all")]
    Task<List<Device>> GetAllDevicesAsync([Query("access_token")] string accessToken);

    [Get("apps/api/60/devices/{deviceId}/{command}/{secondaryValue}")]
    Task SendDeviceCommandAsync(
        [Path("deviceId")] string deviceId,
        [Path("command")] string command,
        [Path("secondaryValue")] string secondaryValue,
        [Query("access_token")] string accessToken
    );

    [Get("apps/api/60/devices/{deviceId}/{command}")]
    Task SendDeviceCommandAsync(
        [Path("deviceId")] string deviceId,
        [Path("command")] string command,
        [Query("access_token")] string accessToken
    );
}

public class Device
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Label { get; set; }
    public string Type { get; set; }
    public string Room { get; set; }
    public string Date { get; set; }
    public string Model { get; set; }
    public string Manufacturer { get; set; }
    public List<string> Capabilities { get; set; }
    public Attributes Attributes { get; set; }
    public List<Command> Commands { get; set; }
}

// ...

After that, I wrapped the client around an MCP server:

[McpServerToolType]
public static class HubitatTool
{
    [McpServerTool, Description("Fetches all devices from the Hubitat API.")]
    public static async Task<List<Device>> GetAllDevices()
    {
        const string baseUrl = "http://192.168.1.120";
        const string accessToken = "YOUR-TOKEN";

        var api = RestClient.For<IHubitatApi>(baseUrl);
        return await api.GetAllDevicesAsync(accessToken);
    }

    [McpServerTool, Description("Send a command to a specific device.")]
    public static async Task SendDeviceCommand(string deviceId, string command, string secondaryValue = null)
    {
        const string baseUrl = "http://192.168.1.120";
        const string accessToken = "YOUR-TOKEN";

        var api = RestClient.For<IHubitatApi>(baseUrl);

        // Ensure secondaryValue is handled properly
        if (string.IsNullOrWhiteSpace(secondaryValue))
        {
            await api.SendDeviceCommandAsync(deviceId, command, accessToken);
        }
        else
        {
            await api.SendDeviceCommandAsync(deviceId, command, secondaryValue.Trim(), accessToken);
        }
    }
}

I "vibe coded" the above, in a real world scenario id have a .env file for tokens and URLs.

Finally, you can ask the LLM to list your devices!

VS Code Copilot Conversation showing MCP usage