FieldCure MCP Essentials
Install once, get the basics. A Model Context Protocol (MCP) server that provides 20 essential tools — HTTP requests, web search & fetch, URL file downloads, Wolfram|Alpha computational knowledge, shell commands, JavaScript execution, file I/O, environment info, and persistent memory — for any MCP client. Category search (news, images, scholar, patents) and runtime engine switching (get/set) are always available; capabilities are guarded at invocation time against the active engine. Built with C# and the official MCP C# SDK.
Features
- 20 essential tools — HTTP, web search & fetch, URL file downloads, runtime search-engine switching (get/set), Wolfram|Alpha, shell, JavaScript sandbox, environment info, file read/write/search, persistent memory + category search (news, images, scholar, patents)
- Zero configuration — no API keys needed for default Bing search; optional API keys unlock Serper, Tavily, SerpApi (+ category search tools), and Wolfram|Alpha
- Document parsing —
web_fetchandread_fileextract text from PDF, DOCX, HWPX, PPTX, XLSX into Markdown. PDF text extraction is text-layer only; scanned PDFs without a text layer yield empty text. For OCR-backed indexing usefieldcure-mcp-rag. - Sandboxed JavaScript — Jint engine with strict limits (timeout, statement count, recursion depth)
- SSRF protection — HTTP requests, web fetch, and file downloads block private IP ranges and loopback addresses
- Cross-client — works with Claude Desktop, VS Code, AssistStudio, and any MCP-compatible client
- Stdio transport — standard MCP subprocess model via JSON-RPC over stdin/stdout
Installation
dotnet tool install -g FieldCure.Mcp.Essentials
After installation, the fieldcure-mcp-essentials command is available globally.
From source
git clone https://github.com/fieldcure/fieldcure-mcp-essentials.git
cd fieldcure-mcp-essentials
dotnet build
Requirements
- .NET 8.0 Runtime or later
Tools
| Tool | Description | Destructive |
|---|---|---|
http_request | Full HTTP client (GET/POST/PUT/DELETE/PATCH/HEAD) with custom headers and body | — |
web_search | Search the web and return snippets (title, URL, description) | — |
web_fetch | Fetch a URL and extract content as Markdown — HTML pages and documents (PDF, DOCX, HWPX, PPTX, XLSX) | — |
download_file | Download URL content to disk with a configurable download directory, 100 MB limit, and atomic save | Yes |
run_command | Execute shell commands with working directory, environment variables, shell selection, and output truncation flags | Yes |
run_javascript | Sandboxed JavaScript execution (Jint) for math, data processing, JSON, regex | — |
wolfram_alpha | Wolfram|Alpha Full Results API — symbolic math, plots, unit conversions, constants; MathML passes through for native rendering | — |
get_environment | System info — local time, timezone, OS, hostname, username, .NET version | — |
read_file | Read files — text with offset/limit, documents (PDF, DOCX, HWPX, PPTX, XLSX) parsed to Markdown | — |
write_file | Write or append text to files with auto directory creation | Yes |
search_files | Search files by glob pattern and content (grep-like) | — |
remember | Store a key-value memory (persisted in SQLite) | — |
forget | Delete memories by key or keyword search | Yes |
list_memories | Search and list stored memories with FTS5 and pagination | — |
Category Search (SerpApi / Serper / Tavily)
Always registered. Each tool runtime-guards on the active engine's capabilities and returns a descriptive error pointing at set_search_engine when the current engine does not support the category.
| Tool | Description | SerpApi | Serper | Tavily |
|---|---|---|---|---|
search_news | Search recent news articles via Google News | Yes | Yes | Yes |
search_images | Search images with size/type filtering | Yes | Yes | — |
search_scholar | Search academic papers with citation counts | Yes | Yes | — |
search_patents | Search patent documents with inventor/assignee filtering | Yes | Yes | — |
Runtime engine switching
| Tool | Description |
|---|---|
set_search_engine | Switch the active engine (bing, duckduckgo, serper, tavily, serpapi) at runtime. Paid-engine API keys resolve lazily via env var or MCP Elicitation on the next search; the switch itself takes only the engine name. Emits notifications/tools/list_changed on success. |
get_search_engine | Return the currently active engine and its category capabilities. Read-only; use this to reflect live engine state in host UIs or to check category support before calling a category search tool. |
web_search vs web_fetch vs download_file vs http_request
http_request | web_search | web_fetch | download_file | |
|---|---|---|---|---|
| Purpose | API calls, raw HTTP | Web search | Read web pages | Save original files |
| Response | Raw (JSON, HTML, etc.) | {title, url, snippet}[] | Markdown (body only) | JSON metadata with saved path |
| Conversion | None | None | SmartReader HTML → Markdown | None |
| Length limit | max_response_chars (default: unlimited, up to 1MB) | max_results (max 10) | max_length (max 20000) | 100 MB |
Document Parsing
web_fetch and read_file can parse binary documents into Markdown:
| Format | Extension | Detection |
|---|---|---|
.pdf | Content-Type / URL extension (text layer only; no OCR) | |
| Word | .docx | Content-Type / URL extension |
| Hangul (HWPX) | .hwpx | URL extension (no standard Content-Type) |
| PowerPoint | .pptx | Content-Type / URL extension |
| Excel | .xlsx | Content-Type / URL extension |
Output includes headings, tables, math expressions ([math: LaTeX]), and slide/page separators.
File Downloads
download_file saves the original bytes from an HTTP(S) URL. If save_path is omitted, the tool infers a filename from Content-Disposition, the URL path, or a generated fallback name. Relative save_path values resolve under the configured download_directory; absolute paths are used as-is except for protected system directories.
The default download directory is ~/Downloads/mcp and is created automatically on first use. Downloads are written to a temporary file in the destination directory and then committed with an atomic move/replace, so failed or cancelled downloads do not leave a partial final file.
{
"url": "https://example.com/report.pdf"
}
{
"url": "https://example.com/report.pdf",
"save_path": "reports/report.pdf",
"overwrite": false
}
Web Search
Default engine is Bing (free, no API key needed). For more reliable results, use an API-based engine:
| Engine | Free Tier | Category Search | API Key |
|---|---|---|---|
| Bing (default) | Unlimited (scraping) | — | Not needed |
| Serper | 2,500 one-time | news, images, scholar, patents | serper.dev |
| SerpApi | 100/month | news, images, scholar, patents | serpapi.com |
| Tavily | 1,000/month | news | tavily.com |
# Use Serper
fieldcure-mcp-essentials --search-engine serper --search-api-key YOUR_KEY
# Use Tavily
fieldcure-mcp-essentials --search-engine tavily --search-api-key YOUR_KEY
# Or via environment variables
ESSENTIALS_SEARCH_ENGINE=serper ESSENTIALS_SEARCH_API_KEY=xxx fieldcure-mcp-essentials
Environment Variable Auto-Detection
When --search-engine is omitted, the server scans environment variables and automatically selects the best available engine:
| Engine | Environment Variable |
|---|---|
| Serper | SERPER_API_KEY |
| SerpApi | SERPAPI_API_KEY |
| Tavily | TAVILY_API_KEY |
Detection priority: Serper → SerpApi → Tavily → Bing/DuckDuckGo fallback.
API Key Security
| Engine | Auth Method | Key Exposure |
|---|---|---|
| Serper | HTTP header (X-API-KEY) | Not in URL |
| Tavily | Authorization header (Bearer token) | Not in URL |
| SerpApi | URL query parameter (api_key=xxx) | Visible in server logs |
Region
Use the region parameter for localized results:
// Korean results
{ "query": "서울 맛집", "region": "ko-kr" }
// US English results
{ "query": "best restaurants NYC", "region": "en-us" }
// Global (default)
{ "query": "Python tutorial" }
Without --search-engine, a fallback engine (Bing → DuckDuckGo) auto-switches on CAPTCHA. Free engines rely on scraping and may be intermittent — an API-based engine is strongly recommended for any non-trivial use.
Explicit paid engine without a key — MCP Elicitation
When --search-engine serper|tavily|serpapi is selected explicitly but no API key is configured (CLI arg, ESSENTIALS_SEARCH_API_KEY, or engine-specific env var), the server waits until the first web_search call and then asks the MCP client for the key via MCP Elicitation. If the user declines, a follow-up prompt asks whether to run the search with free Bing/DuckDuckGo instead. Declining both lets the tool soft-fail with a clear message so the LLM can recover.
Clients without Elicitation support (including older CLI hosts) fall back to the free engine immediately, matching the pre-2.1 behaviour. Cached keys live for the process lifetime; the host can re-elicit after an upstream 401/403 if the tool invalidates the cache.
Wolfram|Alpha
wolfram_alpha calls the Full Results API v2 and returns mixed content — plaintext, MathML (passed through verbatim for clients that render MathML natively, e.g. ChatPanel/WebView2), and plot images embedded as ImageContent. The API's reinterpret=true flag is always on so most typo-level failures auto-correct server-side; only real parse failures surface isError: true with assumptions > tips > didyoumeans guidance.
AppID
Set WOLFRAM_APPID to the AppID obtained at developer.wolframalpha.com (select "Full Results API"; free tier: 2,000 calls/month, non-commercial). On MCP clients that support Elicitation the key can also be supplied interactively on first use. A rejected AppID (401/403) triggers a single invalidate-and-retry so a mistyped key can be re-elicited; the existing ApiKeyResolverRegistry re-elicit cap (2 per env-var slot) prevents loops.
⚠️ Use
developer.wolframalpha.com, notdeveloper.wolfram.com— the latter is a separate paid portal and will show "no permission to access any API keys" for free accounts.
The tool is always registered regardless of AppID status; without a key it returns a setup-guidance error so the model can inform the user instead of silently skipping.
Query tips (surfaced in the tool description)
- English only, simplified keyword form (
'France population', not'how many people live in France') - Exponent notation
6*10^14, never6e14 - Single-letter variables (
x,y,n) - Named physical constants (
'speed of light', not299792458) - For equations with units, solve without units first
RECOMMENDED / AVOIDhints steer the model — simple arithmetic torun_javascript, general web queries toweb_search, subjective/news questions away from Wolfram
JavaScript Sandbox
run_javascript uses the Jint engine with strict limits:
| Constraint | Value |
|---|---|
| Timeout | 5s default, 30s max |
| Max statements | 100,000 |
| Recursion depth | 64 |
| Strict mode | Enforced |
Allowed: Math.*, JSON, Date, RegExp, console.log, string/array methods, parseInt, encodeURIComponent, atob/btoa
Blocked: setTimeout, setInterval, require, import, .NET interop, eval()
Variables can be injected into the script scope for data pipeline use:
1. http_request(url: "https://api.example.com/data") → {"items": [...]}
2. run_javascript(
code: "data.items.filter(x => x.price > 100).map(x => x.name)",
variables: {"data": {"items": [...]}}
)
Run Command
run_command defaults to the backward-compatible shell for the host: cmd.exe on Windows and /bin/sh on Unix. Use shell when a command requires specific syntax:
| Shell | Notes |
|---|---|
auto | Default; cmd.exe on Windows, /bin/sh on Unix |
pwsh | PowerShell Core; recommended for PowerShell-native commands when installed |
powershell | Windows PowerShell fallback for Windows hosts without pwsh |
cmd | Explicit Windows cmd.exe |
bash | Explicit Bash when available |
sh | Explicit POSIX shell when available |
Verbose output is capped per stream with max_output_chars (default 100,000). Responses include shell_used, stdout_truncated, and stderr_truncated; truncated streams include an inline marker with the omitted character count.
Memory
Memories are stored in SQLite (%LOCALAPPDATA%/FieldCure/Mcp.Essentials/memory.db) and shared across all MCP clients on the same machine.
# Custom memory path
fieldcure-mcp-essentials --memory-path /path/to/memory.db
# Or via environment variable
ESSENTIALS_MEMORY_PATH=/path/to/memory.db fieldcure-mcp-essentials
Configuration
Essentials settings
The default settings file is:
- Windows:
%LOCALAPPDATA%/FieldCure/Mcp.Essentials/settings.json - macOS/Linux: the platform local app-data folder plus
FieldCure/Mcp.Essentials/settings.json
{
"download_directory": "~/Downloads/mcp"
}
Download directory precedence is:
- CLI:
--download-directory <path> - Environment:
ESSENTIALS_DOWNLOAD_DIRECTORY - Settings file:
download_directory - Default:
~/Downloads/mcp
Use --settings-path <path> or ESSENTIALS_SETTINGS_PATH to point at a different settings file.
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"essentials": {
"command": "fieldcure-mcp-essentials"
}
}
}
With a search engine:
{
"mcpServers": {
"essentials": {
"command": "fieldcure-mcp-essentials",
"args": ["--search-engine", "serper", "--search-api-key", "YOUR_KEY"]
}
}
}
VS Code (Copilot)
Add to .vscode/mcp.json:
{
"servers": {
"essentials": {
"command": "fieldcure-mcp-essentials"
}
}
}
From source (without dotnet tool)
{
"mcpServers": {
"essentials": {
"command": "dotnet",
"args": [
"run",
"--project", "C:\\path\\to\\fieldcure-mcp-essentials\\src\\FieldCure.Mcp.Essentials"
]
}
}
}
Data Storage
| Data | Location |
|---|---|
| Memory database | %LOCALAPPDATA%/FieldCure/Mcp.Essentials/memory.db |
| Settings file | %LOCALAPPDATA%/FieldCure/Mcp.Essentials/settings.json |
| Default downloads | ~/Downloads/mcp |
| Search API keys | Environment variables (SERPER_API_KEY, TAVILY_API_KEY, SERPAPI_API_KEY) |
Project Structure
src/FieldCure.Mcp.Essentials/
├── Program.cs # MCP server entry point (stdio)
├── Configuration/
│ └── EssentialsSettings.cs # Server settings and download directory resolution
├── Http/
│ └── SsrfGuard.cs # SSRF protection (shared by http_request & web_fetch)
├── Memory/
│ └── MemoryStore.cs # SQLite + FTS5 memory storage
├── Search/
│ ├── ISearchEngine.cs # Search engine interface
│ ├── ICategorySearchEngine.cs # Category search interface (news, images, scholar, patents)
│ ├── SearchResult.cs # Search result record
│ ├── BingSearchEngine.cs # Bing scraping (default)
│ ├── DuckDuckGoSearchEngine.cs # DuckDuckGo lite scraping
│ ├── FallbackSearchEngine.cs # Auto-rotate on CAPTCHA
│ ├── SerperSearchEngine.cs # Serper.dev API (+ category search)
│ ├── TavilySearchEngine.cs # Tavily API (+ news)
│ └── SerpApiSearchEngine.cs # SerpApi API (+ category search)
└── Tools/
├── HttpRequestTool.cs # http_request
├── WebSearchTool.cs # web_search
├── WebFetchTool.cs # web_fetch (SmartReader)
├── DownloadFileTool.cs # download_file
├── CategorySearchTools.cs # search_news / search_images / search_scholar / search_patents
├── RunCommandTool.cs # run_command
├── RunJavaScriptTool.cs # run_javascript (Jint sandbox)
├── WolframAlphaTool.cs # wolfram_alpha (Full Results API, MathML pass-through)
├── GetEnvironmentTool.cs # get_environment
├── ReadFileTool.cs # read_file
├── WriteFileTool.cs # write_file
├── SearchFilesTool.cs # search_files
└── MemoryTools.cs # remember / forget / list_memories
Development
# Build
dotnet build
# Test
dotnet test
# Pack as dotnet tool
dotnet pack src/FieldCure.Mcp.Essentials -c Release
See Also
Part of the AssistStudio ecosystem.