--- title: Your custom agent harness: point it at a cheaper endpoint in one line slug: custom-agent-harness-openai-compatible canonical_url: https://blog.juscode.co/custom-agent-harness-openai-compatible published_at: 2026-05-26T00:00:00+00:00 author: jusCode tags: custom-agent, openai-compatible, agent-harness, openclaw, nemoclaw, hermes-agents, byo-agent tldr: If your custom agent harness uses the OpenAI Python or Node SDK, change two values: base_url to https://api.juscode.co/v1 and api_key to a jcg_ token. No code changes beyond the client constructor. Tool-call shapes are normalized server-side. key_takeaways: - a custom harness works with any OpenAI-compatible endpoint via the OpenAI SDK base_url + api_key. - Set base_url to https://api.juscode.co/v1 and use a jcg_ token with model jusCode-auto. - If your harness speaks Chat Completions, it speaks jusCode with a two-value change. --- # Your custom agent harness: point it at a cheaper endpoint in one line Some teams build their own coding-agent harness instead of using Claude Code, OpenCode, or Cursor. The reasons vary: domain-specific tools, privacy, in-house benchmarks, or just a strong opinion about how an agent loop should work. Names you see in the wild: in-house "OpenClaw" / "nemoClaw" style projects, Hermes-based agent harnesses, custom CrewAI / LangGraph orchestrations, internal forks of Aider. All of them have the same property: **if the harness speaks OpenAI Chat Completions, it speaks jusCode**. This post is the universal setup, plus the three things to verify before you ship. ## The universal config 99% of custom agents use one of two HTTP client patterns. Here are both. ### Pattern 1: OpenAI Python SDK ```python from openai import OpenAI client = OpenAI( base_url="https://api.juscode.co/v1", api_key=os.environ["JUSCODE_API_KEY"], # jcg_… from /developer ) # Everything else stays the same. resp = client.chat.completions.create( model="jusCode-auto", # or any provider/model id you want pinned messages=conversation, tools=tool_schemas, stream=True, ) ``` ### Pattern 2: Raw fetch / requests ```python import requests, os resp = requests.post( "https://api.juscode.co/v1/chat/completions", headers={ "Authorization": f"Bearer {os.environ['JUSCODE_API_KEY']}", "Content-Type": "application/json", }, json={ "model": "jusCode-auto", "messages": conversation, "tools": tool_schemas, "stream": True, }, stream=True, ) ``` That's the whole integration. The hard part (model selection per call, upstream provider routing, failover) happens server-side. ## Mapping your existing config Most custom harnesses have a config block like: ```python LLM_PROVIDER = "anthropic" # or "openai", "together", etc. LLM_MODEL = "claude-sonnet-4-5" LLM_BASE_URL = "https://api.anthropic.com" LLM_API_KEY = "sk-ant-..." ``` To switch to jusCode, only three lines change: ```python LLM_PROVIDER = "openai" # we speak OpenAI shape regardless of underlying model LLM_MODEL = "jusCode-auto" # or pin a specific provider/model id LLM_BASE_URL = "https://api.juscode.co/v1" LLM_API_KEY = "jcg_..." ``` If your harness has hard-coded "anthropic" / "openai" / "together" branches in code, the simplest fix is to add a `"jusCode"` branch that uses the OpenAI client path. Or just use the OpenAI branch and point its base URL at us. ## What works for any custom harness | Feature | Status | |---|---| | `messages` shape (system/user/assistant/tool) | ✅ | | Streaming via SSE | ✅ | | Tool calls (OpenAI shape) | ✅ | | Tool calls (Anthropic shape) | ✅ we normalize | | `response_format: json_object` | ✅ | | Parallel tool calls | ✅ when the underlying model supports it | | Vision inputs (image_url) | ✅ auto-routes to a vision-capable model | | Logprobs | ⚠️ pass-through if upstream supports; ignored if not | | Fine-tunes | ❌ we don't host fine-tunes: use the provider directly for those | ## Three things to verify before shipping ### 1. Tool-call shape on YOUR specific model id If you pin a specific model (e.g. `nousresearch/hermes-4-405b` or `qwen/qwen3-coder-480b`), test that tool calls land in the shape your agent expects. We normalize but edge cases exist, so log one tool call end-to-end and inspect the JSON. ### 2. Cost per task on YOUR workload Don't trust the homepage promise. Run 10 real tasks through your harness, check the usage tab. If it's not 50%+ cheaper than your prior setup, something's miscoded (often: you're sending the same prompt twice because of a retry bug in your harness). ### 3. Failure mode when upstream stutters We retry transparently when an upstream model 502s or rate-limits. Test this: kill your network for 5 seconds mid-stream. Your agent should see a `502 UPSTREAM_ERROR` only if all our retries failed (rare). Otherwise the stream resumes from the same response with no duplicate text. ## Per-user accounting in a multi-user agent If your harness serves multiple users and you need per-user spend attribution: 1. Mint one `jcg_` key per user via `POST /v1/keys` (JWT-authed; humans sign in first). 2. Each user's calls go through their own key. 3. The usage dashboard breaks down spend per key. 4. Set per-user soft caps via `POST /v1/tenant/members/:id/cap` so a single user can't blow the team budget. For a single shared key (single tenant) we still attribute by `user_id` if your agent passes it in headers. See [API reference](/docs/api-reference/). ## A note on the names Got asked about specific custom harnesses recently: "OpenClaw", "nemoClaw", "Hermes agents". These aren't standardized products in the sense Cursor or Claude Code are. They're patterns or in-house projects. If you're building one of them or its equivalent, this guide covers you. If "OpenClaw" or "nemoClaw" is something more specific you want a tailored guide for, email hello@juscode.co with a link to your repo and we'll write one. ## Setup checklist 1. Sign up at [juscode.co/login](https://juscode.co/login). 2. Mint a `jcg_` key at [/developer](https://juscode.co/developer). 3. Set base URL + key in your harness config. 4. Run one task end-to-end. Verify response on the [Usage tab](https://juscode.co/developer). 5. Set per-user caps if multi-tenant. 6. Set rate limits in the [Tenant tab](https://juscode.co/developer) if you expect burst traffic. ## Related reading - [OpenAI-compatible drop-in (every popular harness, step by step)](/docs/openai-drop-in/) - [Hermes models for coding agents](/blog/hermes-models-and-coding-agents/) - [Inference endpoints for coding agents: what's different](/blog/inference-endpoint-coding-agents/) - [API reference](/docs/api-reference/) --- *Raw markdown: [/blog/custom-agent-harness-openai-compatible.md](/blog/custom-agent-harness-openai-compatible.md)* ## FAQ ### How do I point a custom harness at a cheaper endpoint? Use the OpenAI SDK base_url + api_key: base_url https://api.juscode.co/v1, a jcg_ token, and model jusCode-auto. Behavior is unchanged. ### Does a custom harness lose any features on a custom endpoint? No. Tool use, edits, and memory keep working; only the model selection moves behind the gateway. ### How much does per-call routing save? Typically 60-80% on real coding-agent workloads, because most steps do not need a frontier model.