MCP Local LLM Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Local LLM ServerExplain quantum computing in simple terms"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Local LLM Server
A FastMCP server that exposes a locally-hosted llama.cpp language model as MCP tools, plus a suite of utility tools for weather, news, web fetching, file I/O, stock data, summarization, and more.
Overview
This server lets any MCP-compatible client (e.g. Claude Desktop, Cursor) use a local GGUF model for text generation and chat, without sending data to an external API. The model is served by a llama-server subprocess; the MCP server communicates with it over a local HTTP port.
src/
├── llm_server.py # Entry point, argument parsing, server startup
├── model.py # llama-server lifecycle, token generation
├── upload.py # POST /upload endpoint for PDF and Markdown file uploads
├── resources.py # MCP resource: llm://info
└── tools/
├── generate.py # Tool: generate
├── chat.py # Tool: chat
├── weather.py # Tool: get_weather
├── date_time.py # Tool: get_datetime
├── fetch_url.py # Tool: fetch_url
├── news.py # Tool: news_headlines
├── read_pdf.py # Tool: read_pdf
├── read_markdown.py # Tool: read_markdown
├── create_file.py # Tool: create_file
├── list_directory.py# Tool: list_directory
├── stock_price.py # Tool: get_stock_price
├── summarize.py # Tool: summarize_text
├── agent.py # Tool: run_agent (autonomous ReAct agent)
├── explain_code.py # Tool: explain_code (coding tutor)
├── review_code.py # Tool: review_code (coding tutor)
├── coding_tutor.py # Tool: coding_tutor (orchestrating tutor agent)
├── transcribe_audio.py # Tool: transcribe_audio
├── text_to_speech.py # Tool: text_to_speech
├── word_definition.py # Tool: define_word
└── random_joke.py # Tool: get_random_jokeRelated MCP server: MCP Tool Server
Requirements
Python 3.10+
A
llama-serverbinary from llama.cppA GGUF model file (e.g.
models/Qwen2.5-7B-Instruct-Q4_K_M.gguf)CUDA-capable GPU recommended for large models
Install dependencies:
pip install -r requirements.txtOn Windows, IANA timezone data is not bundled with Python. Install it for the get_datetime tool to support non-UTC timezones:
pip install tzdataThe transcribe_audio tool requires faster-whisper, which is listed in requirements.txt but has an optional CUDA-accelerated variant. For GPU inference, install the matching PyTorch CUDA build first:
# CPU-only (default)
pip install faster-whisper
# GPU (CUDA 12)
pip install faster-whisper
pip install torch --index-url https://download.pytorch.org/whl/cu128Configuration
Some tools require API keys. Create a .env file in the project root (already gitignored):
NEWSAPI_KEY=your_key_hereThe server loads this file automatically on startup.
Variable | Required by | Where to get it |
|
| newsapi.org — free tier available |
All other tools work without any API key.
Starting the Server
stdio transport (for MCP clients like Claude Desktop)
python src/llm_server.py \
--model models/Qwen2.5-7B-Instruct-Q4_K_M.gguf \
--llama-server /path/to/llama-serverHTTP transport (for network clients or testing with curl)
python src/llm_server.py \
--model models/Qwen2.5-7B-Instruct-Q4_K_M.gguf \
--llama-server /path/to/llama-server \
--transport http \
--port 5174CLI flags
Flag | Default | Description |
| (required) | Path to a |
| (required) | Path to the |
|
|
|
|
| Host to bind for HTTP transport (use |
|
| MCP server port (HTTP transport only) |
|
| Port for the internal llama-server backend |
|
| Layers to offload to GPU; |
|
| Total context window in tokens (prompt + output combined) |
HTTP Endpoints
These endpoints are only available when using --transport http.
POST /upload
Upload a PDF or Markdown file to the server and receive an upload_id to pass to run_agent.
Supported types: .pdf, .md, .markdown
Request: multipart/form-data with a single field named file.
Response:
{
"upload_id": "3f8a1c...",
"filename": "report.pdf",
"size": 84210
}Uploaded files are stored in uploads/ at the project root and deleted when the server shuts down.
Example:
curl -X POST http://localhost:5174/upload \
-F "file=@/path/to/report.pdf"
curl -X POST http://localhost:5174/upload \
-F "file=@/path/to/notes.md"Tools
generate
Generate text from a raw prompt. The input prompt is not included in the returned text.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Input text to continue |
|
|
| Maximum tokens to generate |
|
|
| Sampling temperature; |
|
|
| Nucleus-sampling cumulative probability cutoff |
|
|
| Top-k vocabulary filter; |
|
|
| Penalty for repeating tokens; |
|
|
| Strings that halt generation when produced |
|
|
| RNG seed for reproducible outputs |
Returns: The generated text as a plain string.
Example
{
"prompt": "The capital of France is",
"max_new_tokens": 50,
"temperature": 0
}chat
Chat with the local LLM using a conversation history.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Conversation history. Valid roles: |
|
|
| Maximum tokens to generate |
|
|
| Sampling temperature; |
|
|
| Nucleus-sampling cumulative probability cutoff |
|
|
| Top-k vocabulary filter; |
|
|
| Penalty for repeating tokens; |
|
|
| Strings that halt generation when produced |
|
|
| RNG seed for reproducible outputs |
Returns: The assistant's reply as plain text.
Example
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the Eiffel Tower?"}
],
"temperature": 0.7,
"max_new_tokens": 256
}get_weather
Fetch current weather for any location using the free Open-Meteo API. No API key required.
Parameters
Parameter | Type | Default | Description |
|
| (required) | City name or region (e.g. |
|
|
|
|
Returns: Current conditions, temperature, humidity, and wind speed.
Example output
Weather in London, England, United Kingdom:
Conditions: Partly cloudy
Temperature: 12.3°C
Humidity: 74%
Wind: 18.5 km/hget_datetime
Return the current date and time for any IANA timezone. No API key required.
Parameters
Parameter | Type | Default | Description |
|
|
| IANA timezone name (e.g. |
Returns: A formatted date/time string, e.g. "2025-03-01 14:30:00 EST (UTC-0500)".
Windows note: Non-UTC timezones require
pip install tzdata.
Example
{"timezone": "America/Chicago"}fetch_url
Fetch the content of any URL and return it as plain text. HTML pages are stripped of tags; JSON and plain-text responses are returned as-is. No API key required.
Parameters
Parameter | Type | Default | Description |
|
| (required) | URL to fetch (must start with |
|
|
| Maximum characters to return before truncating |
Returns: Extracted page text, truncated to max_chars if needed. Returns a descriptive error string on connection failure rather than raising an exception.
Example
{
"url": "https://en.wikipedia.org/wiki/Python_(programming_language)",
"max_chars": 2000
}news_headlines
Fetch the latest news headlines, optionally filtered by topic. Requires a free NewsAPI key.
Parameters
Parameter | Type | Default | Description |
|
|
| Keyword(s) to filter by (e.g. |
|
|
| 2-letter country code used when |
|
|
| Number of headlines to return (1–10) |
Returns: Numbered list of headlines with source, publication date, and URL.
Example
{"topic": "artificial intelligence", "max_results": 3}Example output
1. [BBC News] OpenAI releases new model
Published: 2025-03-01
https://bbc.co.uk/...
2. [Reuters] ...read_pdf
Extract and return the text content of a PDF file, organised by page. Image-only (scanned) PDFs return a clear message rather than empty output.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Absolute or relative path to the PDF file |
|
|
| Maximum characters to return before truncating |
Returns: Extracted text organised by page, truncated to max_chars if needed.
Example
{"file_path": "/home/user/documents/report.pdf", "max_chars": 10000}read_markdown
Read and return the contents of a Markdown file.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Absolute or relative path to the |
|
|
| Maximum characters to return before truncating |
Returns: The file's text content, truncated to max_chars if needed.
Example
{"file_path": "/home/user/documents/notes.md"}create_file
Create a new file with the given name and content. Rejects path traversal attempts and validates the filename before writing.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Basename of the file to create (no path separators allowed) |
|
| (required) | Text content to write to the file |
|
|
| Subdirectory to create the file in (relative to the server's working directory). Created if it doesn't exist |
|
|
| Character encoding for the file |
|
|
| If |
Returns: A JSON object with keys:
success—trueif the file was createdfile_path— absolute path to the created file (nullon failure)error— error message ifsuccessisfalsemessage— human-readable status
Examples
{"file_name": "notes.md", "content": "# My Notes\n"}{
"file_name": "config.json",
"content": "{\"debug\": true}",
"directory": "src",
"overwrite": true
}list_directory
List the files and directories at a given path, with optional glob filtering and recursive traversal.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Absolute or relative path to the directory to list |
|
|
| Glob pattern to filter results (e.g. |
|
|
| If |
|
|
| If |
|
|
| Maximum number of entries to return |
Returns: A formatted listing showing [DIR] and [FILE] entries with file sizes, plus a summary count. Truncation is noted if max_results is reached.
Examples
{"path": "/home/user/projects"}{
"path": "/home/user/projects/mcp-server",
"pattern": "*.py",
"recursive": true
}Example output
Directory: /home/user/projects/mcp-server/src
[DIR] tools/
[FILE] llm_server.py (4 KB)
[FILE] model.py (7 KB)
[FILE] resources.py (1 KB)
[FILE] upload.py (2 KB)
4 item(s) shownget_stock_price
Get the current stock price and key market data for a ticker symbol via the Yahoo Finance API. No API key required.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Stock ticker symbol (e.g. |
Returns: Current price, daily change, day range, 52-week range, volume, and market cap.
Example
{"ticker": "NVDA"}Example output
NVIDIA Corp (NVDA)
Price: 875.40 USD
Change: +12.30 (+1.43%)
Prev close: 863.10 USD
Day range: 860.00 – 879.50 USD
52-wk range: 410.00 – 974.00 USD
Volume: 42,381,200
Market cap: 2.16T USDTip: Crypto pairs are also supported (e.g.
"BTC-USD","ETH-USD").
summarize_text
Summarize a block of text using the local LLM. Long texts are automatically split into chunks, each summarized independently, then merged into a single coherent summary.
Parameters
Parameter | Type | Default | Description |
|
| (required) | The text to summarize. Can be arbitrarily long |
|
|
| Optional instruction to guide the summary (e.g. |
|
|
| Approximate maximum length of the summary in tokens. Controls verbosity |
Returns: A concise summary of the input text.
Examples
{"text": "... (long article) ..."}{
"text": "... (meeting transcript) ...",
"focus": "action items",
"max_length": 150
}{
"text": "... (technical document) ...",
"focus": "key risks",
"max_length": 300
}transcribe_audio
Transcribe an audio file to text using a local Whisper model via faster-whisper. Runs entirely on-device — no API key or internet connection required. Models are downloaded automatically on first use and cached locally.
Supported formats: mp3, mp4, wav, flac, ogg, m4a, webm, and most ffmpeg-readable formats.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Absolute or relative path to the audio file |
|
|
| Whisper model to use: |
|
|
| ISO-639-1 language code to force (e.g. |
|
|
| Inference device. |
|
|
| Precision. |
Returns: A JSON object with keys:
success—trueif transcription succeededtext— the transcribed text (nullon failure)language— detected or forced language codeduration_seconds— audio duration in secondserror— error message ifsuccessisfalse
Examples
{"audio_path": "/home/user/recordings/meeting.mp3"}{
"audio_path": "/home/user/recordings/lecture.wav",
"model_size": "small",
"language": "en"
}Tip: Use
"tiny"or"base"for fast transcription of short clips. Use"small"or higher for better accuracy on noisy audio or non-English speech.
run_agent
Run an autonomous ReAct agent powered by the local LLM. The agent reasons step by step and calls tools as many times as needed before producing a final answer.
How it works
User goal
↓
LLM decides: call a tool or answer?
↓ (if tool)
Tool executes → result fed back to LLM
↓
LLM decides again … (repeats up to max_steps)
↓ (when done)
FINAL answer returnedParameters
Parameter | Type | Default | Description |
|
| (required) | The task or question for the agent to solve |
|
|
| Maximum tool-call iterations before stopping |
|
|
| Token ceiling per LLM call. Mainly affects the length of the final answer |
|
|
| Recent assistant+tool rounds to keep in full; older rounds are summarised |
|
|
|
|
|
|
| ID returned by |
Returns: The agent's final answer as plain text.
If you see
Agent stopped after N steps without a FINAL answer, the agent exhausted its iterations. Either increasemax_stepsor simplify the goal.
Tools available to the agent
Tool | Description |
| Fetch current weather for any city |
| Get the current date and time in any timezone |
| Fetch and extract text from any URL |
| Fetch the latest news headlines by topic |
| Extract text from a PDF file at a given path |
| Read the contents of a Markdown file at a given path |
| Get the current stock price and market data for a ticker symbol |
| Summarize a block of text using the local LLM |
| Create a new file with the given name and content |
| List files and directories at a given path |
| Transcribe an audio file to text using a local Whisper model |
Examples
{"goal": "What should I wear in Paris today?"}{"goal": "Compare the weather in London and Tokyo, then tell me which city is warmer."}{"goal": "Summarise this document", "upload_id": "3f8a1c..."}{
"goal": "What are the top AI news stories today?",
"max_steps": 5
}text_to_speech
Convert text to an MP3 audio file using Google Text-to-Speech (gTTS). Requires an internet connection. No API key required.
Dependency: Install
gTTSbefore using this tool:pip install gtts
Parameters
Parameter | Type | Default | Description |
|
| (required) | The text to convert to speech |
|
| (required) | File path where the MP3 will be saved (e.g. |
|
|
| BCP-47 language code (e.g. |
|
|
| If |
Returns: A JSON object with keys:
success—trueif the file was saved successfullyoutput_path— absolute path to the saved MP3 (nullon failure)error— error message ifsuccessisfalse
Examples
{
"text": "Hello, world!",
"output_path": "output/hello.mp3"
}{
"text": "Bonjour le monde",
"output_path": "output/bonjour.mp3",
"lang": "fr",
"slow": true
}define_word
Look up the definition, phonetics, synonyms, and antonyms of an English word using the free Dictionary API. No API key required.
Parameters
Parameter | Type | Default | Description |
|
| (required) | The English word to look up (e.g. |
Returns: A JSON object with keys:
success—trueif the word was foundword— the normalised word that was looked upresults— list of meanings, each containing:phonetic— IPA phonetic spelling (may benull)part_of_speech— e.g."noun","verb","adjective"definitions— up to 3 definitions, each withdefinition,example(may benull),synonyms(up to 5),antonyms(up to 5)synonyms— up to 5 synonyms for this part of speechantonyms— up to 5 antonyms for this part of speech
error— error message ifsuccessisfalse
Example
{"word": "ephemeral"}Example output (abbreviated)
{
"success": true,
"word": "ephemeral",
"results": [
{
"phonetic": "/ɪˈfɛm(ə)r(ə)l/",
"part_of_speech": "adjective",
"definitions": [
{
"definition": "Lasting for a very short time.",
"example": "fashions are ephemeral",
"synonyms": ["transitory", "transient", "fleeting"],
"antonyms": ["permanent", "eternal"]
}
],
"synonyms": ["transitory", "transient"],
"antonyms": ["permanent"]
}
],
"error": null
}get_random_joke
Fetch a random joke from the free JokeAPI. No API key required.
Parameters
Parameter | Type | Default | Description |
|
|
| Joke category: |
|
|
| Format filter: |
|
|
| If |
Returns: A JSON object with keys:
success—trueif a joke was returnedcategory— the category the joke belongs totype—"single"or"twopart"joke— the joke text; two-part jokes are formatted as"setup\n\n— delivery"error— error message ifsuccessisfalse
Note: The
"Dark"category is unavailable whensafe_modeistrue.
Examples
{"category": "Programming"}{
"category": "Pun",
"joke_type": "twopart",
"safe_mode": true
}Coding Tutor Tools
Three tools that turn the server into an interactive programming tutor. The high-level entry point is coding_tutor; the two supporting tools (explain_code, review_code) can also be called directly.
coding_tutor
An autonomous ReAct agent specialised for teaching. It reasons step by step, calling explain_code, review_code, and fetch_url as needed, then produces a pedagogical response.
Parameters
Parameter | Type | Default | Description |
|
| (required) | Your coding question, code snippet, or error message |
|
|
| Maximum tool-call iterations before stopping |
|
|
| Token ceiling per LLM call |
|
|
| Recent assistant+tool rounds to keep before older ones are summarised |
|
|
|
|
Returns: A teaching response as plain text.
Tools available to the tutor
Tool | Description |
| Explain a code snippet at the learner's skill level |
| Review code for bugs, style, security, or performance issues |
| Fetch documentation or a GitHub link referenced by the learner |
Examples
{"question": "Why does my list comprehension give the wrong result?\n\nresult = [x * 2 for x in [1, 2, 3] if x > 1]"}{"question": "Explain the difference between a shallow copy and a deep copy in Python, with examples."}Tip: The tutor infers skill level from your question — use plain language for beginner explanations, technical terminology for advanced ones.
explain_code
Explain a code snippet using the local LLM, tailored to the learner's skill level.
Parameters
Parameter | Type | Default | Description |
|
| (required) | The source code to explain (capped at 6 000 chars) |
|
|
| Programming language of the snippet |
|
|
| Explanation depth: |
|
|
| Maximum tokens for the explanation |
Returns: A plain-text explanation of the code.
Example
{
"code": "result = {k: v for k, v in zip(keys, values)}",
"language": "python",
"level": "beginner"
}review_code
Review a code snippet for issues. Outputs a structured report: overall impression, numbered issues with severity, positives, and a top recommendation.
Parameters
Parameter | Type | Default | Description |
|
| (required) | The source code to review (capped at 6 000 chars) |
|
|
| Programming language of the snippet |
|
|
| Review focus: |
|
|
| Maximum tokens for the review |
Returns: A structured review with four sections: Overall Impression, Issues Found, Positives, and Top Recommendation.
Example
{
"code": "def get_user(id):\n return db.execute(f'SELECT * FROM users WHERE id={id}')",
"language": "python",
"focus": "security"
}Resources
llm://info
Returns metadata about the currently loaded model (path, context size, GPU layers).
Configuring with Claude Desktop
Add the server to your claude_desktop_config.json:
{
"mcpServers": {
"local-llm": {
"command": "python",
"args": [
"src/llm_server.py",
"--model", "models/Qwen2.5-7B-Instruct-Q4_K_M.gguf",
"--llama-server", "/path/to/llama-server"
],
"cwd": "/absolute/path/to/mcp-server"
}
}
}Notes
The model is loaded once at startup via
llama-serverand held in memory for the lifetime of the server.GPU offloading is controlled by
--gpu-layers;-1offloads all layers.--context-sizesets the total token budget shared between prompt and generated output. Increase it if you experience truncation on long responses.The HTTP transport binds to
0.0.0.0by default, making it accessible from other machines on the network. Use--host 127.0.0.1to restrict to localhost. CORS is enabled for all origins — restrictallow_originsbefore exposing to untrusted networks.Uploaded files (
POST /upload) are stored inuploads/at the project root and automatically deleted on server shutdown.
Running a standalone llama-server (e.g. for opencode)
llama-server \
--model /path/to/model.gguf \
--port 8000 \
--host 127.0.0.1 \
--n-gpu-layers -1 \
--ctx-size 16384 \
--no-mmapThis server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jrgtwo/mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server