NativePort
← How-to

How to use Hermes Agent with NativePort

Configure Hermes Agent's custom-provider block for NativePort: the exact config, the fields that avoid a 400, and a real file-tool round trip.

Hermes Agent is NousResearch’s terminal-based coding and general-purpose agent: a CLI with its own tool loop, session memory and a providers: config block for pointing it at whichever model backend you want. Point that block at NativePort’s unified inference endpoint, and the same key and balance covering NativePort’s other search, scraping and voice APIs also runs Hermes’s model calls — pick any model NativePort’s catalog admits for your account, and switch later by changing one id, with no separate provider account to open first. This guide sets up that one connection; it doesn’t change anything about how Hermes itself works, and it isn’t a substitute for Hermes.

What you’ll need

  • A NativePort API key. Sign up to get a key and $5 in credits.
  • Hermes Agent’s current stable release, v0.19.1 (published 2026-07-30). The official installer bundles its own Python runtime, so there’s nothing separate to install first:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash

On Windows: iex (irm https://hermes-agent.nousresearch.com/install.ps1). Then source ~/.bashrc (or ~/.zshrc) and run hermes. If you’d rather install via pip install hermes-agent, note that PyPI can lag behind the officially published release — the curl/PowerShell installer always tracks the current tag.

  • Your key exported as an environment variable, never hardcoded:
export NATIVEPORT_API_KEY="<your NativePort API key>"

Configure the nativeport provider

Hermes’s config lives at ~/.hermes/config.yaml (%LOCALAPPDATA%\hermes\config.yaml on native Windows), or wherever HERMES_HOME points if you’ve overridden it. Add a named provider block for NativePort with hermes config edit, or hand-edit the file directly — this is the current, verified-working effective shape:

providers:
  nativeport:
    base_url: "https://api.nativeport.ai/inference/v1"
    key_env: "NATIVEPORT_API_KEY"
    transport: "chat_completions"
model:
  provider: "nativeport"
  default: "openai/gpt-4o-mini"
  context_length: 128000
  max_tokens: 8000
agent:
  reasoning_effort: ""

Every field here is load-bearing:

  • key_env, not a literal api_key value — this reads the key from the named environment variable rather than writing it into the config file on disk.
  • transport: "chat_completions" matches NativePort’s /inference/v1 route, which is OpenAI Chat Completions-shaped. It’s also Hermes’s default if omitted, but setting it explicitly avoids relying on that default silently changing later.
  • model.default must be NativePort’s full canonical id, including the provider prefix (openai/gpt-4o-mini, not a bare gpt-4o-mini) — Hermes forwards this string unchanged as the wire model value. Avoid any id containing gpt-5 or codex: Hermes rewrites the system-prompt message’s role to developer whenever the model id matches either substring, a shape NativePort’s unified endpoint doesn’t admit (messages[0].role has to be system, user, assistant or tool). openai/gpt-4o-mini is the verified-working example used throughout this guide.
  • context_length: 128000 — Hermes refuses to use any model reporting under 64,000 tokens of context, and NativePort’s catalog doesn’t expose a context-window field for auto-detection against a gateway route, so set it explicitly rather than relying on that to resolve on its own.
  • max_tokens: 8000 — set this explicitly. Left unset, Hermes derives its own output-token ceiling by matching substrings of the model id against its own internal catalog and can size a request well above what NativePort’s gateway accepts for that model, which fails closed with a 400 rather than a silent truncation.
  • agent.reasoning_effort: "" is the fix for a real, otherwise-silent failure: Hermes’s generic custom-provider profile attaches a top-level reasoning_effort field to every request once any reasoning configuration resolves to non-None — independent of whether the model you picked is a reasoning model at all. NativePort’s unified endpoint validates against a deliberately narrow cross-provider field set that doesn’t include reasoning_effort, so the request 400s before it ever reaches a provider. Setting this to an explicit empty string stops Hermes from emitting the field.

Validate the config

hermes config check
hermes doctor

hermes doctor may print one advisory-only note — something like “model.default is vendor-prefixed but provider is nativeport” — and it’s a false positive worth ignoring here: that heuristic assumes a vendor-prefixed id implies a different kind of routing provider, but NativePort’s unified API specifically requires the vendor-prefixed canonical id (openai/...), so keep the prefix.

Run a plain one-shot call

With the config above set as your default provider and model, a plain call needs no extra flags:

hermes chat -q "Reply with exactly the single word: PONG"

To call a different model or provider ad hoc without touching the config file, pass them explicitly: hermes chat --provider nativeport --model openai/gpt-4o-mini -q "...".

Confirm a local file tool works end to end

Hermes’s read_file tool resolves relative paths against your real home directory by default, not necessarily the directory you’re running from — pass an absolute path to sidestep that entirely:

mkdir -p "$HOME/hermes-nativeport-demo"
echo "The verification code is 7420." > "$HOME/hermes-nativeport-demo/code.txt"

hermes chat --toolsets file \
  -q "Read the file at $HOME/hermes-nativeport-demo/code.txt using its exact absolute path, then reply with exactly the verification code it contains."

Hermes’s default permission mode prompts for confirmation before running a tool — approve it when asked. A correct run shows the assistant requesting read_file with your absolute path as the argument, a tool-result message carrying the file’s real content, and a final reply of 7420, confirming tool-call generation, local execution and tool-result replay all went through NativePort cleanly on this route.

What isn’t covered here

This guide confirms the main chat-and-tool-use loop; it doesn’t independently verify streamed output against this specific route, so it isn’t claimed above. Hermes’s toolset system covers more than filehermes tools enable <name> / hermes tools list manage what’s active — but a single deterministic read-only tool is the right first check before turning on anything with write access.

Troubleshooting

  • 400 naming reasoning_effort. agent.reasoning_effort: "" is missing from config.yaml, or was set on a different config file than the one Hermes is actually reading (hermes config path prints the active one).
  • 400 naming max_completion_tokens or a similar output-token field. model.max_tokens is unset or too high for the model behind model.default. 8000 is verified safe for openai/gpt-4o-mini; lower it further if you switch to a smaller-ceiling model.
  • A context-window error at startup. The configured model reports under Hermes’s 64,000-token minimum, or context_length wasn’t set explicitly for a proxy route like this one. Set it to a real number for the model you’re using.
  • 400 naming messages[0].role. The configured model id contains gpt-5 or codex — switch to an id outside that family, like openai/gpt-4o-mini.
  • Session titles fail to generate, but the conversation itself completes fine. This is a separate, cosmetic background call Hermes makes to auto-title a session; it can independently request an output-token ceiling above what the configured model actually supports, unrelated to model.max_tokens on your main call. It doesn’t affect the conversation itself — safe to ignore.
  • 401 on every call. NATIVEPORT_API_KEY isn’t set in the environment Hermes runs in, or key_env in the provider block points at a different variable name.
  • 402 on every call. The NativePort balance is at $0; every request fails closed rather than degrading. Top up and retry.

What this costs

Usage is metered at NativePort’s real, pass-through per-token rate for whichever model you configure, with no markup from routing it through Hermes. Check GET /inference/v1/models/openai/gpt-4o-mini (or your chosen model id) with your key for the current live rate before budgeting a workload against it — see pricing for the full billing model. A zero balance fails every request with 402 rather than degrading output.

Where to go next