Skills, MCP & Tools
Skill manifests, cryptographic signing, MCP transports, tool classification, the Hub, and how to extend Kazma with new tools — all source-referenced.
1. Concepts
Section titled “1. Concepts”| Term | Meaning |
|---|---|
| Tool | A function the supervisor can call (file ops, shell, memory, web, …). Registered in ToolRegistry. |
| Skill | A packaged, optionally-signed Python entry point + manifest that registers one or more tools. Lives under kazma-skills/manifests/ or the Hub registry. |
| MCP server | An external Model Context Protocol server (stdio or SSE) whose tools are discovered at runtime and proxied into the agent. |
| Hub | The skill registry/marketplace (kazma hub …) with certification and signing. |
2. The ToolRegistry
Section titled “2. The ToolRegistry”kazma-core/kazma_core/agent/tool_registry.py is the registry the supervisor consults each turn. Key points:
execute(tool_name, arguments)(tool_registry.py:335) — the single execution path. It:- Pops
_hitl_approvedfrom args (line 349) — the double-gate flag. - For danger tools, calls
await safety.check(...)unless already approved (lines 384-417). - Fail-closed: any exception in the safety check returns
is_error=True“blocked — SafetyMiddleware unavailable” (lines 411-417).
- Pops
- Built-in tools include
memory_search(line 591),memory_store(line 607), and others registered at startup. - Vector memory is injected via
set_vector_memory(...)(tool_registry.py:95-98), stored in a module global.
See Security & Safety for the danger-tool classification that governs execution.
3. Skills
Section titled “3. Skills”3.1 Manifest location & discovery
Section titled “3.1 Manifest location & discovery”- Config:
skills.path: kazma-skills/manifests/,skills.auto_discover: true(kazma.yaml:55-57). - On startup, the loader scans the path and loads each
skill_manifest.yaml.
3.2 Manifest shape
Section titled “3.2 Manifest shape”A skill manifest declares the entry point, capabilities, and (when signed) integrity fields:
name: my-skillversion: 1.0.0description: "Example skill"entry_point: my_skill.py # Python file implementing the tool(s)capabilities: [mcp, file_read]author: your-org# Added by `kazma hub sign`:checksum: <sha256 of entry_point file>signature: <HMAC-SHA256 of the checksum>3.3 Cryptographic signing (HMAC-SHA256) — VERIFIED
Section titled “3.3 Cryptographic signing (HMAC-SHA256) — VERIFIED”Skill signing is real, fail-closed, and lives in the Hub subsystem.
Signing — kazma hub sign <path> (kazma_core/hub/cli.py:703-770):
# Read the entry-point .py fileraw = py_file.read_bytes()actual_hash = hashlib.sha256(raw).hexdigest()
# HMAC-SHA256 over the checksum, keyed by KAZMA_SECRETsigning_secret = secret or os.environ["KAZMA_SECRET"]sig = hmac.new( signing_secret.encode(), actual_hash.encode(), hashlib.sha256,).hexdigest()
# Write both into skill_manifest.yamlmanifest["checksum"] = actual_hashmanifest["signature"] = sigRequires KAZMA_SECRET (env or --secret); exits if unset (cli.py:728-733).
Verification on load (fail-closed) — kazma_core/hub/loader.py:206-266 (SkillLoader._load_module_from_file):
| Condition | Behavior |
|---|---|
checksum present, mismatch | SkillLoadError — “may have been tampered with” (lines 227-232). |
signature present, no KAZMA_SECRET | SkillLoadError (lines 237-241). |
signature present, HMAC mismatch | SkillLoadError (lines 242-250). |
No checksum at all | Warning logged; loads unsigned (backward compat, lines 251-257). |
| Any verification error | Fatal — not swallowed (lines 259-266). |
Verification uses hmac.compare_digest (constant-time) for both checksum and signature.
3.4 Adding a custom skill (minimal example)
Section titled “3.4 Adding a custom skill (minimal example)”- Create
kazma-skills/manifests/my-skill/skill_manifest.yaml+my_skill.py. - Implement the tool function(s) your skill exposes.
- (Recommended) Sign it:
export KAZMA_SECRET="$(openssl rand -hex 32)"kazma hub sign kazma-skills/manifests/my-skillkazma hub validate kazma-skills/manifests/my-skill- Restart the server (or rely on
skills.auto_discover). The loader verifies the signature withKAZMA_SECRETand refuses to load on mismatch.
4. The Hub (kazma hub)
Section titled “4. The Hub (kazma hub)”The Hub is a Click-based CLI for the skill registry/marketplace (kazma_core/hub/cli.py:104). See CLI Reference → hub for the full subcommand list.
4.1 Hub API authentication
Section titled “4.1 Hub API authentication”Write endpoints (kazma_core/hub/api.py:26-47, _require_auth) require an X-Kazma-Secret header matched via hmac.compare_digest. Fail-closed: if KAZMA_SECRET is unset, all writes are rejected.
4.2 Certification
Section titled “4.2 Certification”kazma hub certified— list certified skills.kazma hub badge <skill_ref>— show a certification badge.kazma hub check-certification <path>— check a skill against certification criteria.- The manifest carries a plain boolean
certified: trueflag (manifest.py:87-90is_certified).
“Trust tiers” do NOT exist as a cryptographic/security feature. The only “trust” references in the codebase are (a) the plain
certified: boolflag and (b) thetrust: trustedstring inkazma.yamlMCP config, which no code reads. This is explicitly flagged because older docs implied a tiered trust model.
4.3 Finding & installing skills (consumer workflow)
Section titled “4.3 Finding & installing skills (consumer workflow)”Search the registry by text, capability, tag, or author (cli.py:171-234):
kazma hub search "weather"kazma hub search --capabilities "image_analysis,data_processing"kazma hub search --tags "utility,beginner-friendly"kazma hub search --author "kazma-team"Browse installed skills and inspect one in detail (cli.py:208-303):
kazma hub listkazma hub info author/skill-nameInstall a specific version or the latest (cli.py:234-266):
kazma hub install author/skill-name@1.0.0kazma hub install author/skill-nameOr use the interactive skill-installation wizard (kazma_core/cli/wizard.py, main.py:117-123):
kazma wizard⚠
hub install/hub updateare currently stubbed —registry.py:269only updates a DB row and performs no real fetch. Verify the skill source out-of-band until the installer is fully wired.
5. MCP (Model Context Protocol)
Section titled “5. MCP (Model Context Protocol)”kazma-core/kazma_core/mcp/manager.py discovers and proxies external MCP servers.
5.1 Transports
Section titled “5.1 Transports”| Transport | Config | Auth |
|---|---|---|
stdio | command: [argv] — subprocess spawn. | None. The subprocess inherits the process environment. |
sse | url + optional auth field. | Yes — AsyncMCPManager._connect_sse (manager.py:452-505) supports a first-class auth config injecting Authorization: Bearer <token> or a custom header (lines 461-466). |
There is no authentication inside
mcp/manager.pyfor the stdio transport. Run stdio MCP servers you trust, in a sandboxed environment.
5.2 Tool classification (classify_mcp_tool)
Section titled “5.2 Tool classification (classify_mcp_tool)”MCP tools are runtime-discovered, so they can’t be on a static danger list. classify_mcp_tool() (manager.py:71-88) classifies by name-pattern substring matching:
| Category | Matched keywords |
|---|---|
danger | write, delete, remove, exec, run, shell, bash, command, kill, terminate, install, deploy, upload, download, fetch, request, post, put, patch |
safe | read, list, search, get, info, status, check, describe, query, count, exists, help |
unknown | (neither set matched) |
The gate at UnifiedToolExecutor.execute() (manager.py:725-727) treats both danger and unknown as requiring approval — i.e. unknown defaults to danger (fail-safe).
5.3 Configuring an MCP server
Section titled “5.3 Configuring an MCP server”mcp: servers: - name: filesystem transport: stdio trust: trusted # informational only — not enforced command: - npx - '-y' - '@modelcontextprotocol/server-filesystem' - kazma-data/workspace - name: secured-api transport: sse url: https://mcp.example.com/sse auth: type: bearer token: ${MCP_API_TOKEN} # supply via env ide_server: enabled: true root: . max_file_size: 10485765.4 IDE server
Section titled “5.4 IDE server”The in-process IDE/file MCP server (mcp.ide_server) exposes file read/write over the workspace root with a 1 MB per-file cap (max_file_size). Per audit reports, it is expected to require _secret matching KAZMA_SECRET via hmac.compare_digest; verify against mcp_server.py before relying on it.
6. Delegation (agent-to-agent) — separate crypto subsystem
Section titled “6. Delegation (agent-to-agent) — separate crypto subsystem”Distinct from skills and MCP, the delegation subsystem (kazma_core/delegation/) lets agents hand tasks to other agents with cryptographic integrity:
| Primitive | Algorithm | Location |
|---|---|---|
| Signing | Ed25519 (not HMAC) | delegation/security.py:81-119 |
| Encryption | X25519 + AES-256-GCM | delegation/security.py:121-161 |
| Wiring | requests signed on send, verified on receipt | delegation/protocol.py:153 (sign), :179-208 (verify, fail-closed) |
This is the inter-agent delegation path — unrelated to MCP or skill signing.
7. Adding a new tool (extension point)
Section titled “7. Adding a new tool (extension point)”The simplest extension is a registered tool function. Minimal pattern:
from kazma_core.agent.tool_registry import register_tool
@register_tool( name="weather_lookup", description="Look up current weather for a city.", danger=False, # set True if it should trigger HITL)async def weather_lookup(city: str) -> str: # ... your implementation ... return f"Weather in {city}: sunny, 25C"Register it during startup (or via a skill’s entry point). The supervisor will expose it to the LLM as a callable tool. If danger=True, execution flows through the HITL gate (see Security & Safety).
Documentation Audit Notes
Section titled “Documentation Audit Notes”- HMAC skill signing is real and fail-closed — contrary to what one might assume from the mix of subsystems, the loader genuinely refuses tampered/unsigned-by-required skills.
- “Trust tiers” are NOT a code feature. Documented explicitly to counter any implication of a tiered trust model. Only a boolean
certifiedflag and an unusedtrust: trustedstring exist. - MCP stdio transport has no auth. Only SSE supports bearer/custom-header auth. This is a meaningful security boundary for production planning.
classify_mcp_toolunknown → danger is the safe default and should be preserved.