Thin, stdlib-only client + CLI for the NatureLM-Idun-5-MoE agent on Azure AI Foundry — with a pluggable multi-backend layer.
Runs headless on Termux/Android with nothing but the Python standard library
(no httpx, no azure-identity, no Flask). Idun is a tool agent (reasons +
calls tools like web_search); this SDK surfaces the full agent trajectory
(reasoning + tool calls) instead of a black-box answer.
The same IdunClient API dispatches to three interchangeable backends. Non-Azure
backends need no FOUNDRY_TOKEN, so the SDK keeps working even when the Azure
subscription is suspended.
| Backend | Credentials | Cost | Notes |
|---|---|---|---|
azure |
Entra device-code (idun login) |
paid | default; full tool-agent trajectory |
hf |
HF_TOKEN / ~/hf_token.txt |
free | Hugging Face Inference API; flat answer |
github |
GITHUB_TOKEN / ~/github_token.txt |
free tier | GitHub Models (OpenAI-compatible); needs Copilot/VS Code routing — plain PAT returns 404 |
openai |
OPENAI_API_KEY / ~/openai_token.txt |
paid/free tier | OpenAI-compatible /v1/chat/completions; any OpenAI-compatible endpoint via OPENAI_BASE |
Set the backend globally via env (IDUN_BACKEND=hf) or per-call (--backend).
Model overrides: HF_MODEL, GITHUB_MODEL, OPENAI_MODEL, OPENAI_BASE.
Non-Azure backends return a flat answer (res.steps == []) — the tool-agent
trajectory is an Azure-Idun feature.
pip install idun-sdkInstalls the idun CLI, the idun Python package, and the stdlib MCP server
idun_mcp.py. Requires Python ≥ 3.8; no third-party dependencies
(stdlib-only, runs headless on Termux/Android).
Verify the install:
idun --help # shows all commands
idun welcome # banner + matrix introIdun is backend-agnostic. Pick a backend once with the wizard (writes
~/.idunrc, sourced automatically by your shell), or set credentials per
backend. Run the wizard for a guided, universal first-run setup:
idun wizard # choose backend, capture creds/config -> ~/.idunrc
source ~/.idunrc # or restart your shell
idun status # confirm active backend + credential state| Backend | Setup command | Stored at / env |
|---|---|---|
azure |
idun login |
~/foundry_token.txt |
hf |
idun login --backend hf |
~/hf_token.txt / HF_TOKEN |
github |
idun login --backend github |
~/github_token.txt / GITHUB_TOKEN |
openai |
idun login --backend openai |
~/openai_token.txt / OPENAI_API_KEY |
Azure (default). idun login runs a device-code flow and stores an Entra
bearer token. No admin role required — any tenant user with agent RBAC can
run it; admin rights are only needed to configure the agent, not to use it.
The token auto-rotates before expiry.
Hugging Face / GitHub. The wizard or idun login --backend <x> prompts for
a token and saves it (0600). Both offer a free tier; no Azure subscription or
card needed.
Globally via env, or per call via --backend:
export IDUN_BACKEND=hf # all future calls use HF
idun chat --backend github "Hi" # one-off overrideModel overrides (optional): HF_MODEL, GITHUB_MODEL.
idun chat "Hello" # azure (needs login first)
idun chat --backend hf "Hello" # any backend with creds setidun chat "Summarize Contoso's sustainability comms in one sentence."
idun trace --backend azure "Use web_search to find the current CEO of Contoso."from idun import IdunClient
# Azure (default)
res = IdunClient().complete("Your prompt here")
print(res.text) # final answer
for s in res.steps: # agent trajectory
print(s.kind, s.tool, s.query, s.status)
# Hugging Face (no Azure token needed)
res = IdunClient(backend="hf", hf_token="hf_xxx",
hf_model="microsoft/phi-3-mini-4k-instruct").complete("Hello")
print(res.text)| Command | Purpose |
|---|---|
idun wizard |
universal first-run setup |
idun login [--backend X] |
store backend credentials |
idun status |
show active backend + credential state |
idun chat |
final answer only |
idun trace |
full trajectory (steps + text) |
idun export |
trajectory as JSON / Markdown |
idun packs / idun run |
curated prompt packs (e.g. Contoso) |
idun diff |
side-by-side trace diff of two prompts |
idun token |
inspect / refresh the Foundry token |
idun logo |
print the Foundry logo |
The hf command wraps the Hugging Face Hub + Inference API (stdlib-only for
whoami / status; push uses the optional huggingface_hub client):
idun hf whoami # validate token, show HF user
idun hf status microsoft/phi-3-mini-4k-instruct # exists? gated? private? task?
idun hf push Qapdex/my-agent-out a.txt b.txt # create repo + upload filespush needs pip install huggingface_hub (kept optional so the SDK stays
stdlib-only for everything else). Upload under your user namespace
(Qapdex/...), not an org, unless your token has write rights there.
idun_mcp.py is a zero-dependency stdio MCP server (no FastMCP / httpx):
python3 idun_mcp.pyExposes idun_chat(prompt) and idun_trace(prompt). Add to any MCP client:
{ "mcpServers": { "idun": { "command": "python3", "args": ["/abs/path/idun-sdk/idun_mcp.py"] } } }Docs mirror (GitMCP): https://gitmcp.io/qapdex-maker/idun-sdk/sse
Idun pairs well with Sentry's MCP server
so an agent can both call Idun and inspect Sentry errors. Add it remotely
(OAuth, note the /mcp suffix):
{ "mcpServers": { "sentry": { "url": "https://mcp.sentry.dev/mcp" } } }Recommended combo: idun (calls the agent) + idun-docs (reads SDK docs) +
sentry (queries error tracking).
POST {base}/api/projects/{project}/agents/{agent}/endpoint/protocols/openai/responses?api-version=2025-05-15-preview
Authorization: Bearer ***
{"model": "model-router", "input": "<prompt>", "max_output_tokens": 4096}
modelMUST be"model-router"(agent id is in the URL).- Do not send a
toolskey — the agent owns its tools (else400 invalid_payload).