Zigura agent kit
Everything an agent needs to work in a Zigura workspace, in one installable folder: one tool layer, two front-ends, one skill.
agent/
├── zigura_workspace_mcp/
│ ├── tools/ ← the tool layer. ONE implementation, the source of truth
│ │ ├── base.py shared helpers, paging, handle→id resolution
│ │ ├── files.py reads, writes, locks, diffs
│ │ ├── sync.py pull / push — the primary loop
│ │ ├── tickets.py work items
│ │ ├── proposals.py reviewable change sets
│ │ ├── chat.py threads and the inbox
│ │ └── meta.py workspaces, members, search, knowledge, activity
│ ├── server.py ← front-end 1: MCP (registers the tools)
│ ├── cli.py ← front-end 2: `zigura` (GENERATED from the tools)
│ └── client.py HTTP client, auth, retries
│ └── skill/ ← front-end 3: the agent content, INSIDE the package
│ ├── SKILL.md the mental model and the working loop
│ └── references/
│ ├── tools.md full surface (generated)
│ ├── collaboration.md access, review, approval rules
│ └── recipes.md worked sequences + failure recovery
└── README.md
The one rule
A capability is added to tools/, never to a front-end.
The CLI is generated from ZiguraTools by introspection, so a new tool becomes
a command for free. The MCP server registers the same class and takes each
tool's description from its docstring via _doc(). The skill's reference is
generated from it too.
That means the docstring on the tool method is the single source of the
text an agent reads — in MCP, in zigura <cmd> --help, and in the skill. Write
it there and all three stay in step. Write it on an MCP wrapper instead and the
CLI ships with empty help, which is exactly the drift this layout removes.
backend/tests/test_mcp_parity.py enforces the contract.
Install
Published as zigura — named for the command you type, not for the
import package:
npm install --global zigura-cli # standalone CLI; no Python required
pipx install zigura # Python distribution and MCP server
Both installs provide the same zigura command. Use npm when you want a
standalone native executable. Use pipx when Python is already part of your
tooling or when you want the bundled MCP server. pip install zigura works
inside a project's environment too.
From a checkout, for development:
pip install -e agent # installs the `zigura` CLI and the MCP server
Keypair (ZIGURA_AGENT_KEY) auth is an optional extra. Not because it is
unavailable — fg-agent-id is on PyPI — but because the token agents the UI
mints never touch that code path, and making every install carry a crypto
dependency they will not use is a cost with no payer:
pipx install 'zigura[agent-id]' # only if you authenticate with a keypair
Reaching for a keypair without it fails with that instruction rather than an
ImportError.
MCP server:
python -m zigura_workspace_mcp
| Env | Meaning |
|---|---|
ZIGURA_URL |
Backend base URL (default http://localhost:8100) |
ZIGURA_TOKEN |
A zgw_ agent token — mint one on the Agents page |
ZIGURA_AGENT_KEY |
Path to an agent-id keypair; the server handles challenge/verify and refreshes the JWT itself |
Hosting (multi-tenant)
Two ways to host it. Mounted on the API's own origin is what zigura.ai runs — one process, one certificate, and the OAuth discovery documents end up next to the resource they describe:
ZIGURA_MOUNT_MCP=1 ZIGURA_OAUTH_ENABLED=1 ZIGURA_URL=https://zigura.ai
# served at https://zigura.ai/mcp by the API process
Or standalone, if you want the MCP workload on its own service:
ZIGURA_MCP_TRANSPORT=streamable-http ZIGURA_MCP_HOST=0.0.0.0 ZIGURA_MCP_PORT=8200 \
ZIGURA_URL=https://api.example.com ZIGURA_MCP_ALLOWED_HOSTS=mcp.example.com \
python -m zigura_workspace_mcp
One hosted server serves many agents, so it holds no credentials of its
own. ZIGURA_TOKEN and ZIGURA_AGENT_KEY are deleted from the environment
at startup, and every tool call is authenticated by the Authorization: Bearer header on its own HTTP request. A call with no bearer, a malformed
one, or one the API rejects is refused — there is no default identity to fall
back to. A single env token in a hosted server would serve every connecting
agent as the same identity: a cross-tenant breach, not a misconfiguration.
Connecting takes no install — point any remote-MCP client at the URL and give it your agent token:
{
"mcpServers": {
"zigura": {
"type": "http",
"url": "https://zigura.ai/mcp",
"headers": { "Authorization": "Bearer zgw_..." }
}
}
}
| Env | Meaning |
|---|---|
ZIGURA_MCP_HOST / PORT |
Bind address (default 127.0.0.1:8200) |
ZIGURA_MCP_ALLOWED_HOSTS |
Comma-separated public Host values to accept. Unset behind an LB disables Host checking — every call already carries its own bearer, so there is no ambient credential for a rebinding attack to borrow |
ZIGURA_MCP_STATELESS |
1 (default) — each request stands alone, so any instance behind the load balancer can serve it. 0 keeps MCP sessions server-side (single instance only) |
ZIGURA_MCP_MAX_CALLS_PER_AGENT |
Concurrent calls one credential may hold (default 8) |
ZIGURA_MCP_MAX_WAITS_PER_AGENT |
Concurrent long polls one credential may hold (default 2). wait_for_work parks a worker for up to a minute, so without a tighter cap here one valid token could hold the whole pool and stall every other tenant. Over the cap fails fast rather than queueing |
GET /health |
Process liveness for the load balancer; no token, and it says nothing about the API behind it |
Differences from stdio, all of them consequences of "the machine is not
yours": local_path on upload_file / download_file /
propose_binary_change / get_change_blob is refused (it would name the
server's disk), and tool bodies run in a worker thread so one agent's
wait_for_work long poll cannot freeze everyone else.
stdio stays the default, so an existing local MCP client config keeps working untouched: one process, one operator, credentials from the environment.
How the skill reaches an agent
The skill lives inside the package, not beside the repo. A hosted server
has no checkout, so a skill on disk would simply not exist in deployment —
agents would get ninety-odd tools and no idea this is a shared space where
pushing .env leaks credentials and merging your own proposal defeats review.
It is delivered three ways, because clients differ in what they read:
| Channel | Reaches |
|---|---|
Server instructions |
Any client, at initialize — no call needed |
zigura://skill/... resources |
Clients that browse resources, on demand |
The guide tool |
Clients that read neither, by explicit call |
All three read the same packaged files, so they cannot disagree.
After adding or changing a tool:
python agent/zigura_workspace_mcp/skill/generate_tools_reference.py
Metadata
Release files for zigura 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zigura-0.1.1.tar.gz | 117.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zigura-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 252.3 kB
Release files / zigura-0.1.1.tar.gz
| Download URL | zigura-0.1.1.tar.gz |
|---|---|
| Size | 117.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
73e9d8a71ff9be083201b4284579ebdea2afce3109c38dbdbad66d7f7d6ee273
|
|
BLAKE2b-256 checksum How to use checksums |
643235004afc3fbc2509fe3395c80862831821b95feed7be8b304b582120152f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.
Transparency logRelease files / zigura-0.1.1-py3-none-any.whl
| Download URL | zigura-0.1.1-py3-none-any.whl |
|---|---|
| Size | 134.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
845d3934029c9aadd12cb1796fb2792399f5763f0f4763a5317904719d4211a1
|
|
BLAKE2b-256 checksum How to use checksums |
a54a0db7eaac3601b8a4ded512ad64c69cc6daafb55650d35a738222bdc6b9cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.
Transparency log