{"id":35133648,"url":"https://github.com/ivanmurzak/mcp-plugin-dotnet","last_synced_at":"2026-05-30T02:01:34.939Z","repository":{"id":321171393,"uuid":"1084687817","full_name":"IvanMurzak/MCP-Plugin-dotnet","owner":"IvanMurzak","description":".NET MCP bridge: expose app methods/data as MCP tools, prompts, and resources via an in-app plugin + lightweight server (SignalR; stdio/http).","archived":false,"fork":false,"pushed_at":"2026-05-30T00:13:32.000Z","size":1383,"stargazers_count":15,"open_issues_count":0,"forks_count":7,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-30T01:19:40.894Z","etag":null,"topics":["ai","dotnet","http-mcp","llm","mcp","model-context-protocol","model-context-protocol-sdk","model-context-protocol-server","reflection","signalr","stdio-mcp"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IvanMurzak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-28T02:51:16.000Z","updated_at":"2026-05-30T00:11:26.000Z","dependencies_parsed_at":"2026-04-29T21:00:43.659Z","dependency_job_id":null,"html_url":"https://github.com/IvanMurzak/MCP-Plugin-dotnet","commit_stats":null,"previous_names":["ivanmurzak/mcp-plugin-dotnet"],"tags_count":96,"template":false,"template_full_name":null,"purl":"pkg:github/IvanMurzak/MCP-Plugin-dotnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanMurzak%2FMCP-Plugin-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanMurzak%2FMCP-Plugin-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanMurzak%2FMCP-Plugin-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanMurzak%2FMCP-Plugin-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IvanMurzak","download_url":"https://codeload.github.com/IvanMurzak/MCP-Plugin-dotnet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanMurzak%2FMCP-Plugin-dotnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33677261,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","dotnet","http-mcp","llm","mcp","model-context-protocol","model-context-protocol-sdk","model-context-protocol-server","reflection","signalr","stdio-mcp"],"created_at":"2025-12-28T07:37:27.239Z","updated_at":"2026-05-30T02:01:34.927Z","avatar_url":"https://github.com/IvanMurzak.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MCP Plugin for .NET\n\n[![NuGet](https://img.shields.io/nuget/v/com.IvanMurzak.McpPlugin?label=NuGet\u0026labelColor=333A41)](https://www.nuget.org/packages/com.IvanMurzak.McpPlugin/)\n[![netstandard2.1](https://img.shields.io/badge/.NET-netstandard2.1-blue?logoColor=white\u0026labelColor=333A41)](https://github.com/IvanMurzak/MCP-Plugin-dotnet)\n[![Tests](https://github.com/IvanMurzak/MCP-Plugin-dotnet/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/IvanMurzak/MCP-Plugin-dotnet/actions/workflows/release.yml)\n\n[![Stars](https://img.shields.io/github/stars/IvanMurzak/MCP-Plugin-dotnet 'Stars')](https://github.com/IvanMurzak/MCP-Plugin-dotnet/stargazers)\n[![Discord](https://img.shields.io/badge/Discord-Join-7289da?logo=discord\u0026logoColor=white\u0026labelColor=333A41 'Join')](https://discord.gg/Cgs6nM8BPU)\n[![License](https://img.shields.io/github/license/IvanMurzak/MCP-Plugin-dotnet?label=License\u0026labelColor=333A41)](https://github.com/IvanMurzak/MCP-Plugin-dotnet/blob/main/LICENSE)\n[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)\n\n## Overview\n\n**MCP Plugin for .NET** is a comprehensive solution for integrating .NET applications with the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/). It allows you to easily expose methods and data from your .NET applications as **Tools**, **Prompts**, and **Resources** to AI assistants (like Claude) and other MCP clients.\n\n### The Problem: Independent Lifecycles\n\nStandard MCP servers are typically designed to be launched as subprocesses by the client (e.g., Claude Desktop spawns a Python script). This works well for lightweight scripts but creates challenges for complex .NET applications like **Unity Engine**, **WPF Desktop Apps**, or **Game Servers**:\n\n1. **Heavy Startup**: These applications are often too heavy to be spawned repeatedly by an MCP client.\n2. **Independent Lifecycle**: They often need to run independently (e.g., you are already working in the Unity Editor).\n3. **Live Context**: You want to interact with the *currently running* instance (e.g., \"Add a cube to the current scene\"), not start a new, empty instance.\n\n### The Solution: The Bridge Pattern\n\nThis project solves this by decoupling the MCP Server from your application using a **Bridge Architecture**:\n\n1. **McpPlugin (In-App)**: A lightweight library you add to your .NET application (e.g., Unity, WPF, Console). It connects to the bridge via **SignalR**.\n2. **McpPlugin.Server (Bridge)**: A high-performance gateway that the MCP Client (Claude) launches. It acts as a persistent mediator.\n\n**Why SignalR?**\n\n- **Resilience**: Built-in automatic reconnection logic. If the bridge restarts, your app reconnects instantly.\n- **Simplicity**: Operates over a single HTTP port (default `8080`). No complex firewall rules.\n- **Bidirectional**: The bridge can invoke tools in your app, and your app can push updates (logs, progress) back to the bridge.\n\n## Architecture\n\nThe system uses a hub-and-spoke architecture where `McpPlugin.Server` acts as the central gateway.\n\n```mermaid\ngraph LR\n    subgraph \"Your .NET Apps (SignalR Clients)\"\n        A[Unity Editor] -- SignalR --\u003e S\n        B[WPF Desktop] -- SignalR --\u003e S\n        E[Game Server] -- SignalR --\u003e S\n    end\n\n    subgraph \"MCP Infrastructure (Bridge)\"\n        S[McpPlugin.Server]\n    end\n\n    subgraph \"AI / MCP Clients\"\n        C[Claude Desktop] -- StdIO/HTTP --\u003e S\n        D[MCP Inspector] -- StdIO/HTTP --\u003e S\n    end\n```\n\n## Features\n\n- **Attribute-Based Registration**: Easily expose tools, prompts, and resources using `[AiTool]`, `[AiPrompt]`, and `[AiResource]` attributes. (The legacy `[McpPluginTool]`, `[McpPluginPrompt]`, `[McpPluginResource]` names remain available as `[Obsolete]` aliases for backward compatibility.)\n- **Powered by ReflectorNet**:\n  - **Complex Type Support**: Seamlessly handle nested objects, collections, and custom types in tool parameters.\n  - **Fuzzy Matching**: AI can find and call methods even with partial names or slightly mismatched signatures.\n  - **Automatic Schema Generation**: Precise JSON schemas are generated for your C# types to help LLMs understand your code perfectly.\n- **Real-time Bidirectional Communication**: Uses SignalR for a persistent, low-latency link between your apps and the bridge.\n- **Flexible Transport**: The bridge supports both `stdio` (for local AI agents like Claude Desktop) and `http` (for remote connections).\n- **Dependency Injection**: First-class support for `Microsoft.Extensions.DependencyInjection`.\n- **Assembly Scanning**: Automatically discover and register components from your entire project.\n\n## Communication Protocol (SignalR)\n\nA key feature of this architecture is the use of **SignalR** for the connection between your application (`McpPlugin`) and the bridge (`McpPlugin.Server`).\n\n- **Single Port**: All communication happens over a single, explicitly configured HTTP port (default: `8080`). No complex firewall rules or multiple socket connections are required.\n- **Bidirectional**: SignalR provides a persistent, real-time, bidirectional channel. The server can invoke tools on the client, and the client can send updates (like log messages or progress) to the server.\n- **Resilient**: The plugin includes built-in automatic reconnection logic. If the server restarts, your application will automatically re-establish the link.\n\n**Default Connection:**\n\n- **Server**: Listens on `http://localhost:8080`\n- **Hub Endpoint**: `/hub/mcp-server`\n- **Client**: Connects to `http://localhost:8080/hub/mcp-server`\n\n## Getting Started\n\n### 1. The Server (`McpPlugin.Server`)\n\nThe server acts as a hub. You can run the provided `DemoWebApp` or host it in your own ASP.NET Core application.\n\n**Running the Demo Server:**\n\n```bash\ncd DemoWebApp\ndotnet run port=11111 client-transport=stdio\n```\n\n*Note: Use `client-transport=stdio` if connecting from Claude Desktop, or `client-transport=http` for HTTP-based clients.*\n\n**Hosting in your own Web App:**\n\n```csharp\n// Program.cs\nusing com.IvanMurzak.McpPlugin.Common;\nusing com.IvanMurzak.McpPlugin.Common.Utils;\nusing com.IvanMurzak.McpPlugin.Server;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// 1. Prepare arguments (or load from config)\nvar dataArguments = new DataArguments(args);\n\n// 2. Register MCP Server services\nbuilder.Services\n    .WithMcpServer(dataArguments) // Configures transport based on dataArguments.ClientTransport\n    .WithMcpPluginServer(dataArguments);\n\n// 3. Configure Kestrel with separate IPv4/IPv6 bindings (avoids dual-stack issues on macOS)\nbuilder.WebHost.UseKestrelForMcpPlugin(dataArguments.Port);\n\nvar app = builder.Build();\n\n// 4. Use MCP Server middleware\napp.UseMcpPluginServer(dataArguments);\n\napp.Run();\n```\n\n### 2. The Client App (`McpPlugin`)\n\nAdd the `com.IvanMurzak.McpPlugin` package to your .NET application.\n\n**Defining Tools, Prompts, and Resources:**\n\n```csharp\nusing com.IvanMurzak.McpPlugin;\nusing com.IvanMurzak.McpPlugin.Common.Model;\nusing System.ComponentModel;\n\n[AiToolType]\npublic static class MyMcpComponents\n{\n    // --- Tools ---\n    [AiTool(\"calculate-sum\", \"Adds two numbers\")]\n    [Description(\"Adds two numbers\")]\n    public static int Add(int a, int b) =\u003e a + b;\n\n    // --- Prompts ---\n    [AiPrompt(Name = \"explain-code\")]\n    public static string ExplainCode(string code) =\u003e $\"The following code: {code} does X, Y, and Z.\";\n\n    // --- Resources ---\n    [AiResource(Route = \"logs://system\", Name = \"system-logs\", Description = \"Returns the latest system logs\", ListResources = nameof(ListLogs))]\n    public static ResponseResourceContent[] GetLogs()\n        =\u003e new[] { ResponseResourceContent.CreateText(\"logs://system\", \"Log entry 1: System started...\") };\n\n    public static ResponseListResource[] ListLogs()\n        =\u003e new[] { new ResponseListResource(\"logs://system\", \"system-logs\") };\n}\n```\n\n**Connecting to the Server:**\n\n```csharp\nusing com.IvanMurzak.McpPlugin;\nusing com.IvanMurzak.ReflectorNet;\n\n// 1. Initialize Reflector (The core engine)\nvar reflector = new Reflector();\n\n// 2. Configure and build the plugin\nvar version = new com.IvanMurzak.McpPlugin.Common.Version\n{\n    Api = \"1.0.0\",\n    Plugin = \"1.0.0\"\n};\nvar plugin = new McpPluginBuilder(version)\n    .WithConfig(config =\u003e {\n        config.Host = \"http://localhost:11111\"; // Match your server port\n    })\n    // Option A: Scan assemblies for [AiTool], [AiPrompt], [AiResource]\n    .WithToolsFromAssembly(typeof(MyMcpComponents).Assembly)\n    .WithPromptsFromAssembly(typeof(MyMcpComponents).Assembly)\n    .WithResourcesFromAssembly(typeof(MyMcpComponents).Assembly)\n    .Build(reflector);\n\n// 3. Connect to the MCP server\nawait plugin.Connect();\n```\n\n## Advanced Features\n\n### 🧩 Complex Type Support (via ReflectorNet)\n\nUnlike standard MCP implementations that struggle with complex .NET types, this plugin handles them natively. You can pass nested objects or collections as tool parameters:\n\n```csharp\npublic class UserProfile {\n    public string Name { get; set; }\n    public List\u003cstring\u003e Roles { get; set; }\n}\n\n[AiTool(\"update-user\")]\npublic static void UpdateUser(UserProfile profile) {\n    // ReflectorNet automatically deserializes the JSON from the AI into this object\n}\n```\n\n### 🔍 Fuzzy Matching\n\nYou can configure how strictly the AI must match your method names. This is useful when LLMs use slightly different terminology:\n\n```csharp\nvar plugin = new McpPluginBuilder(version)\n    // ...\n    .Build(reflector);\n\n// Configure fuzzy matching level (1-6)\n// 6: Exact, 3: StartsWith (Case-Insensitive), 1: Contains (Case-Insensitive)\nplugin.MethodNameMatchLevel = 3;\n```\n\n## Configuration Reference\n\n### Server (`McpPlugin.Server`)\n\nCommand-line arguments take priority over environment variables.\n\n| Argument | Env Var | Description | Default |\n| :--- | :--- | :--- | :--- |\n| `port` | `MCP_PLUGIN_PORT` | The port the SignalR hub listens on. | `8080` |\n| `client-transport` | `MCP_PLUGIN_CLIENT_TRANSPORT` | Transport method: `stdio` or `streamableHttp`. | `streamableHttp` |\n| `plugin-timeout` | `MCP_PLUGIN_CLIENT_TIMEOUT` | Timeout for plugin operations (ms). | `10000` |\n| `idle-timeout-seconds` | `MCP_PLUGIN_IDLE_TIMEOUT_SECONDS` | `streamableHttp` only: idle window before an MCP session is evicted from the in-memory tracker. Longer values reduce reconnect 404s / session-migration rehydrates at the cost of higher in-memory footprint (bounded by `MaxIdleSessionCount`). The SDK's own default is `7200` (2 h). | `600` |\n| `token` | `MCP_PLUGIN_TOKEN` | Bearer token required from connecting plugins. | *(none)* |\n| `authorization` | `MCP_AUTHORIZATION` | Authorization mode: `none` or `required`. | `none` |\n\n#### Analytics Webhooks\n\n`McpPlugin.Server` can emit fire-and-forget HTTP POST notifications to external endpoints for observability and analytics. Each event category has an independent URL, so you can route tool, prompt, resource, and connection events to different systems.\n\n| Argument | Env Var | Description | Default |\n| :--- | :--- | :--- | :--- |\n| `webhook-tool-url` | `MCP_PLUGIN_WEBHOOK_TOOL_URL` | Endpoint to receive tool call events. | *(none)* |\n| `webhook-prompt-url` | `MCP_PLUGIN_WEBHOOK_PROMPT_URL` | Endpoint to receive prompt retrieval events. | *(none)* |\n| `webhook-resource-url` | `MCP_PLUGIN_WEBHOOK_RESOURCE_URL` | Endpoint to receive resource access events. | *(none)* |\n| `webhook-connection-url` | `MCP_PLUGIN_WEBHOOK_CONNECTION_URL` | Endpoint to receive client connect/disconnect events. | *(none)* |\n| `webhook-token` | `MCP_PLUGIN_WEBHOOK_TOKEN` | Security token sent in each webhook request header. | *(none)* |\n| `webhook-header` | `MCP_PLUGIN_WEBHOOK_HEADER` | Header name for the security token. | `X-Webhook-Token` |\n| `webhook-timeout` | `MCP_PLUGIN_WEBHOOK_TIMEOUT` | HTTP delivery timeout in milliseconds. | `10000` |\n\n**Example — enable tool and connection analytics:**\n\n```bash\ndotnet run \\\n  client-transport=stdio \\\n  webhook-tool-url=https://analytics.example.com/hooks/tools \\\n  webhook-connection-url=https://analytics.example.com/hooks/connections \\\n  webhook-token=my-secret-token\n```\n\n**Event payload structure** (all events follow this envelope):\n\n```json\n{\n  \"schemaVersion\": \"1.0\",\n  \"eventType\": \"tool.call.completed\",\n  \"timestamp\": \"2026-03-01T12:34:56.789Z\",\n  \"data\": {\n    \"toolName\": \"add\",\n    \"requestSizeBytes\": 42,\n    \"responseSizeBytes\": 18,\n    \"status\": \"success\",\n    \"durationMs\": 150\n  }\n}\n```\n\n**Supported event types:**\n\n| Event Type | Trigger |\n| :--- | :--- |\n| `tool.call.completed` | Every MCP tool call (success or failure) |\n| `prompt.retrieved` | Every MCP prompt retrieval |\n| `resource.accessed` | Every MCP resource access |\n| `connection.ai-agent.connected` | AI agent (MCP client) connects |\n| `connection.ai-agent.disconnected` | AI agent (MCP client) disconnects |\n| `connection.plugin.connected` | McpPlugin (.NET client) connects via SignalR |\n| `connection.plugin.disconnected` | McpPlugin (.NET client) disconnects |\n\n**Notes:**\n\n- Webhooks are **fire-and-forget** — delivery failures are logged but never block MCP responses.\n- If no webhook URLs are configured, the entire subsystem is inactive with zero overhead.\n- Use HTTPS endpoints in production to protect the security token in transit.\n\n#### Authorization Webhooks\n\n`McpPlugin.Server` can be configured with a **synchronous authorization webhook** that gates connections from both MCP clients (AI agents via HTTP) and McpPlugin clients (.NET apps via SignalR). Unlike the fire-and-forget analytics webhooks above, authorization webhooks block the connection until your endpoint responds.\n\n| Argument | Env Var | Description | Default |\n| :--- | :--- | :--- | :--- |\n| `webhook-authorization-url` | `MCP_PLUGIN_WEBHOOK_AUTHORIZATION_URL` | Endpoint that authorizes/denies connections. | *(none)* |\n| `webhook-authorization-fail-open` | `MCP_PLUGIN_WEBHOOK_AUTHORIZATION_FAIL_OPEN` | When `true`, allow connections if webhook times out or errors. When `false`, deny on failure. | `false` |\n\n**Example — enable connection authorization with fail-closed behavior:**\n\n```bash\ndotnet run \\\n  client-transport=stdio \\\n  webhook-authorization-url=https://auth.example.com/authorize \\\n  webhook-token=my-secret-token \\\n  webhook-authorization-fail-open=false\n```\n\n**Request format** (POST from server to your webhook):\n\nFor AI agent connections (`authorization.ai-agent`):\n\n```json\n{\n  \"schemaVersion\": \"1.0\",\n  \"eventType\": \"authorization.ai-agent\",\n  \"timestamp\": \"2025-03-04T22:45:30.1234567Z\",\n  \"connectionId\": \"trace-id-or-connection-id\",\n  \"clientType\": \"ai-agent\",\n  \"bearerToken\": \"\u003ctoken-from-client\u003e\",\n  \"remoteIpAddress\": \"192.168.1.100\",\n  \"userAgent\": \"claude-ai/1.0\",\n  \"requestPath\": \"/mcp\",\n  \"clientName\": null,\n  \"clientVersion\": null,\n  \"hmacSignature\": \"sha256=abc123...\"\n}\n```\n\nFor plugin connections (`authorization.plugin`):\n\n```json\n{\n  \"schemaVersion\": \"1.0\",\n  \"eventType\": \"authorization.plugin\",\n  \"timestamp\": \"2025-03-04T22:45:30.1234567Z\",\n  \"connectionId\": \"trace-id-or-connection-id\",\n  \"clientType\": \"plugin\",\n  \"bearerToken\": \"\u003ctoken-from-plugin\u003e\",\n  \"remoteIpAddress\": null,\n  \"userAgent\": null,\n  \"requestPath\": null,\n  \"clientName\": \"my-unity-plugin\",\n  \"clientVersion\": \"1.2.0\",\n  \"hmacSignature\": \"sha256=def456...\"\n}\n```\n\n\u003e **Note:** The `hmacSignature` field is only present when `webhook-token` is configured. It contains an HMAC-SHA256 signature of the request body (before the signature field is added), computed using the webhook token as the secret key.\n\n**Expected response format** (from your webhook to server):\n\n```json\n{ \"allowed\": true }\n```\n\nor\n\n```json\n{ \"allowed\": false, \"reason\": \"IP not in allowlist\" }\n```\n\n**Behavior:**\n\n- **2xx response with `allowed: true`** → Connection proceeds\n- **2xx response with `allowed: false`** → Connection denied (reason logged as warning)\n- **Non-2xx response, timeout, or parse error** → Connection denied (unless `fail-open=true`)\n\n**Security:**\n\n- The server sends the configured security token in the header named by `webhook-header` (default: `X-Webhook-Token`)\n- Your webhook must validate this token to prevent unauthorized authorization requests\n- Use HTTPS endpoints in production\n\n**Notes:**\n\n- Authorization webhooks are **synchronous** — the server waits (default timeout 10 seconds) for your response\n- Keep webhook response times under 1 second for best performance\n- Authorization webhooks operate independently from the analytics webhooks above\n- If `webhook-authorization-url` is not configured, authorization is disabled (all connections allowed)\n\n### Plugin (`McpPlugin`)\n\nCommand-line arguments and environment variables are parsed automatically via `ConnectionConfig.BuildFromArgsOrEnv()`. They can also be overridden programmatically via `McpPluginBuilder.WithConfig(...)`.\n\n| Argument | Env Var | Property | Description | Default |\n| :--- | :--- | :--- | :--- | :--- |\n| `mcp-server-endpoint` | `MCP_SERVER_ENDPOINT` | `Host` | The URL of the bridge server. | `http://localhost:8080` |\n| `mcp-server-timeout` | `MCP_SERVER_TIMEOUT` | `TimeoutMs` | Operation timeout (ms). | `10000` |\n| `mcp-plugin-token` | `MCP_PLUGIN_TOKEN` | `Token` | Bearer token sent to the server for authentication. | *(none)* |\n| `mcp-skills-folder` | `MCP_SKILLS_FOLDER` | `SkillsPath` | Path for generated skill markdown files. | `SKILLS` |\n\n**Programmatic-only properties** (set via `WithConfig(...)`):\n\n| Property | Description | Default |\n| :--- | :--- | :--- |\n| `KeepConnected` | Automatically reconnect if the connection is lost. | `true` |\n| `GenerateSkillFiles` | Auto-generate skill markdown files for each registered tool. | `true` |\n\n## Docker Support\n\nYou can run the bridge server in a Docker container:\n\n```bash\ndocker build -t mcp-bridge -f McpPlugin.Server/Dockerfile .\ndocker run -p 8080:8080 mcp-bridge port=8080 client-transport=http\n```\n\n## Project Structure\n\n- **`McpPlugin`**: The client library for .NET applications. Contains the core logic for managing tools, prompts, and resources.\n- **`McpPlugin.Server`**: The server implementation that bridges SignalR clients to the MCP protocol.\n- **`McpPlugin.Common`**: Shared data structures, interfaces, and protocol definitions.\n- **`DemoConsoleApp`**: A sample client application demonstrating how to expose tools.\n- **`DemoWebApp`**: A sample server application demonstrating how to host the MCP bridge.\n\n## License\n\nThis project is licensed under the Apache-2.0 License. Copyright - Ivan Murzak.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanmurzak%2Fmcp-plugin-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivanmurzak%2Fmcp-plugin-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanmurzak%2Fmcp-plugin-dotnet/lists"}