A Model Context Protocol (MCP) server built with C# and ASP.NET Core that exposes 52 developer utility tools to LLMs.
The server implements the MCP specification so any compatible host (Claude Desktop, VS Code Copilot, Cursor, etc.) can discover and call tools at runtime without custom integrations.
git clone https://github.com/dmeldrum6/csharp-mcp-tools
cd csharp-mcp-tools
dotnet run --project McpToolServer.Api
# Server is now listening on http://localhost:5000- JSON-RPC endpoint:
POST http://localhost:5000/mcp - Tool browser:
GET http://localhost:5000/mcp/tools - Health check:
GET http://localhost:5000/mcp/health - Swagger UI:
http://localhost:5000/swagger
Add the following to claude_desktop_config.json
(typically ~/Library/Application Support/Claude/claude_desktop_config.json on macOS
or %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"csharp-tools": {
"transport": "http",
"url": "http://localhost:5000/mcp"
}
}
}Restart Claude Desktop. The tools will appear in the tool picker automatically.
| Tool | Description | Key Parameters |
|---|---|---|
fetch_webpage |
Fetch a URL and return its content as clean plain text (HTML stripped) | url (required), max_chars |
fetch_json |
Fetch a URL that returns JSON and return the parsed, pretty-printed result | url (required) |
post_json |
POST a JSON body to a URL and return the response | url, body (required) |
check_url |
Check the HTTP status of a URL; returns status code, final URL after redirects, and response time | url (required) |
| Tool | Description | Key Parameters |
|---|---|---|
evaluate_expression |
Evaluate a mathematical expression using NCalc (supports trig, log, sqrt, variables) | expression (required) |
unit_convert |
Convert a value between units using UnitsNet (length, mass, temperature, …) | value, from_unit, to_unit (required) |
statistics |
Compute descriptive statistics (mean, median, stddev, percentiles) for a list of numbers | values (required) |
linear_regression |
Fit a simple linear regression y = mx + b to (x, y) data points | x_values, y_values (required) |
| Tool | Description | Key Parameters |
|---|---|---|
regex_match |
Find all regex matches in text; returns positions and captured groups | pattern, text (required), flags |
regex_replace |
Replace regex matches with a substitution string (supports $1, ${name}) |
pattern, text, replacement (required) |
text_diff |
Generate a unified diff between two strings | old_text, new_text (required) |
url_encode |
URL-encode or decode a string | text (required), decode |
text_stats |
Count words, sentences, characters, lines; estimate reading time | text (required) |
base64 |
Encode or decode Base64 / Base64-URL | text (required), decode, url_safe |
html_to_text |
Convert HTML to plain text, preserving links as [text](url) |
html (required) |
| Tool | Description | Key Parameters |
|---|---|---|
now |
Return the current date and time in multiple formats and timezones | timezone |
parse_date |
Parse a date string in various formats and return normalized ISO 8601 | date (required), timezone |
date_add |
Add or subtract a duration from a date | date, amount, unit (required) |
date_diff |
Calculate the difference between two dates | date1, date2 (required), unit |
timezone_convert |
Convert a datetime from one timezone to another | datetime, from_tz, to_tz (required) |
cron_next |
Calculate the next N occurrences of a cron expression | expression (required), count, from_date |
| Tool | Description | Key Parameters |
|---|---|---|
hash |
Compute a cryptographic hash (MD5, SHA-1, SHA-256, SHA-512) | text (required), algorithm |
hmac |
Compute an HMAC using a secret key | text, key (required), algorithm |
aes_crypt |
Encrypt or decrypt a string with AES-256-CBC | text, key (required), mode |
generate_uuid |
Generate one or more UUIDs (v4) | count |
generate_password |
Generate a cryptographically secure random password | length, include_symbols |
| Tool | Description | Key Parameters |
|---|---|---|
parse_csv |
Parse a CSV string and return data as JSON | csv (required), delimiter |
convert_csv_json |
Convert between CSV and JSON array-of-objects | input (required), direction |
format_json |
Parse, validate, and pretty-print (or minify) a JSON string | json (required), minify |
convert_yaml_json |
Convert between YAML and JSON | input (required), direction |
query_json |
Run a JSONPath query against a JSON document | json, path (required) |
convert_json_xml |
Convert between JSON and XML formats | input (required), direction |
format_xml |
Parse, validate, and pretty-print (or minify) an XML string | xml (required), minify |
query_xml |
Run an XPath query against an XML document | xml, xpath (required) |
| Tool | Description | Key Parameters |
|---|---|---|
dns_lookup |
Resolve a hostname to IPs, or look up DNS record types | host (required), type |
reverse_dns |
Resolve an IP address to a hostname | ip (required) |
ping |
Ping a host and return round-trip time and packet loss | host (required), count |
check_port |
Check whether a TCP port is open on a host | host, port (required) |
| Tool | Description | Key Parameters |
|---|---|---|
run_csharp |
Execute C# via the Roslyn scripting engine; returns stdout and return value | code (required), timeout_seconds, imports |
evaluate_js |
Evaluate JavaScript using the Jint engine (ECMAScript 2020) | code (required), timeout_seconds |
run_sql |
Execute SQL against a temporary in-memory SQLite database | query_sql (required), setup_sql, timeout_seconds |
| Tool | Description | Key Parameters |
|---|---|---|
read_file |
Read a text file from the sandbox | path (required) |
write_file |
Write text content to a file in the sandbox | path, content (required) |
list_files |
List files and directories in the sandbox | path |
delete_file |
Delete a file or empty directory from the sandbox | path (required) |
zip_files |
Create a ZIP archive from files in the sandbox | files, output_path (required) |
unzip_file |
Extract a ZIP archive in the sandbox | path, output_dir (required) |
| Tool | Description | Key Parameters |
|---|---|---|
image_info |
Return image metadata: dimensions, format, color space, file size | url or base64 (required) |
image_resize |
Resize an image by dimensions or scale factor; returns base64 | image, width/height or scale |
image_convert |
Convert an image to a different format (PNG, JPEG, WebP, …) | image, format (required) |
markdown_to_html |
Render Markdown text to HTML | markdown (required) |
extract_text |
Extract readable text from an HTML page URL, stripping nav/ads/boilerplate | url (required) |
All settings live under the McpTools key in appsettings.json:
{
"McpTools": {
"Http": {
"TimeoutSeconds": 30,
"UserAgent": "McpToolServer/1.0",
"MaxResponseBytes": 5242880
},
"FileSystem": {
"SandboxPath": "/tmp/mcp-sandbox",
"MaxFileSizeBytes": 10485760,
"MaxTotalSandboxBytes": 104857600
},
"CodeExecution": {
"CSharpTimeoutSeconds": 10,
"JsTimeoutSeconds": 5,
"SqlTimeoutSeconds": 10
},
"Limits": {
"MaxRequestBodyBytes": 1048576
}
}
}Settings are bound to McpToolsOptions at startup and injected as IOptions<McpToolsOptions>.
File system operations are restricted to the configured sandbox directory. Path
traversal attempts (e.g. ../etc/passwd) are rejected before any I/O occurs.
C# execution (run_csharp) uses a text-based blocklist to reject common escape
patterns (System.IO, System.Net, System.Reflection, System.Diagnostics.Process,
Environment.Exit, AppDomain). This is not an OS-level sandbox — do not expose it
to untrusted callers without additional host isolation (containers, gVisor, seccomp).
JavaScript execution (evaluate_js) runs inside Jint,
a pure .NET interpreter with no built-in file system or networking. The blocklist also
rejects require(), import, fetch(), and XMLHttpRequest.
SQL execution (run_sql) runs against an in-memory SQLite database that is discarded
after each request. ATTACH, DETACH, .load, and PRAGMA are blocked.
Transport security: By default the server listens on HTTP. In production, place it behind a reverse proxy (nginx, Caddy) that terminates TLS, enforces authentication, and rate-limits requests.
# Unit + non-Integration tests (recommended for CI)
dotnet test --filter "Category!=Integration"
# Full test suite (requires network access)
dotnet test| Project | Type | Purpose |
|---|---|---|
McpToolServer.Api |
ASP.NET Core Web API | HTTP endpoint, routing, middleware, Swagger |
McpToolServer.Tools |
Class library | All 52 tool implementations, registry, core interfaces |
McpToolServer.Tests |
xUnit | Integration and unit tests |
See CLAUDE.md for the full developer guide including how to add new tools.