Skip to content

Skills, MCP & Tools

Skill manifests, cryptographic signing, MCP transports, tool classification, the Hub, and how to extend Kazma with new tools — all source-referenced.


TermMeaning
ToolA function the supervisor can call (file ops, shell, memory, web, …). Registered in ToolRegistry.
SkillA packaged, optionally-signed Python entry point + manifest that registers one or more tools. Lives under kazma-skills/manifests/ or the Hub registry.
MCP serverAn external Model Context Protocol server (stdio or SSE) whose tools are discovered at runtime and proxied into the agent.
HubThe skill registry/marketplace (kazma hub …) with certification and signing.

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:
    1. Pops _hitl_approved from args (line 349) — the double-gate flag.
    2. For danger tools, calls await safety.check(...) unless already approved (lines 384-417).
    3. Fail-closed: any exception in the safety check returns is_error=True “blocked — SafetyMiddleware unavailable” (lines 411-417).
  • 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.


  • 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.

A skill manifest declares the entry point, capabilities, and (when signed) integrity fields:

skill_manifest.yaml
name: my-skill
version: 1.0.0
description: "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.

Signingkazma hub sign <path> (kazma_core/hub/cli.py:703-770):

# Read the entry-point .py file
raw = py_file.read_bytes()
actual_hash = hashlib.sha256(raw).hexdigest()
# HMAC-SHA256 over the checksum, keyed by KAZMA_SECRET
signing_secret = secret or os.environ["KAZMA_SECRET"]
sig = hmac.new(
signing_secret.encode(),
actual_hash.encode(),
hashlib.sha256,
).hexdigest()
# Write both into skill_manifest.yaml
manifest["checksum"] = actual_hash
manifest["signature"] = sig

Requires 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):

ConditionBehavior
checksum present, mismatchSkillLoadError — “may have been tampered with” (lines 227-232).
signature present, no KAZMA_SECRETSkillLoadError (lines 237-241).
signature present, HMAC mismatchSkillLoadError (lines 242-250).
No checksum at allWarning logged; loads unsigned (backward compat, lines 251-257).
Any verification errorFatal — 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)”
  1. Create kazma-skills/manifests/my-skill/skill_manifest.yaml + my_skill.py.
  2. Implement the tool function(s) your skill exposes.
  3. (Recommended) Sign it:
Terminal window
export KAZMA_SECRET="$(openssl rand -hex 32)"
kazma hub sign kazma-skills/manifests/my-skill
kazma hub validate kazma-skills/manifests/my-skill
  1. Restart the server (or rely on skills.auto_discover). The loader verifies the signature with KAZMA_SECRET and refuses to load on mismatch.

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.

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.

  • 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: true flag (manifest.py:87-90 is_certified).

“Trust tiers” do NOT exist as a cryptographic/security feature. The only “trust” references in the codebase are (a) the plain certified: bool flag and (b) the trust: trusted string in kazma.yaml MCP 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):

Terminal window
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):

Terminal window
kazma hub list
kazma hub info author/skill-name

Install a specific version or the latest (cli.py:234-266):

Terminal window
kazma hub install author/[email protected]
kazma hub install author/skill-name

Or use the interactive skill-installation wizard (kazma_core/cli/wizard.py, main.py:117-123):

Terminal window
kazma wizard

hub install/hub update are currently stubbedregistry.py:269 only updates a DB row and performs no real fetch. Verify the skill source out-of-band until the installer is fully wired.


kazma-core/kazma_core/mcp/manager.py discovers and proxies external MCP servers.

TransportConfigAuth
stdiocommand: [argv] — subprocess spawn.None. The subprocess inherits the process environment.
sseurl + optional auth field.YesAsyncMCPManager._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.py for 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:

CategoryMatched keywords
dangerwrite, delete, remove, exec, run, shell, bash, command, kill, terminate, install, deploy, upload, download, fetch, request, post, put, patch
saferead, 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).

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: 1048576

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:

PrimitiveAlgorithmLocation
SigningEd25519 (not HMAC)delegation/security.py:81-119
EncryptionX25519 + AES-256-GCMdelegation/security.py:121-161
Wiringrequests signed on send, verified on receiptdelegation/protocol.py:153 (sign), :179-208 (verify, fail-closed)

This is the inter-agent delegation path — unrelated to MCP or skill signing.


The simplest extension is a registered tool function. Minimal pattern:

my_tools.py
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).


  • 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 certified flag and an unused trust: trusted string 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_tool unknown → danger is the safe default and should be preserved.