RanchHand
RanchHand is an OpenAI-compatible MCP server that acts as a proxy to AI backends like Ollama, providing standardized API access through multiple tools:
Core Capabilities:
List Available Models: Query all models from the backend using
openai_models_listviaGET /v1/modelsChat Completions: Generate conversational responses with
openai_chat_completionsviaPOST /v1/chat/completions, supporting parameters like temperature, top_p, and max_tokens (streaming not yet implemented)Create Embeddings: Generate vector embeddings from text using
openai_embeddings_createviaPOST /v1/embeddingsHTTP Ingest Service: Optional service on localhost:41414 for ingesting data like Slack messages via
POST /ingest/slackwith authentication (currently a stub)
Configuration & Integration:
Backend Flexibility: Works with any OpenAI-compatible backend (defaults to Ollama at localhost:11434/v1)
Environment Variables: Configurable via
OAI_BASE,OAI_API_KEY,OAI_DEFAULT_MODEL, andOAI_TIMEOUT_MSMCP Integration: Can run standalone or integrate into MCP configurations for Claude/Codex integration
Provides access to locally hosted AI models through Ollama's OpenAI-compatible endpoints, enabling chat completions, embeddings generation, and model listing capabilities
Offers integration with OpenAI-compatible APIs for chat completions, embeddings creation, and model management through standardized OpenAI endpoints
Click on "Deploy 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., "@RanchHand summarize this article about climate change"
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.
RanchHand — OpenAI-compatible MCP Server (Architecture)
RanchHand is a minimal MCP server that fronts an OpenAI-style API. It works great with Ollama's OpenAI-compatible endpoints (http://localhost:11434/v1) and should work with other OpenAI-compatible backends.
Features
Tools:
openai_models_list→ GET/v1/modelsopenai_chat_completions→ POST/v1/chat/completionsopenai_embeddings_create→ POST/v1/embeddingsOptional HTTP ingest on localhost:41414 (bind 127.0.0.1):
POST /ingest/slack(index: chunk + embed + upsert in in-memory store)POST /query(kNN query with embeddings)GET /profiles|POST /profiles(role defaults: embed, summarizers, reranker, chunking)POST /answer(retrieve + generate answer with bracketed citations)
Config via env:
OAI_BASE(defaulthttp://localhost:11434/v1)OAI_API_KEY(optional; some backends ignore it, Ollama allows any value)OAI_DEFAULT_MODEL(fallback model name, e.g.llama3:latest)OAI_TIMEOUT_MS(optional request timeout)
Development
Linting
This project uses ESLint to maintain code quality and consistency.
# Run the linter to check for issues
npm run lint
# Automatically fix linting issues where possible
npm run lint:fixThe linting rules enforce:
Consistent code style (single quotes, semicolons, 2-space indentation)
Error prevention (no unused variables, no undefined variables)
Modern JavaScript practices (const/let instead of var, arrow functions)
CI will automatically run linting checks on all pull requests.
Testing
This repo uses Vitest for unit tests. External network calls are mocked, so tests run deterministically without Ollama or internet access.
Commands:
# Run tests once
npm test
# TDD: watch mode
npm run test:watch
# With coverage report
npm run test:coverageCoverage thresholds are configured in vitest.config.mjs (initial targets):
Lines/Statements ≥ 60%
Functions ≥ 55%
Branches ≥ 50%
These thresholds indicate the minimum proportion of code exercised by tests. They are a guardrail, not a guarantee of correctness. We can raise them as the test suite grows.
Notes:
Tests live in tests/**/*.test.js
Use vi.spyOn/vi.mock to stub fetch and other external calls
For CI stability, avoid real network calls in tests
Run (standalone)
# Example with Ollama running locally
export OAI_BASE=http://localhost:11434/v1
export OAI_DEFAULT_MODEL=llama3:latest
node server.mjsHTTP Ingest Service
node http.mjs
# Binds to 127.0.0.1:41414
# Shared secret is created at ~/.threadweaverinc/auth/shared_secret.txt on first runExample request:
SECRET=$(cat ~/.threadweaverinc/auth/shared_secret.txt)
curl -s -X POST http://127.0.0.1:41414/ingest/slack \
-H "Content-Type: application/json" \
-H "X-Ranchhand-Token: $SECRET" \
-d '{
"namespace":"slack:T123:C456",
"channel":{"teamId":"T123","channelId":"C456"},
"items":[{"ts":"1234.5678","text":"Hello world","userName":"Dan"}]
}'Query:
SECRET=$(cat ~/.threadweaverinc/auth/shared_secret.txt)
curl -s -X POST http://127.0.0.1:41414/query \
-H "Content-Type: application/json" \
-H "X-Ranchhand-Token: $SECRET" \
-d '{
"namespace":"slack:T123:C456",
"query":"hello",
"topK": 5,
"withText": true
}'Answer with citations:
SECRET=$(cat ~/.threadweaverinc/auth/shared_secret.txt)
curl -s -X POST http://127.0.0.1:41414/answer \
-H "Content-Type: application/json" \
-H "X-Ranchhand-Token: $SECRET" \
-d '{
"namespace":"slack:T123:C456",
"query":"What did Dan say about hello?",
"topK": 3
}'Profiles:
curl -s http://127.0.0.1:41414/profiles
curl -s -X POST http://127.0.0.1:41414/profiles \
-H "Content-Type: application/json" \
-d '{ "embed": { "model": "nomic-embed-text:latest" }, "chunking": { "chunk_tokens": 512 } }'MCP Tools
openai_models_listInput:
{}Output: OpenAI-shaped
{ data: [{ id, object, ... }] }
openai_chat_completionsInput:
{ model?: string, messages: [{ role: 'user'|'system'|'assistant', content: string }], temperature?, top_p?, max_tokens? }Output: OpenAI-shaped chat completion response (single-shot; streaming TBD)
openai_embeddings_createInput:
{ model?: string, input: string | string[] }Output: OpenAI-shaped embeddings response
Claude/Codex (MCP)
Point your MCP config to:
{
"mcpServers": {
"ranchhand": {
"command": "node",
"args": ["/absolute/path/to/server.mjs"],
"env": { "OAI_BASE": "http://localhost:11434/v1", "OAI_DEFAULT_MODEL": "llama3:latest" }
}
}
}Notes
Streaming chat completions are not implemented yet (single response per call). If your backend requires streaming, we can add an incremental content pattern that MCP clients can consume.
RanchHand passes through OpenAI-style payloads and shapes outputs to be OpenAI-compatible, but exact metadata (usage, token counts) depends on the backend.
HTTP ingest is currently an acknowledgment stub (counts + sample). Chunking/embedding/upsert will be wired next; design is pluggable for local store or Qdrant.
Available Tools
3 toolsopenai_chat_completionsD
Create chat completion (POST /v1/chat/completions).
Inputs: messages (required), max_tokens, model, stream, +2 more.
openai_embeddings_createC
Create embeddings (POST /v1/embeddings).
Inputs: input (required), model.
openai_models_listB
List models from OpenAI-compatible backend (GET /v1/models).
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose targeting different OpenAI API endpoints: chat completions, embeddings creation, and model listing. There is no overlap or ambiguity between these functions.
The naming follows a consistent pattern with 'openai_' prefix and descriptive suffixes, though there's a minor deviation: 'openai_chat_completions' uses plural while 'openai_embeddings_create' uses singular verb form. Overall, the pattern is predictable and readable.
With only 3 tools, the set feels thin for a server named 'RanchHand' which suggests broader functionality. While these cover core OpenAI operations, the limited scope may not fully represent what the server name implies.
For an OpenAI-compatible backend, the tools cover chat, embeddings, and models, but there are notable gaps in other common operations like image generation, audio processing, file operations, or fine-tuning endpoints. The surface is functional but incomplete for comprehensive OpenAI API coverage.
Related MCP Connectors
MCP server for OpenAI API (chat completions, image generation, embeddings) via AceDataCloud
Use AI models for chat, image, and video generation from Claude Code and other MCP hosts.
Chat, image, video, and audio models from many vendors behind one remote MCP server and one key.
Connect MCP clients to 2,000+ AI models without managing provider API keys.