Skip to content

Offline / air-gapped install

kneo-agent is a pure-Python library that does not phone home and does not require network access at runtime — beyond whatever your own application chooses to talk to. This page explains how to install it on a host with no outbound internet, and what that means for your audit story.

No phone-home guarantee

The SDK does not perform analytics, telemetry, update checks, or "call home" requests of any kind. The only outbound network calls the SDK can make are:

  1. Provider SDK calls through the optional extras (openai-agents, langchain, google-adk). These only trigger when your code invokes an agent that uses those extras, and they go to the endpoints your code configured (e.g. base_url=... for a local Ollama).
  2. MCP HTTP / SSE transports (MCPServerConfig.http() / .sse()). These only trigger when your code registers an MCP server.

The [telemetry] extra ships only opentelemetry-api, which has no exporter — your deployment chooses where to ship spans (none, a local OTLP collector, etc.). See self_hosted_observability.md.

For a code-level audit, grep for outbound calls in kneo_agent/ — you will find urllib.request.urlopen only inside kneo_agent/mcp/client.py (the MCP transports) and nothing else.

Installing in an air-gapped environment

The standard pattern: download wheels on a connected host, transfer them to the air-gapped host, install with --no-index --find-links.

1. On a connected host

# Choose the same Python version + platform as the target host.
# --platform / --python-version match what `pip install` would
# resolve on the target.
mkdir -p wheelhouse
pip download \
    --dest wheelhouse \
    --python-version 3.12 \
    --platform manylinux2014_x86_64 \
    --only-binary=:all: \
    "kneo-agent[all]==1.2.0"

Adjust --platform for your target (e.g. manylinux_2_28_x86_64, macosx_14_0_arm64). Drop [all] to omit provider extras you don't need; the matching set keeps only core + PyYAML.

2. Transfer the wheelhouse

rsync, scp, USB, whatever your security model requires. The wheelhouse is just a directory of .whl and .tar.gz files — nothing in it executes during transfer.

3. On the air-gapped host

python -m venv /opt/myapp/venv
source /opt/myapp/venv/bin/activate
pip install --no-index --find-links /path/to/wheelhouse \
    "kneo-agent[all]==1.2.0"

--no-index tells pip not to consult any package index; --find-links points it at the local directory. If the resolver complains about a missing dependency, your pip download step on the connected host missed it — re-run pip download with the same flags as your target install, or add the missing package name explicitly.

4. Verify

python -c "import kneo_agent; print(kneo_agent.__version__)"
# → 1.2.0

For the no-phone-home guarantee, smoke-test on a host with no outbound network at all:

# Block all egress (example with iptables; adjust for your platform).
sudo iptables -A OUTPUT -j REJECT
python -c "
from kneo_agent import AgentBuilder
agent = AgentBuilder().with_name('air-gap').build()
print(agent)
"

Importing the SDK and constructing an Agent (without invoking a provider) makes zero outbound calls.

Reproducible installs

For audit-grade reproducibility:

pip download --dest wheelhouse \
    --no-deps \
    "kneo-agent==1.2.0"
pip download --dest wheelhouse "kneo-agent==1.2.0"   # then resolve deps
sha256sum wheelhouse/* > wheelhouse.SHA256SUMS

Verify on the target host:

sha256sum -c wheelhouse.SHA256SUMS

If your release pipeline already produces a manifest, use that as the source of truth — kneo-agent has nothing kneo-specific to add beyond standard pip-wheel discipline.

Updating in place

Because the SDK does not check for updates, upgrading is entirely your call. Re-run the pip download step on a connected host against the new version, transfer, and re-install with --no-index --find-links against the new wheelhouse.

The upgrading_to_1.2.md guide covers the user-facing changes between minor releases.

What you still need network access to (just not from the SDK itself)

  • Whatever LLM provider your agent talks to (a local Ollama / vLLM / llama.cpp server is fine; that's still on-prem).
  • Whatever MCP servers your agent uses (MCPServerConfig can point at a localhost URL — no public network needed).
  • Whatever observability backend your application ships spans to (a local OTLP collector / Jaeger / Tempo / SigNoz — see self_hosted_observability.md).

The library installs and runs without any of those. They become required only when your application code chooses to use them.