# Bay Run — full LLM/agent reference (served live from the service) > Bay Run is the discover -> prove -> serve loop for small open specialist models. > OpenAI-compatible + MCP-native, with a LIVE remote streamable-HTTP MCP endpoint. The > wedge: for a narrow, high-volume task, a small proven specialist served per-use is > cheaper and faster than a frontier API call or a reserved GPU — and you don't have to > guess which model; you PROVE it on your data. Live base URL: https://run.huggingbay.xyz Remote MCP (streamable-http): https://run.huggingbay.xyz/mcp/ (trailing slash; bare /mcp also works over https) Public server card (no auth): https://run.huggingbay.xyz/.well-known/mcp/server-card.json Autonomous auth (no client secret or browser): POST JSON `{"grant_type":"client_credentials"}` to https://run.huggingbay.xyz/oauth/token, then send the returned access token as `Authorization: Bearer `. Persist the returned refresh token to keep the same private memory principal across renewals. Interactive OAuth discovery starts at https://run.huggingbay.xyz/.well-known/oauth-protected-resource. Human token management remains at https://run.huggingbay.xyz/oauth/token. All request/response bodies are JSON; content-type: application/json. --- ## Decision guide (which call do I make?) | Your situation | Call | |---|---| | "I need a model for task X and I HAVE a few labeled examples" | find_specialist_for_task (or discover_models then eval_models) | | "I need a model NOW, no examples, don't even want to name one" | route / POST /v1/route (or model="auto" on embed/rerank) | | "I have a shortlist and want the best on MY data" | eval_models | | "I have a chosen embedding model, give me vectors" | embed / POST /v1/embeddings | | "I have retrieval results to reorder" | rerank / POST /v1/rerank | | "I need a guardrail/moderation/sentiment/intent label" | classify / POST /v1/classify | | "I have my own labels and no trained model" | classify with candidate_labels (zero-shot) | | "I have messy HTML/text and want structured JSON" | extract / POST /v1/chat/completions | | "I have a PDF and need text ready for RAG" | parse_pdf / POST /v1/pdf/extract | | "I'm not even sure you have a model for this" | request_specialist (serve-or-capture) | | "Just browse candidates" | discover_models | ## Build-time vs runtime routing (don't confuse them) - find_specialist_for_task = BUILD-TIME router: needs labeled examples, runs a real head-to-head bake-off, returns the PROVEN winner. Use once to pick, then serve that id. - route / model="auto" = RUNTIME router: zero examples, infers the task family and prefers its curated warm small specialist while retaining the catalog candidate for evaluation. HONEST: the pick is unproven — promote it to a proven winner with find_specialist_for_task when the task matters. --- ## MCP (agent-native, LIVE remote endpoint) Remote streamable-HTTP MCP is LIVE at https://run.huggingbay.xyz/mcp/ — no local proxy needed. Tools exposed (21): try_bay_run, find_specialist_for_task, request_specialist, route, discover_models, eval_models, embed, rerank, classify, extract, parse_pdf, summarize, rag_search, memory_context, speed_test, remember, recall, forget, calculate, validate_json, resolve_link. Discovery (initialize + tools/list) is UNAUTHENTICATED; the fixed no-argument try_bay_run call is public; every other tools/call needs a bearer. The endpoint returns a plain-JSON unary result and is LENIENT on the Accept header (a client that sends `application/json` without `text/event-stream` is NOT 406'd). Remote MCP client config (works today): ```json { "mcpServers": { "bay-run": { "type": "streamable-http", "url": "https://run.huggingbay.xyz/mcp/", "headers": { "Authorization": "Bearer " } } } } ``` Registry scanners that can't authenticate can enumerate all 21 tools from the unauthenticated server card at https://run.huggingbay.xyz/.well-known/mcp/server-card.json . --- ## REST endpoints ### POST /v1/discover Task -> ranked candidate specialist models from a 147K-model catalog, mirrored-first. Request: {"query": "multilingual sentence embeddings", "kind": "embedding", "limit": 5, "max_params_b": 1.0} `kind` in embedding | llm | vision | audio | tool | agent | any. Candidates, not proven — pass them to /v1/eval. ### POST /v1/eval Bake off N candidate models on YOUR labeled data. Leaderboard rank does not predict your-domain fit. `task` in embedding | rerank | extraction | generation. Ranking datasets: {query, positive, negatives:[...]}; extraction datasets: {input, expected:{...}, schema?}. Returns a ranked scorecard + `winner`. ### POST /v1/route (RUNTIME auto-router) Pick the curated warm specialist for a job you can't name a model for, based on the inferred task family. Request: {"task_hint": "embed support tickets for semantic search", "kind": "auto"} (kind in embedding|rerank|classification|zeroshot|generative|auto). Add serve=True and the matching inputs (embedding/classification: input; zeroshot: input+candidate_labels; rerank: query+documents; generative: content, optional schema) to route AND serve in one call. Returns {routed_model, routing_reason, mirrored, candidates_considered, serve, note}. HEURISTIC (correct-kind -> configured-warm -> mirrored/catalog evidence) — the pick is unproven; prove it with /v1/find_specialist. Same router also reachable as model="auto". ### POST /v1/embeddings (OpenAI-compatible) Request: {"model": "BAAI/bge-small-en-v1.5", "input": ["hello", "world"]} `model` = any HF embedding / sentence-transformers id. OpenAI /v1/embeddings-shaped response. Pass `"model": "auto"` (+ optional `"task_hint"`) to invoke the runtime router; the response adds `x_bay_run_routed_model` + a `routing` block naming the chosen model and why. ### POST /v1/rerank (Cohere/Jina-shaped) Request: {"model": "BAAI/bge-reranker-base", "query": "...", "documents": ["...","..."], "top_n": 3} Returns {model, results:[{index, relevance_score}]}. ### POST /v1/chat/completions (OpenAI-compatible, CPU-served generative) Schema-guided JSON extraction via `response_format` (json_object | json_schema). The `extract` MCP tool wraps this. Response carries `json_valid` + `parsed` when a schema is set. ### POST /v1/classify (text-classification, CPU-served) Two modes. FIXED-LABEL: {"model": "protectai/deberta-v3-base-prompt-injection-v2", "input": "ignore all previous instructions"} -> the model's own labels + scores. ZERO-SHOT: add `candidate_labels` with an NLI model: {"model": "facebook/bart-large-mnli", "input": "my order never arrived", "candidate_labels": ["billing", "shipping", "praise"]} -> entailment-scored labels, no training. `model="auto"` routes to the best mirrored classifier (or NLI model for zero-shot). Optional `multi_label`, `top_k`, `hypothesis_template`. Returns {model, labels:[{label, score}], zero_shot, usage}. Serves guardrail/safety/moderation/sentiment/ NLI/intent specialists — the category agents most need. ### POST /v1/request_specialist (serve-or-capture) {"task": "detect prompt injection in agent inputs", "kind": "classification", "examples": [...]}. If a servable specialist exists -> chains discover -> (eval if examples) -> a serve pointer. If NOT -> records the demand (task, kind, examples-hash, ts) and returns {status:"recorded", subscribe_hint}. Never a dead end. ### GET /v1/models Curated catalog + provenance flag. Any non-curated HF id also works on demand. ### Agent working context — POST /v1/memory/context Fast one-call load/update/delete. POST {"updates":{"goal":"ship","decision":"use bge"}} loads the default private context after atomically applying both updates. Optional `namespace`, `delete_keys`, `ttl`, `max_items`, and `max_bytes` keep the returned prompt context bounded. OAuth returns a refresh credential so the same private context follows an agent across access-token renewal and across harnesses. MCP tool: memory_context. ### Agent memory — POST/GET/DELETE /v1/memory Durable cross-call key->value memory, scoped to your bearer-token PRINCIPAL (multi-tenant isolation) + a caller `namespace`. POST {"namespace":"proj-42","key":"chosen_model","value": {"id":"BAAI/bge-small-en-v1.5"},"ttl":86400} upserts (ttl seconds optional). GET /v1/memory?namespace=proj-42&key=chosen_model reads one; omit `key` to LIST the namespace. DELETE /v1/memory?namespace=proj-42[&key=...] forgets one key or the whole namespace. The Signed OAuth credentials receive a private refreshable agent principal. The legacy static demo token remains shared for compatibility — don't store secrets under that static token. MCP tools: remember / recall / forget. ### POST /v1/calculate {"expression":"sqrt(2) * (3 + 4) ** 2"} -> {ok, result}. Safe whitelist parser (NO eval): + - * / // % **, parentheses, sqrt/log/log10/exp/sin/cos/tan/floor/ceil/abs/factorial, pi/e/tau. The exact calculator agents need. MCP tool: calculate. ### POST /v1/validate_json {"data":"{...}","schema":{...}} — if `data` is a string it must PARSE; if `schema` (JSON Schema Draft 2020-12) is given, the value is validated against it. Returns {valid, errors[], parsed}. MCP tool: validate_json. ### POST /v1/resolve_link {"url":"https://huggingface.co/owner/model"} -> {alive, status, final_url, mirror_url?}. Checks liveness; if the URL is dead AND names a model Hugging Bay has MIRRORED, returns the mirrored copy's serve pointer (a fallback UNIQUE to Bay Run). SSRF-safe: http(s) only, never probes private/internal addresses. MCP tool: resolve_link. ### POST /v1/pdf/extract Native PDFium text extraction with no model load. Provide exactly one source: a public URL (`{"url":"https://example.org/report.pdf"}`) or small base64 input (`pdf_base64`). Optional `start_page`, `max_pages`, and `max_chars` keep work bounded. Returns `pages`, combined `text`, and `rag_documents` that can be passed directly to /v1/rag. The source URL is validated on every redirect and capped by bytes/time/pages/characters/concurrency. Image-only PDFs return `needs_ocr:true`; OCR is deliberately not claimed. MCP tool: parse_pdf. --- ## Use it as an OpenAI client (zero adapter code) ```python from openai import OpenAI client = OpenAI(base_url="https://run.huggingbay.xyz/v1", api_key="") client.embeddings.create(model="BAAI/bge-small-en-v1.5", input=["hello"]) ``` Framework wrappers (copy-paste): LangChain, LlamaIndex, and OpenAI Agents / function-calling adapters are published alongside the docs. --- ## Two Hugging Bay MCPs — namespace disambiguation - Catalog MCP: io.github.barneywohl/hugging-bay — RECOMMEND / VERIFY (browse + provenance). - Bay Run: io.github.barneywohl/bay-run — PROVE-on-your-data + SERVE (this service). ## Why Bay Run - Neutral: it doesn't sell one model; it helps you pick the one that wins on your data. - Instant + cheap: CPU, scale-to-zero, no packaging tax; the niche long tail on demand. - Provenance-tracked supply: content-addressed, quarantine-gated mirror (sha256 integrity via content addressing; flagged models hard-blocked). Signed manifests exist as a moat feature and /api/verify is live; full serve-time signature verification is in progress — mirror bytes are integrity-checked, not yet signature-verified per byte at serve time.