- Inleiding
- Voorbereiding (Linux / WSL)
- LM Studio - Download en laad een model in
- Test API verbinding
- Python script - Vraag en response
- Autoit script - Vraag en response
- Python script - Vraag en response (streaming)
- Script - Vraag en response van een afbeelding
- Voorbeeld met CURL
- Voorbeeld met CURL en MCP tools
Inleiding #
Wanneer je LM studio hebt geïnstalleerd, kan je via de ingebouwde server eenvoudig communiceren via een HTTP API, daarmee zijn de mogelijkheden onbeperkt en kan je dus de LLM aanspreken vanuit elke computer, app of IOT device!
Voorbereiding (Linux / WSL) #
WSL #
WSL is een (ubuntu) Linux omgeving in Windows, deze kan men installeren via de APP store.
Zit je in een (verse) WSL prompt dan moet men eerst nog PIP (python package manager) en VENV (python virtual environment) installeren:
sudo apt install -y python3-pip python3-venv
VENV aanmaken #
Python werkt tegenwoordig met virtual environments om conflicten met bibliotheken tegen te gaan en uit te sluiten.
Maak een virtual environment aan met het commando:
python3 -m venv ~/venv
en activeer deze:
source ~/venv/bin/activate
Python OpenAI module installeren #
pip3 install openai
LM Studio – Download en laad een model in #
Download en laad een model in (bv Mistral 3 8B Q4_K_M)


Eenmaal het model geladen ga naar de “developers” TAB en zet daar “running” aan (op poort 1234)

Ps als je de server uit en weer aan zet zie je in het debug/log onderaan zoiets als:
[INFO] [LM STUDIO SERVER] Supported endpoints:
[INFO] [LM STUDIO SERVER] -> GET http://192.168.2.28:1234/v1/models
[INFO] [LM STUDIO SERVER] -> POST http://192.168.2.28:1234/v1/responses
[INFO] [LM STUDIO SERVER] -> POST http://192.168.2.28:1234/v1/chat/completions
[INFO] [LM STUDIO SERVER] -> POST http://192.168.2.28:1234/v1/completions
[INFO] [LM STUDIO SERVER] -> POST http://192.168.2.28:1234/v1/embeddings
Test API verbinding #
Test de verbinding met LM Studio via een browser ga naar localhost of het server ip om de modellijst te krijgen met de volgende URL:
http://localhost:1234/v1/models
of
http://192.168.2.28:1234/v1/models
TIP: Gebruik het IP adres (ipv localhost) ook als je vanuit een WSL omgeving wil comuniceren.
De output is een lijst met beschikbare modellen in LM studio:
{
"data": [
{
"id": "ministral-3-8b-instruct-2512",
"object": "model",
"owned_by": "organization_owner"
},
{
"id": "mistralai/ministral-3-14b-reasoning",
"object": "model",
"owned_by": "organization_owner"
},
{
"id": "ministral-3-14b-instruct-2512",
"object": "model",
"owned_by": "organization_owner"
},
{
"id": "text-embedding-nomic-embed-text-v1.5",
"object": "model",
"owned_by": "organization_owner"
},
{
"id": "deepseek/deepseek-r1-0528-qwen3-8b",
"object": "model",
"owned_by": "organization_owner"
}
],
"object": "list"
}
Python script – Vraag en response #
Hieronder vind je een eenvoudig python script die een vraag stelt via de LM Studio API en het antwoord in de console uitprint:
from openai import OpenAI
client = OpenAI(
base_url="http://192.168.2.28:1234/v1",
api_key="lm-studio"
)
MODEL = "lmstudio-community/ministral-3-8b-instruct-2512"
resp = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "user", "content": "Wat is de hoofdstad van Nederland"}
]
)
print(resp.choices[0].message.content)
Voorbeeld output:
De hoofdstad van **Nederland** is **Amsterdam**.
Hoewel Amsterdam de officiële hoofdstad is, heeft het land ook een **politieke hoofdstad**: **Den Haag**. Dit is waar de regering en het parlement zitten.
Zou je meer informatie willen over deze steden?
of:
Hoewel Amsterdam de officiële hoofdstad is, heeft het land **Den Haag** als zittende hoofdstad (de plaats waar de regering en het parlement gevestigd zijn). Amsterdam fungeert echter wel als cultureel, historisch en economisch centrum.
Wil je meer informatie over een specifiek aspect?
Ps. zorg er wel voor dat je een model ingeladen hebt anders krijg je deze foutmelding:
openai.BadRequestError: Error code: 400 - {'error': {'message': "No models loaded. Please load a model in the developer page or use the 'lms load' command.", 'type': 'invalid_request_error', 'param': 'model', 'code': None}}
Autoit script – Vraag en response #
#include <MsgBoxConstants.au3>
; =========================
; Configuratie
; =========================
Global $LMSTUDIO_URL = "http://192.168.2.36:1234/v1/chat/completions"
Global $API_KEY = "lm-studio"
Global $MODEL = "lmstudio-community/ministral-3-14b-instruct-2512"
; =========================
; JSON body opbouwen
; =========================
Global $sJson = _
'{' & _
' "model": "' & $MODEL & '",' & _
' "messages": [' & _
' {' & _
' "role": "user",' & _
' "content": "Wat is de hoofdstad van Nederland"' & _
' }' & _
' ]' & _
'}'
; =========================
; HTTP request
; =========================
Local $oHttp = ObjCreate("WinHttp.WinHttpRequest.5.1")
$oHttp.Open("POST", $LMSTUDIO_URL, False)
$oHttp.SetRequestHeader("Content-Type", "application/json")
$oHttp.SetRequestHeader("Authorization", "Bearer " & $API_KEY)
$oHttp.Send($sJson)
; =========================
; Response uitlezen
; =========================
Local $sResponse = $oHttp.ResponseText
; Debug: volledige JSON response
; MsgBox($MB_OK, "Volledige response", $sResponse)
; =========================
; Simpel antwoord extraheren
; (quick & dirty JSON parsing)
; =========================
Local $sAnswer = ""
; zoekt: "content":"...."
Local $aMatch = StringRegExp($sResponse, '"content"\s*:\s*"([^"]+)"', 1)
If IsArray($aMatch) Then
$sAnswer = $aMatch[0]
Else
$sAnswer = "Kon geen antwoord vinden in de response."
EndIf
; =========================
; Resultaat tonen
; =========================
MsgBox($MB_OK, "LM Studio antwoord", $sAnswer)
Python script – Vraag en response (streaming) #
Wil je streaming tekst voorbij zien komen zet dan Stream=True en gebruik als voorbeeld onderstaand script:
from openai import OpenAI
import sys
client = OpenAI(
base_url="http://192.168.2.28:1234/v1",
api_key="lm-studio"
)
MODEL = "lmstudio-community/ministral-3-8b-instruct-2512"
stream = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "user", "content": "Wat is de hoofdstad van Nederland"}
],
stream=True
)
# Stream woord/token voor woord naar de terminal
for chunk in stream:
delta = chunk.choices[0].delta
if delta.content:
print(delta.content, end="", flush=True)
print()
Script – Vraag en response van een afbeelding #
Hieronder een script en afbeelding om het AI model de afbeelding te laten analyseren
Sla het bestand op als bv orctest.jpg en plaats deze in dezelfde folder als het script.

Het script om de afbeelding te analyseren moet als Base64 verzonden worden (pas het IP adres aan naar eigen situatie):
from openai import OpenAI
import base64
client = OpenAI(
base_url="http://192.168.2.28:1234/v1",
api_key="lm-studio-or-mistral-key",
)
MODEL = "ministral-8b-2512"
IMAGE = "ocrtest.jpg"
# 1) Afbeelding inlezen en naar base64 encoderen
with open(IMAGE, "rb") as f:
image_bytes = f.read()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")
# 2) Versturen als data-URL
resp = client.chat.completions.create(
model=MODEL,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Wat zie je op deze foto?"},
{
"type": "image_url",
"image_url": {
"url": f"data:image/png;base64,{image_b64}"
},
},
],
}
],
max_tokens=256,
)
print(resp.choices[0].message.content)
Voorbeeld output:
Op deze foto zie ik een tekstbeeld met de volgende zin:
**"The quick brown fox jumped over the 5 lazy dogs!"**
Het is een klassieke zinsconstructie die vaak wordt gebruikt om het alfabet te oefenen of als testzin voor typersoftware en lettertypes. De zin bevat alle letters van het Engelse alfabet (a-z).
of:
Op deze foto zie je een tekstbeeld met de klassieke **ingelotte zin**:
*"The quick brown fox jumped over the five lazy dogs!"*
Het is een bekende zinsconstructie die vaak wordt gebruikt om het typen van letters te oefenen of als voorbeeldzin voor het testen van fonts en toetsers. De zin bevat alle letters van het Engelse alfabet (a-z).
Ps. installeer en gebruik hiervoor wel een LLM model die “dat”vision” ondersteunt (zoals Mistral 3), anders krijg je een foutmelding zoals:
openai.BadRequestError: Error code: 400 - {'error': 'Model does not support images. Please use a model that does.'}
Voorbeeld met CURL #
Je kan ook eenvoudig (in WSL / Linux) metr curl een json sturen, voorbeeld (pas IP en model aan aan eigen situatie):
(Kies bij voorkeur een model dat al geladen is in LM Studio)
curl http://192.168.2.36:1234/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 1234" \
-d '{
"model": "ministral-3-14b-reasoning",
"messages": [
{
"role": "developer",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Kan je mij de tijd vertellen?"
}
]
}'
Response:
{
"id": "chatcmpl-e8mfmikolcv7fy7ae0daz",
"object": "chat.completion",
"created": 1766702287,
"model": "mistralai/ministral-3-14b-reasoning",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hallo! Ik ben een AI-assistent, ontworpen om je te helpen met vragen, informatie of andere taken. Je kunt me vragen over alles, van wetenschap en geschiedenis tot hobbys en dagelijkse tips.\n\n**Wie ben jij?** Hoe kan ik je vandaag helpen?",
"tool_calls": []
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 19,
"completion_tokens": 73,
"total_tokens": 92
},
"stats": {},
"system_fingerprint": "mistralai/ministral-3-14b-reasoning"
}
Voorbeeld met CURL en MCP tools #
Hieronder staat een voorbeeld om met curl een vraag te stellen en er gebruik wordt gemaakt van MCP tools via een server en poort.
Let op: de MCP server van LM stuydio werkt alleen lokaal via de UI, niet via de API, daarnaast zit je met allerlei beveiligingsmaatregelen
De date-time tool #
(c:\lmstudio-tools\date-time\date-time.py)
import sys
import json
from datetime import datetime
from zoneinfo import ZoneInfo
def send(msg: dict) -> None:
sys.stdout.write(json.dumps(msg, ensure_ascii=False) + "\n")
sys.stdout.flush()
def is_notification(req: dict) -> bool:
# JSON-RPC notification: geen id of id == null
return ("id" not in req) or (req.get("id") is None)
def safe_id(req: dict):
# Alleen gebruiken als het echt een request is
return req.get("id")
# ========== HOOFDLOOP ==========
for line in sys.stdin:
line = line.strip()
if not line:
continue
try:
req = json.loads(line)
except Exception:
continue
method = req.get("method")
params = req.get("params") or {}
# Notifications moet je meestal NIET beantwoorden
notify = is_notification(req)
req_id = safe_id(req)
# ===== Handshake: initialize =====
if method == "initialize":
# initialize is een request (heeft id); maar wees safe
if notify:
continue
send({
"jsonrpc": "2.0",
"id": req_id,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": {"name": "date-time", "version": "1.0.0"},
"capabilities": {"tools": {"listChanged": False}}
}
})
# ===== Notification: initialized =====
elif method in ("notifications/initialized", "initialized"):
# Dit is meestal een notification → geen reply sturen
continue
# ===== tools/list =====
elif method == "tools/list":
if notify:
continue
send({
"jsonrpc": "2.0",
"id": req_id,
"result": {
"tools": [
{
"name": "date-time",
"title": "Get current date and time",
"description": (
"Geeft de huidige datum, tijd, weekdag, weeknummer en UNIX-tijd "
"voor een opgegeven IANA-tijdzone (bijv. Europe/Amsterdam). "
"Gebruik deze tool bij vragen over tijd, datum, kalenderinformatie, "
"vandaag, nu, weeknummer, of tijdzones."
),
"inputSchema": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "IANA timezone, bijv. Europe/Amsterdam",
"default": "Europe/Amsterdam"
}
},
"required": []
}
}
]
}
})
# ===== tools/call =====
elif method == "tools/call":
if notify:
continue
tool_name = params.get("name")
arguments = params.get("arguments") or {}
if tool_name == "date-time":
tzname = arguments.get("timezone", "Europe/Amsterdam")
try:
now = datetime.now(ZoneInfo(tzname))
WEEKDAGEN_NL = [
"Maandag", "Dinsdag", "Woensdag",
"Donderdag", "Vrijdag", "Zaterdag", "Zondag"
]
structured = {
"timezone": tzname,
"datetime": now.strftime("%Y-%m-%d %H:%M:%S"),
"iso": now.isoformat(),
"unix": int(now.timestamp()),
"weeknummer": now.isocalendar().week,
"weekdag": WEEKDAGEN_NL[now.weekday()]
}
text_answer = (
f"Het is nu {structured['datetime']} in tijdzone {structured['timezone']}.\n"
f"UNIX-tijd: {structured['unix']}\n"
f"Weeknummer: {structured['weeknummer']}\n"
f"Weekdag: {structured['weekdag']}"
)
send({
"jsonrpc": "2.0",
"id": req_id,
"result": {
"content": [{"type": "text", "text": text_answer}],
"structuredContent": structured,
"isError": False
}
})
except Exception as e:
send({
"jsonrpc": "2.0",
"id": req_id,
"result": {
"content": [{"type": "text", "text": f"Fout bij ophalen van de tijd: {e}"}],
"isError": True
}
})
else:
send({
"jsonrpc": "2.0",
"id": req_id,
"error": {"code": -32602, "message": f"Unknown tool: {tool_name}"}
})
else:
# Onbekende method: alleen antwoorden als het een request is
if notify:
continue
send({
"jsonrpc": "2.0",
"id": req_id,
"error": {"code": -32601, "message": f"Unknown method: {method}"}
})
MCP server #
Activeer de VENV:
source ~/venv/bin/activate
Installeer mcp-proxy
pip3 install mcp-proxy
Start de MCP server
Pas evt pad aan naar eigen situatie
mcp-proxy --port 8787 -- python /mnt/c/lmstudio-tools/date-time/date-time.py
Output voorbeeld
I 2025-12-26 01:03:14,925.925 mcp_proxy.__main__] Configured default server: python /mnt/c/lmstudio-tools/date-time/date-time.py
[I 2025-12-26 01:03:14,925.925 mcp_proxy.mcp_server] Setting up default server: python /mnt/c/lmstudio-tools/date-time/date-time.py
[I 2025-12-26 01:03:14,974.974 mcp.server.streamable_http_manager] StreamableHTTP session manager started
[I 2025-12-26 01:03:14,975.975 mcp_proxy.mcp_server] Serving MCP Servers via SSE:
[I 2025-12-26 01:03:14,975.975 mcp_proxy.mcp_server] - http://127.0.0.1:8787/sse
INFO: Started server process [2826]
INFO: Waiting for application startup.
[I 2025-12-26 01:03:14,989.989 mcp_proxy.mcp_server] Main application lifespan starting...
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8787 (Press CTRL+C to quit)
CURL gebruiken #
Gebruik nu CURL op de endpoint “responses” (niet chat completions) en laat de LLM weten dat er tools beschikbaar zijn. verwijs hierbij naar de MCP server:
curl http://192.168.2.36:1234/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "ministral-3-14b-reasoning",
"tools": [{
"type": "mcp",
"server_label": "date-time",
"server_url": "http://127.0.0.1:8787/sse",
"allowed_tools": ["date-time"]
}],
"input": "Kan je mij de tijd vertellen?"
}'
Als alles goed is ingesteld krijg je als voorbeeld deze output terug:
{
"id": "resp_01d8cea09169890ffc6e7a6c6a1d0ce911cf8af3e4c7eff2",
"object": "response",
"created_at": 1766706856,
"status": "completed",
"model": "mistralai/ministral-3-14b-reasoning",
"output": [
{
"id": "mcpl_wfqqivlw3prqhcw2q5hixf",
"type": "mcp_list_tools",
"server_label": "date-time",
"tools": [
{
"name": "date-time",
"description": "Geeft de huidige datum, tijd, weekdag, weeknummer en UNIX-tijd voor een opgegeven IANA-tijdzone (bijv. Europe/Amsterdam). Gebruik deze tool bij vragen over tijd, datum, kalenderinformatie, vandaag, nu, weeknummer, of tijdzones.",
"input_schema": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "IANA timezone, bijv. Europe/Amsterdam",
"default": "Europe/Amsterdam"
}
},
"required": []
}
}
],
"error": null
},
{
"id": "rs_jww3kekdtfarcg6fi5oxp",
"type": "reasoning",
"summary": [],
"content": [
{
"type": "reasoning_text",
"text": "De gebruiker vraagt om de huidige tijd. Ik heb een tool beschikbaar die de huidige datum, tijd, weekdag, weeknummer en UNIX-tijd kan geven voor een opgegeven IANA-tijdzone. De standaardtijdzone is Europe/Amsterdam, maar ik moet first bevestigen of de gebruiker een specifieke tijdzone heeft vermeld. In dit geval heeft de gebruiker geen tijdzone vermeld, dus ik zal de standaardtijdzone (Europe/Amsterdam) gebruiken.\n\nIk ga de `date_time` tool oproepen met de standaardtijdzone om de huidige tijd te krijgen. Vervolgens zal ik de resultaten verwerken en een leesbare antwoord formuleren voor de gebruiker. Ik moet erop letten dat het antwoord duidelijk en informatief is, inclusief de datum, tijd, weekdag en eventueel andere relevante informatie.\n\nLaten we dit uitvoeren:"
}
]
},
{
"id": "mcp_wu9co7sygnjxbveucvaaq",
"type": "mcp_call",
"server_label": "date-time",
"name": "date-time",
"arguments": "{\"timezone\":\"Europe/Amsterdam\"}",
"output": "[{\"type\":\"text\",\"text\":\"Het is nu 2025-12-26 00:54:20 in tijdzone Europe/Amsterdam.\\nUNIX-tijd: 1766706860\\nWeeknummer: 52\\nWeekdag: Vrijdag\"}]",
"error": null,
"approval_request_id": null
},
{
"id": "rs_pyzx1wog27h91brlt6g79",
"type": "reasoning",
"summary": [],
"content": [
{
"type": "reasoning_text",
"text": "De tool heeft de volgende informatie teruggegeven:\n- Datum en tijd: 2025-12-26 00:54:20\n- UNIX-tijd: 1766706860 (dit is niet noodzakelijk voor het antwoord, tenzij de gebruiker specifiek naar vraagt)\n- Weeknummer: 52\n- Weekdag: Vrijdag\n\nIk kan deze informatie verwerken tot een vriendelijk en informatief antwoord. De gebruiker heeft alleen gevraagd om de tijd, maar ik kan ook de datum, weekdag en eventueel het weeknummer toevoegen voor extra context.\n\nHier is een mogelijke formulering:\n\"Het is nu 00:54:20 in Amsterdam. Vandaag is vrijdag, 26 december 2025, en het is week 52.\"\n\nMaar ik kan het ook iets korter houden, afhankelijk van wat de gebruiker precies wil. Aangezien de vraag \"Kan je mij de tijd vertellen?\" is, is een korte en duidelijke antwoord probably het beste.\n\nLaten we gaan voor:\n\"Het is nu 00:54:20 in Amsterdam.\"\n\nMaar om het wat rijker te maken, kan ik toevoegen:\n\"Het is nu 00:54:20 in Amsterdam. Vandaag is het vrijdag, 26 december 2025.\"\n\nOf nog korter:\n\"De huidige tijd in Amsterdam is 00:54:20.\"\n\nIk denk dat de laatste optie het beste balanced is tussen informatief en concies.\n\nLaten we dat als antwoord gebruiken."
}
]
},
{
"id": "msg_8zsip08eyylysg1oagti1m",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "De huidige tijd in Amsterdam is 00:54:20."
}
]
}
],
"usage": {
"input_tokens": 569,
"output_tokens": 391,
"total_tokens": 960,
"output_tokens_details": {
"reasoning_tokens": 372
}
},
"previous_response_id": null

