Python SDK + MCP server for the Intellign optimization platform — describe assignment, scheduling, routing, allocation, or matching problems and get solved rosters back. All computation runs server-side; this package is a typed HTTP client plus an MCP wrapper.
Guides: SDK guide · REST API reference · MCP server · Deployment · Examples
pip install intellign # core SDK (httpx + pydantic)
pip install "intellign[mcp]" # + intellign-mcp server
pip install "intellign[pandas]" # + Result.to_dataframe()
pip install "intellign[ical]" # + Result.export_ical()Python ≥ 3.10. Get an API key from your Intellign dashboard — ik_live_
(production) or ik_test_ (free sandbox: ≤200 entities/targets, capped
solver budget, no quota usage).
from intellign import Client, Problem
client = Client(
api_key="ik_live_...",
base_url="https://api.intellign.ai", # or your deployment / http://localhost:8000
)
nurses = [
{"id": "n1", "name": "Ada", "skills": "triage,general"},
{"id": "n2", "name": "Bola", "skills": "surgery"},
]
clinics = [
{"id": "c1", "name": "ER", "required_skills": "triage", "capacity": 1},
{"id": "c2", "name": "Theatre", "required_skills": "surgery", "capacity": 1},
]
problem = (
Problem.assignment(name="Nurse assignment")
.entities(rows=nurses)
.targets(rows=clinics)
.maximize("skill_match", weight=70,
entity_column="skills", target_column="required_skills")
.maximize("workload_balance", weight=30, target_column="capacity")
.require("entity.skills superset_of target.required_skills") # hard constraint
.quality("balanced") # fast | balanced | best
)
result = client.submit(problem).wait()
for a in result.assignments:
print(a["resource_id"], "->", a["target_id"])
df = result.to_dataframe() # optional pandas extraAsync — identical surface, plus SSE progress streaming:
from intellign import AsyncClient
async with AsyncClient(api_key="ik_live_...") as client:
job = await client.submit(problem)
async for event in job.stream_progress():
print(event.get("current_generation"), event.get("best_fitness"))
result = await job.result()| Capability | SDK entry point | Example |
|---|---|---|
| Structured solve (builder) | Problem.assignment()... → client.submit() |
examples/01 |
| Upload data once, reference by id | client.upload_dataset("team.csv") → .entities(dataset_id=...) |
examples/02 |
| Natural-language solve | client.solve_nl("assign vans to zones...", ds_a, ds_b) |
examples/03 |
| Starter templates | client.templates() / client.template(name) |
examples/04 |
| Live progress (SSE) | job.stream_progress() (sync or async) |
examples/05 |
| Webhooks on completion | client.create_webhook(url) — HMAC-signed deliveries |
examples/06 |
| Guided conversational flow | client.create_session() / send_message() / export_session() |
examples/07 |
| Robust error handling | typed exceptions, idempotency keys, retries | examples/08 |
| LLM tool access (MCP) | intellign-mcp — stdio + Streamable HTTP |
MCP guide |
Objectives are named metrics with weights (live catalog:
client.capabilities()): skill_match, distance, workload_balance,
attribute_match, cost, preference_match — each maximize or minimize.
Constraints use a small formal grammar (invalid expressions are rejected at create time with the reason):
entity.skills superset_of target.required_skills
entity.hours <= target.max_hours # also >= == < >, or numeric literal
sum(entity.load) <= target.capacity
haversine(entity.location, target.location) <= 25
entity.region in ['north', 'east']
.require(expr) = hard (violation weight 100); .require(expr, hard=False) = soft.
client.submit() returns a Job: .status(), .wait(timeout=300),
.result(), .stream_progress(). Solves are asynchronous server-side —
prefer webhooks over polling for production integrations.
Result: .assignments (list of dicts with resource_id/target_id/
score/rationale), .metrics, .best_fitness, .to_dataframe(),
.export_ical(path) for scheduling results with start/end timestamps.
Every API failure raises a typed subclass of IntelligError carrying
.code, .status_code, and .request_id (quote it in support requests):
AuthenticationError, ScopeError, InvalidSpecError, NotFoundError,
ConflictError, QuotaError, RateLimitError (.retry_after),
SandboxLimitError, SolveFailedError, ServerError.
- The client automatically retries 429/502/503/504 (honoring
Retry-After). - Pass
idempotency_key="your-uuid"tocreate_problem/solve_problem— retries return the original response instead of duplicating work (24 h window). - Rate limits per key/minute by plan: free 30, pro 120, enterprise 600.
Full error taxonomy and endpoint reference: API.md.
hook = client.create_webhook("https://myapp.com/hooks/intellign")
secret = hook["secret"] # shown exactly once — store itDeliveries are POSTs with X-Intellign-Event and
X-Intellign-Signature: sha256=<hmac_sha256(secret, raw_body)>; verify with
a constant-time compare (working receiver: examples/06_webhooks.py).
Failed deliveries retry 3× and everything is inspectable via
client.webhook_deliveries(id).
Expose Intellign as tools to Claude or any MCP client:
pip install "intellign[mcp]"
INTELLIGN_API_KEY=ik_live_... intellign-mcp # stdio (local)
intellign-mcp --transport http --port 8001 --stateless # hosted, multi-tenantTools: create_problem, solve_problem, get_status, get_result,
list_templates, get_template. Resources: intellign://schema/spec,
intellign://capabilities. Over HTTP each request authenticates with its
own Authorization: Bearer ik_... header.
Setup + hosting: MCP.md
and DEPLOYMENT.md.
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest -q # unit suite (offline)
# contract tests against a live server:
INTELLIGN_CONTRACT_BASE_URL=http://localhost:8000 \
INTELLIGN_CONTRACT_API_KEY=ik_... .venv/bin/python -m pytest -m contract -q
.venv/bin/python -m build # wheel + sdist into dist/Layout: src/intellign/ (client, spec models, builders, job/result, errors,
mcp/server.py), tests/ (unit, respx-mocked), tests/contract/
(env-gated, live server), examples/ (runnable per capability).
CI (.github/workflows/ci.yml) tests every push/PR on Python 3.10–3.12 and
builds artifacts. Publishing (publish.yml) uses PyPI Trusted Publishing:
- Bump
src/intellign/_version.py. - Commit, tag
vX.Y.Z, push the tag. - Create a GitHub Release from the tag → workflow builds, verifies the tag
matches the package version, and publishes to PyPI via OIDC (no token
secrets). One-time setup: add this repo as a trusted publisher on
pypi.org (workflow
publish.yml, environmentpypi) and create thepypienvironment in repo settings.
MIT