mlops••4 min read

Exposing LM Studio as an OpenAI-Compatible Endpoint for Local Scripts

How to run local models inside LM Studio and consume them via standard OpenAI SDKs or curl commands without cloud dependencies or paid API keys.

When building prototypes for RAG pipelines, autonomous agents, or document parsers, relying on paid cloud APIs can quickly add friction—both in cost and in sending sensitive data over the wire.

LM Studio is known primarily as a desktop GUI for downloading and testing GGUF quantized models. However, its built-in local server is one of its most practical features: it exposes an OpenAI-compatible HTTP REST endpoint right on your local machine.

Here is a quick setup guide on how to configure it, test it, and pipe it directly into standard Python code using the official openai client.


1. Starting the Local Server in LM Studio

  1. Download your preferred model (e.g., Qwen2.5-Coder-7B-Instruct-GGUF or Qwen2.5-3.5B-Instruct-GGUF).
  2. Head over to the Local Server tab on the left navigation bar (the <-> icon).
  3. Select the model from the dropdown at the top.
  4. In the server configuration panel:
    • Port: Set your desired port (e.g., 1235 or 1234).
    • CORS: Enable CORS if you plan to connect from local browser frontends or web UI tools.
    • GPU Offload: Set GPU offload to max out layers that fit in your VRAM (e.g., for an 8 GB RTX 4060, a 4-bit quantized 7B model can typically be 100% offloaded to GPU).
    • Context Length: Adjust the context limit based on your memory (4096 or 8192 tokens are safe starting points).
  5. Click Start Server.

2. Verifying the Endpoint via cURL

Once the server status indicator turns green, test the connection directly from your terminal or WSL:

bash
curl http://localhost:1235/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "system", "content": "You are a concise technical assistant."},
      {"role": "user", "content": "What is the difference between TCP and UDP in one sentence?"}
    ],
    "temperature": 0.2,
    "max_tokens": 100
  }'

You should receive a standard JSON response identical to OpenAI's schema:

json
{
  "id": "chatcmpl-local-12345",
  "object": "chat.completion",
  "created": 1700000000,
  "model": "qwen2.5-coder-7b-instruct",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "TCP is a connection-oriented protocol that guarantees ordered and reliable data delivery, whereas UDP is connectionless and prioritizes low-latency transmission without delivery guarantees."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 32,
    "completion_tokens": 35,
    "total_tokens": 67
  }
}

3. Integrating with Python's Official OpenAI SDK

Because the server complies with the OpenAI API specification, you do not need special local libraries or proprietary wrappers. You can use the standard openai Python package.

Installation

Using uv:

bash
uv add openai

Script Example (test_local_llm.py)

python
from openai import OpenAI

# Initialize client pointing to local LM Studio endpoint
client = OpenAI(
    base_url="http://localhost:1235/v1",
    api_key="lm-studio"  # LM Studio does not enforce auth; pass any dummy string
)

response = client.chat.completions.create(
    model="local-model",  # LM Studio serves whichever model is loaded in GUI
    messages=[
        {"role": "system", "content": "You are an assistant for code reviews."},
        {"role": "user", "content": "Write a Python function to check if a string is a palindrome."}
    ],
    temperature=0.1,
    max_tokens=256
)

print(response.choices[0].message.content)

Run it via uv:

bash
uv run test_local_llm.py

Practical Constraints to Keep in Mind

  1. Model Switching Overhead: LM Studio serves whatever model is currently loaded in memory. If you send a request with a different model identifier string in the API body, LM Studio will simply direct the prompt to whichever model is actively loaded, unless multi-model loading is configured.
  2. Context Window vs. VRAM: Increasing context length (e.g., beyond 8k tokens) allocates substantial memory for the KV cache. If you hit out-of-memory errors or generation slows down drastically, reduce the context window or reduce GPU offload layers to spill excess layers into system RAM.
  3. WSL to Windows Host Networking: If you are running your Python code inside WSL2 while LM Studio is running on Windows host, localhost:1235 might require using your Windows host IP or using WSL's host.docker.internal / mirrored networking depending on your WSL configuration. Binding LM Studio to 0.0.0.0 or using localhost forwarding in .wslconfig resolves cross-environment calls cleanly.

Conclusion

Using LM Studio as an OpenAI-compatible backend is an easy way to decouple your application architecture from specific providers. Your agent, FastAPI backend, or evaluation script can be written against standard interfaces, allowing you to develop and debug completely offline for free before swapping base_url to production endpoints.

Technical Discussion (0)

Ask a question or reply to a thread below. Your email is never displayed publicly.

No comments yet. Start the technical discussion above.