使用说明
MCP C# Starter
A feature-complete Model Context Protocol (MCP) server template in C# using the official csharp-sdk. This starter demonstrates all major MCP features with clean, idiomatic C# code leveraging .NET 8 and dependency injection.
📚 Documentation
✨ Features
| Category | Feature | Description |
|---|---|---|
| Tools | hello |
Basic tool with annotations |
get_weather |
Tool returning structured JSON | |
ask_llm |
Tool that invokes LLM sampling | |
long_task |
Tool with progress updates | |
load_bonus_tool |
Dynamically loads a new tool | |
bonus_calculator |
Calculator (dynamically loaded) | |
| Resources | info://about |
Static informational resource |
file://example.md |
File-based markdown resource | |
| Templates | greeting://{name} |
Personalized greeting |
data://items/{id} |
Data lookup by ID | |
| Prompts | greet |
Greeting in various styles |
code_review |
Code review with focus areas |
🚀 Quick Start
Prerequisites
Installation
# Clone the repository
git clone https://github.com/SamMorrowDrums/mcp-csharp-starter.git
cd mcp-csharp-starter
# Restore packages
dotnet restore
Running the Server
stdio transport (for local development):
dotnet run
HTTP transport (for remote/web deployment):
dotnet run -- --http
# Or with custom port:
dotnet run -- --http --port 8080
# Server runs on http://localhost:3000 by default
🔧 VS Code Integration
This project includes VS Code configuration for seamless development:
- Open the project in VS Code
- The MCP configuration is in
.vscode/mcp.json - Build with
Ctrl+Shift+B(orCmd+Shift+Bon Mac) - Debug with F5 (configurations for both transports)
- Test the server using VS Code's MCP tools
Using DevContainers
- Install the Dev Containers extension
- Open command palette: "Dev Containers: Reopen in Container"
- Everything is pre-configured and ready to use!
📁 Project Structure
.
├── Program.cs # Main entry point (stdio/HTTP)
├── Tools/
│ └── AllTools.cs # All tool definitions
├── Resources/
│ └── AllResources.cs # All resource definitions
├── Prompts/
│ └── AllPrompts.cs # All prompt definitions
├── .vscode/
│ ├── mcp.json # MCP server configuration
│ ├── tasks.json # Build/run tasks
│ ├── launch.json # Debug configurations
│ └── extensions.json
├── .devcontainer/
│ └── devcontainer.json
├── McpCSharpStarter.csproj
├── global.json
└── appsettings.json
🛠️ Development
# Development with live reload (recommended)
dotnet watch run
# Build
dotnet build
# Run tests
dotnet test
# Format code
dotnet format
# Clean
dotnet clean
# Publish for production
dotnet publish -c Release
Live Reload
The dotnet watch run command provides automatic rebuilds during development.
Changes to any .cs file will automatically rebuild and restart the server.
Dependency Updates
Dependabot checks NuGet packages, GitHub Actions, and the .NET SDK in global.json
weekly. NuGet versions are explicit, and packages.lock.json records the
resolved direct and transitive dependencies. CI restores in locked mode and
treats restore warnings, including vulnerability advisories, as errors.
After changing package versions, regenerate and commit the lockfile:
dotnet restore --force-evaluate
dotnet restore --locked-mode --warnaserror
dotnet list package --vulnerable --include-transitive
The server uses the stable MCP SDK 1.4.1 release. SDK 2.x is deferred because it changes HTTP session defaults and deprecates sampling, which this workshop demonstrates; upgrading requires a separate behavior and compatibility migration.
🔍 MCP Inspector
The MCP Inspector is an essential development tool for testing and debugging MCP servers.
Running Inspector
npx @modelcontextprotocol/inspector -- dotnet run -- --stdio
What Inspector Provides
- Tools Tab: List and invoke all registered tools with parameters
- Resources Tab: Browse and read resources and templates
- Prompts Tab: View and test prompt templates
- Logs Tab: See JSON-RPC messages between client and server
- Schema Validation: Verify tool input/output schemas
Debugging Tips
- Start Inspector before connecting your IDE/client
- Use the "Logs" tab to see exact request/response payloads
- Test tool annotations (ReadOnlyHint, etc.) are exposed correctly
- Verify progress notifications appear for
long_task - Check that McpServer injection works for sampling tools
📖 Feature Examples
Tool with Attributes
[McpServerToolType]
public class GreetingTools
{
[McpServerTool(Name = "hello", Title = "Say Hello")]
[Description("A friendly greeting tool")]
public static string Hello(
[Description("The name to greet")] string name)
{
return $"Hello, {name}!";
}
}
Resource Template
[McpServerResourceType]
public class StaticResources
{
[McpServerResource(
UriTemplate = "greeting://{name}",
Name = "Personalized Greeting",
MimeType = "text/plain")]
public static string Greeting(string name)
{
return $"Hello, {name}!";
}
}
Tool with Sampling
[McpServerTool(Name = "ask_llm")]
public static async Task<string> AskLlm(
McpServer server,
[Description("The prompt")] string prompt,
CancellationToken cancellationToken)
{
var result = await server.SampleAsync(
new CreateMessageRequestParams
{
Messages = [
new SamplingMessage
{
Role = Role.User,
Content = [new TextContentBlock { Text = prompt }]
}
],
MaxTokens = 100
},
cancellationToken: cancellationToken);
return result.Content.OfType<TextContentBlock>()
.FirstOrDefault()?.Text ?? "";
}
Prompt Definition
[McpServerPromptType]
public class CodeReviewPrompts
{
[McpServerPrompt(Name = "code_review", Title = "Code Review")]
public static IEnumerable<PromptMessage> CodeReview(
[Description("The code to review")] string code,
[Description("Programming language")] string language)
{
return [
new PromptMessage
{
Role = Role.User,
Content = new TextContentBlock
{
Text = $"Review this {language} code:\n```{language}\n{code}\n```"
}
}
];
}
}
🔐 Configuration
Configuration via appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
🤝 Contributing
Contributions welcome! Please ensure your changes maintain feature parity with other language starters.
📄 License
MIT License - see LICENSE for details.
