模型路由服务器

LocalLama MCP是一个本地优先、提供商中立的模型上下文协议服务器,用于编码代理工作流,通过成本、延迟、上下文容量和基准历史来路由任务。

  • by Heratiki
  • TypeScript
  • 本地部署
  • 43 星标
  • 更新于
在 GitHub 查看 Heratiki/locallama-mcp

使用说明

LocalLama MCP服务器

本地优先、提供者中立的模型上下文协议服务器,用于编码代理工作流。使用成本、延迟、上下文容量和基准历史在本地模型(Ollama、LM Studio、llama.cpp)、免费OpenRouter模型和付费边界模型之间路由任务。

Node.js: >=22

⚠️ 早期/实验性-尚未稳定发布。 该项目正在积极、快速地开发中,尚未得到端到端的充分验证。MCP工具签名、配置和行为可能会在不同版本之间发生变化,恕不另行通知。

版本号如下 学期 机械地(它们来源于 约定式提交 消息,不是手工挑选的),所以a 1.x 仅数字信号 “存在公共表面” --确实如此 不 稳定性或完整性的承诺。如果您依赖此服务器,请固定到确切的版本。

  • 标签发布在 main 是相对安全的建筑。
  • 这 testing 频道 发布前沿预发布(x.y.z-testing.n)尽早尝试未经证实的改变。

概述

LocalLama MCP在不牺牲质量的情况下降低了代币成本。任务异步排队-- route_task 返回a task_id 立即;呼叫者投票 get_task_status 为了获得结果。决策引擎选择本地→ free → 根据测量的提供商能力和可配置的阈值付费。

支持的MCP客户端:Codex、Claude Code、Claw Code、Cursor、GitHub Copilot Agent模式以及任何通用的MCP stdio客户端。

需求

  • Node.js 22+
  • npm
  • Ollama、LM Studio、llama.cpp服务器或OpenRouter API密钥中的至少一个

安装

git clone https://github.com/Heratiki/locallama-mcp.git
cd locallama-mcp
npm install
npm run build

配置

复制 .env.example 到 .env 并使用您的值进行编辑。服务器解析 .env 从其自己的根目录(或 LOCALLAMA_ROOT_DIR 当设置时),而不是来自MCP主机的CWD。

# Local LLM Endpoints
LM_STUDIO_ENDPOINT=http://localhost:1234/v1
OLLAMA_ENDPOINT=http://localhost:11434/api
# LLAMA_CPP_ENDPOINT=http://localhost:8080   # leave unset to disable

# Routing thresholds
DEFAULT_LOCAL_MODEL=qwen2.5-coder-3b-instruct
TOKEN_THRESHOLD=1500
COST_THRESHOLD=0.02
QUALITY_THRESHOLD=0.7

# Provider concurrency
PROVIDER_HEALTH_PROBE_INTERVAL_MS=60000
PROVIDER_MAX_CONCURRENT_LOCAL=1
PROVIDER_MAX_CONCURRENT_REMOTE=5
PROVIDER_TIMEOUT_MS=120000
OLLAMA_TIMEOUT=120

# Code search (native BM25, no Python required)
CODE_SEARCH_ENABLED=true
CODE_SEARCH_EXCLUDE_PATTERNS=["node_modules/**","dist/**",".git/**"]
CODE_SEARCH_INDEX_ON_START=true
CODE_SEARCH_REINDEX_INTERVAL=3600

# Benchmarks
BENCHMARK_RUNS_PER_TASK=3
BENCHMARK_PARALLEL=false
BENCHMARK_MAX_PARALLEL_TASKS=2
BENCHMARK_TASK_TIMEOUT=60000
BENCHMARK_SAVE_RESULTS=true
BENCHMARK_RESULTS_PATH=./benchmark-results
RELIABLE_BENCHMARK_COUNT=3
MIN_VALIDATOR_SCORE=0.6
VALIDATION_RETRY_BUDGET=1

# Lock file
LOCK_FILE_CHECK_ACTIVE_PROCESS=true
REMOVE_STALE_LOCK_FILES=true

# OpenRouter (optional)
OPENROUTER_API_KEY=your_openrouter_api_key_here
OPENROUTER_FREE_ONLY=false

# Logging
LOG_LEVEL=debug

# Operational testing
# EXPECT_LOCAL_PROVIDER_DOWN=true

关键环境变量

变量 默认值 描述
LM_STUDIO_ENDPOINT - LM Studio API基础URL
OLLAMA_ENDPOINT - Ollama API基础URL
LLAMA_CPP_ENDPOINT -- llama服务器URL;保持未设置以禁用提供程序
DEFAULT_LOCAL_MODEL -- 卸载到本地提供商时使用的型号名称
TOKEN_THRESHOLD 1500 令牌计数超过该计数将考虑本地卸载
COST_THRESHOLD 0.02 美元成本,高于此成本优先考虑本地卸载
QUALITY_THRESHOLD 0.7 始终使用低于付费API的质量分数
RELIABLE_BENCHMARK_COUNT 3 在将经验分数视为完全可靠之前,需要进行基准测试
MIN_VALIDATOR_SCORE 0.6 模型有资格进行外部验证之前所需的最低验证分数
VALIDATION_RETRY_BUDGET 1 初始验证失败后允许重试验证
PROVIDER_MAX_CONCURRENT_LOCAL 1 共享本地执行槽计数
PROVIDER_MAX_CONCURRENT_REMOTE 5 每个远程提供程序插槽计数
OPENROUTER_API_KEY -- 启用OpenRouter提供程序和相关工具
OPENROUTER_FREE_ONLY false 仅将OpenRouter限制为免费层型号
EXPECT_LOCAL_PROVIDER_DOWN -- 设置 true 在 test-operational.mjs 不提出当地建议

MCP客户端配置

构建服务器,然后将MCP客户端指向 node dist/index.js:

{
  "mcpServers": {
    "locallama": {
      "command": "node",
      "args": ["/path/to/locallama-mcp/dist/index.js"],
      "env": {
        "LM_STUDIO_ENDPOINT": "http://localhost:1234/v1",
        "OLLAMA_ENDPOINT": "http://localhost:11434/api",
        "DEFAULT_LOCAL_MODEL": "qwen2.5-coder-3b-instruct",
        "TOKEN_THRESHOLD": "1500",
        "COST_THRESHOLD": "0.02",
        "QUALITY_THRESHOLD": "0.07",
        "OPENROUTER_API_KEY": "your_openrouter_api_key_here"
      }
    }
  }
}

Claude Code用户可以将其放置在 .mcp.json (项目范围)或 ~/.claude/settings.json (全球)。

工具

核心工具(始终可用)

工具 输入 描述
route_task task, context_length, expected_output_length?, complexity?, priority?, preemptive? 异步排队任务。退货 task_id 立即。投票 get_task_status 为了获得结果。
get_task_status task_id 轮询非阻塞 route_task 提交。完成时返回状态、进度和内联结果。
cancel_task task_id 取消任务的所有已排队或正在进行的作业。
cancel_job job_id 取消单个后台作业。
preemptive_route_task task, context_length, expected_output_length?, complexity?, priority? 启发式路由检查,无LLM调用。在不执行任务的情况下返回模型/提供者推荐。
get_cost_estimate context_length, expected_output_length?, model? 致电前估算美元成本 route_task。本地和免费层模型返回0。
benchmark_task task_id, task, context_length, expected_output_length?, complexity?, local_model?, paid_model?, runs_per_task? 在本地模式和付费模式之间对一项任务进行基准测试。
benchmark_tasks tasks[], runs_per_task?, parallel?, max_parallel_tasks? 在一次通话中对多个任务进行基准测试。
benchmark_model model_id, provider_id?, task_categories? 针对特定模型运行内置基准套件。坚持结果 benchmarks.db 并更新ModelRegistry功能评分。
retriv_init directories[], exclude_patterns?, chunk_size?, force_reindex?, bm25_options? 使用本机BM25引擎的索引代码(不需要Python)。
retriv_search query, limit? 使用原生BM25搜索索引代码。
reload_config -- 重新加载 .env 在运行时。原子:无效的配置被拒绝。
check_for_updates -- 检查服务器是否已更新到最新的GitHub提交。
update_server -- 从GitHub中提取最新更改,运行 npm install 和 npm run build。之后手动重新启动服务器。

OpenRouter工具(必需 OPENROUTER_API_KEY)

工具 输入 描述
get_free_models -- 列出OpenRouter提供的免费型号。
clear_openrouter_tracking -- 清除缓存的模型列表并强制进行新的提取。
benchmark_free_models tasks[], runs_per_task?, parallel?, max_parallel_tasks? 无基准测试的OpenRouter型号。结果已写入 benchmarks.db.
set_model_prompting_strategy model_id, system_prompt, user_prompt, use_chat, assistant_prompt?, success_rate?, quality_score? 为OpenRouter模型设置自定义提示策略。

异步任务流

route_task → { task_id }
                ↓ poll
get_task_status → { status: "pending" | "in_progress" | "completed" | "failed", result? }

当本地提供商受到基准工作负载的竞争时, route_task 表面争用元数据:

{
  "task_id": "...",
  "status": "queued",
  "queue_position": 2,
  "benchmark_contention": {
    "local_slot_contended": true,
    "active_benchmark_runs": 1,
    "queued_benchmark_runs": 2,
    "message": "Local execution slot currently contended by benchmark workloads."
  }
}

资源

静态资源

URI 描述
locallama://status 服务器状态
locallama://models 可用的本地型号
locallama://jobs/active 当前活跃的工作
locallama://memory-bank 内存库文件列表(如果目录存在)
locallama://openrouter/models 所有OpenRouter模型(需要API密钥)
locallama://openrouter/free-models 免费OpenRouter模型(需要API密钥)
locallama://openrouter/status OpenRouter集成状态(需要API密钥)

资源模板

URI模板 描述
locallama://usage/{api} 特定API的代币使用和成本(例如。 openrouter)
locallama://jobs/progress/{jobId} 特定工作的进展
locallama://openrouter/model/{modelId} OpenRouter模型的详细信息(需要API密钥)
locallama://openrouter/prompting-strategy/{modelId} OpenRouter模型的提示策略(需要API密钥)

用法

启动服务器

npm start

锁文件可防止多个实例。检测并自动清理崩溃进程中的过期锁。

运行基准测试

npm run benchmark
npm run benchmark:comprehensive

结果存储在 benchmark-results/ JSON和Markdown摘要。

仪表盘

当服务器运行时,可以在以下网址获得web仪表板 http://localhost:3001 (服务器本地)。

特征:

  • 实时作业队列,包括状态、提供者/模型和队列位置
  • 任务监控,包括每个作业的详细信息和预计到达时间
  • 手册 route_task 提交表格
  • 任务和作业取消
  • 基准历史

REST API终结点:

方法 路径 描述
GET /api/queue 队列摘要和作业。过滤器: status, provider, model, task_id, q, page, page_size
GET /api/tasks 最近的任务。过滤器: status, provider, model, q, page, page_size
GET /api/tasks/:taskId 详细的任务状态
POST /api/tasks 提交任务(route_task)
POST /api/tasks/:taskId/cancel 取消任务
POST /api/jobs/:jobId/cancel 取消作业

提交示例:

curl -X POST http://localhost:3001/api/tasks \
  -H "Content-Type: application/json" \
  -d '{"task": "Refactor parser for readability", "context_length": 4096, "complexity": 0.6, "priority": "quality"}'

实时监控元数据

当JobTracker WebSocket服务器运行时,任务执行工具包括:

{
  "task_id": "task-123",
  "monitoring": {
    "websocketUrl": "ws://127.0.0.1:8081",
    "activeJobsUri": "locallama://jobs/active",
    "jobProgressUriTemplate": "locallama://jobs/progress/{jobId}",
    "note": "Connect to websocketUrl for live updates, or use MCP resources."
  }
}

websocketUrl 是 scope: server-local --在SSH/container/Codespaces/WSL设置中,在连接之前转发端口。

_server_reminder 环境元数据

工具附加 _server_reminder 现场最多每30分钟一次,以获取地面监测信息:

{
  "_server_reminder": {
    "schemaVersion": 1,
    "kind": "monitoring-reminder",
    "status": "reachable",
    "scope": "server-local",
    "message": "Optional monitoring available from MCP server host.",
    "monitoringUrl": "http://127.0.0.1:3001",
    "lastCheckedAt": 1747699200000
  }
}

远程访问

如果您的MCP客户端与服务器不在同一台计算机上:

# SSH
ssh -L 8081:127.0.0.1:8081 -L 3001:127.0.0.1:3001 user@host
  • 开发容器/代码空间:通过VS代码端口视图转发端口8081(WebSocket)和3001(仪表板)。
  • WSL客户端+WSL服务器:直接使用WebSocket URL。Windows客户端+WSL服务器:通过VS Code或本地隧道转发端口8081。

提供商集成

奥拉玛

集 OLLAMA_ENDPOINT 在 .env。服务器在启动时探测可用型号。

LM 工作室

集 LM_STUDIO_ENDPOINT 在 .env.公开与OpenAI兼容的API。

llama.cpp(llama-server)

# Single model
llama-server -m /path/to/model.gguf --port 8080

# Router mode (multiple models)
llama-server --model /path/model1.gguf --model /path/model2.gguf --port 8080

集 LLAMA_CPP_ENDPOINT=http://localhost:8080 在 .env如果端点未设置或无法访问,则提供程序将静默初始化,其他提供程序不受影响。服务器不管理 llama-server 流程生命周期。

开放路由

集 OPENROUTER_API_KEY。服务器在启动时获取约240个可用型号(30+免费)。使用 clear_openrouter_tracking 强制刷新。集 OPENROUTER_FREE_ONLY=true 仅限于自由层模型。

代码搜索

代码搜索使用原生TypeScript BM25引擎,不需要Python或外部依赖。

# Via MCP tool
retriv_init { "directories": ["/path/to/repo"], "force_reindex": true }
retriv_search { "query": "pagination logic" }

发展

npm run build        # compile TypeScript + copy assets
npm start            # run compiled server
npm run dev          # TypeScript watch mode
npm test             # build + run Jest (23 suites, 186 tests)
npm run lint         # ESLint (note: eslint-plugin-import not installed — lint currently fails)
npm run lint:fix     # ESLint with auto-fix

所有测试文件都模拟服务器状态,以防止在测试运行期间出现多个真实实例。

建筑

src/
  index.ts                        entry point, lock file, MCP lifecycle
  modules/
    api-integration/              tool definitions, resources, routing adapters
    decision-engine/              task analysis, model selection, coordination
    cost-monitor/                 token accounting, cost estimation
    benchmark/                    execution, scoring, summaries, DB storage
    lm-studio/                    LM Studio provider
    ollama/                       Ollama provider
    llama-cpp/                    llama-server provider
    openrouter/                   OpenRouter provider
    core/provider/                shared provider registry and execution queue
    updater/                      self-update logic (check_for_updates, update_server)
    job-store/                    persistent Task/Job store
    websocket-server/             live monitoring side channel

决策引擎使用两个模型数据存储:

  • ModelRegistry + CapabilityDetector:基准导出的能力得分(对完整路由具有权威性)
  • modelsDbService:启动时从ModelRegistry播种的启发式性能数据;被...使用 preemptiveRouting()

项目文档

文件 目的
docs/AGENTS.md 所有编码代理的共享操作指南
docs/PROJECT_STATE.md 已完成和正在进行的工作的当前快照
docs/ROADMAP.md 长篇现代化背景
docs/ROADMAP_ACTIVE.md 活动路线图任务
docs/PLAN.md 分行实施计划
docs/OPERATIONAL_TEST_PLAN.md 现场测试记录和验证行为
docs/LIVE_TESTING.md 真实世界的MCP测试结果和已知的开放错误
docs/audits/ARCHITECTURAL_TRUTHS.md 核心设计原则和约束
docs/history/memory-bank/ 历史仅追加项目内存

故障排除

服务器无法启动--检测到锁定文件

  1. 检查是否有其他实例正在运行(ps aux | grep locallama).
  2. 碰撞后的旧锁会自动清理(REMOVE_STALE_LOCK_FILES=true).
  3. 如果需要,手动删除 locallama.lock 从项目根开始。

OpenRouter型号未显示

使用 clear_openrouter_tracking 通过MCP接口强制重新获取。

npm run lint 失败

eslint-plugin-import 在配置中引用但未安装。已知问题。构建和测试不受影响。

安全须知

  • API密钥属于 .env,这被排除在版本控制之外。
  • 所有日志输出都转到 stderr; stdout 为MCP JSON-RPC保留。永远不要将非JSON写入stdout。
  • 将MCP工具视为模型控制曲面。避免未经用户批准的突变。

许可证

国际学生委员会