Skip to content

Commit 483a053

Browse files
committed
Release v0.5.2 — full feature parity, 14 types, security hardening
Version bump to 0.5.2 across Rust, Python, JS, Go, docs, and metadata. Since v0.5.1: - 14 built-in types (added msf_options, credential_file, duration, regex_match) - Custom types via toolclad.toml with base type inheritance - Real timeout enforcement with process group kill (Rust) - Output parsers: json, jsonl, csv, xml, text (all 4 languages) - HTTP body JSON-escaping to prevent request injection - HTTP error semantics: 4xx client_error, 5xx server_error - Platform-aware evidence directories (no hardcoded /tmp) - Rich MCP schema generation with format/pattern/min/max constraints - command section optional for HTTP/MCP-only manifests - Full feature parity across Rust, Python, JavaScript, Go - Scope validation aligned across all implementations - String type rejects shell metacharacters by default - Unknown arg types fail closed
1 parent 1a85b83 commit 483a053

11 files changed

Lines changed: 73 additions & 15 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
|-------|-------|
1010
| Name | ToolClad |
1111
| Description | Declarative CLI tool interface contracts for agentic runtimes |
12-
| Version | 0.5.1 |
12+
| Version | 0.5.2 |
1313
| License | MIT (spec), Apache 2.0 (Symbiont integration) |
1414
| Repository | https://github.com/ThirdKeyAI/ToolClad |
1515

@@ -18,7 +18,7 @@
1818
ToolClad provides:
1919

2020
- **Manifest parsing** — Load and validate `.clad.toml` tool interface contracts (oneshot, session, browser modes)
21-
- **Argument validation** — 14 typed validators (10 core + 4 extended) with shell injection sanitization
21+
- **Argument validation** — 14 built-in type validators with shell injection sanitization, plus custom types via `toolclad.toml`
2222
- **Five execution backends** — Shell command, HTTP API, MCP proxy, PTY session, CDP/Playwright browser
2323
- **HTTP backend** — REST/GraphQL API tools with `{_secret:name}` template variable injection
2424
- **MCP proxy backend** — Governed passthrough to upstream MCP servers with field mapping

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type = "object"
4444
type = "string"
4545
```
4646

47-
The agent fills typed parameters. The executor validates, constructs the command, executes with timeout, and returns structured JSON. The agent never sees or generates a shell command.
47+
The agent fills typed parameters. The executor validates, constructs the command, executes with timeout, and returns structured JSON. The agent never sees or generates a shell command. The `[command]` section is optional for HTTP-only or MCP-only manifests.
4848

4949
## Security Model
5050

@@ -62,6 +62,9 @@ The dangerous action cannot be expressed because the interface doesn't permit it
6262
- **Process group isolation**: Tools spawned in new PGID; timeout kills entire process group (no zombies)
6363
- **Absolute path blocking**: `path` type rejects `/etc/shadow`, `C:\...` style paths
6464
- **Newline injection blocking**: `\n` and `\r` rejected in all string-based types
65+
- **HTTP body JSON-escaping**: Values interpolated into HTTP body templates are JSON-escaped to prevent injection
66+
- **Platform-aware evidence directories**: Evidence output uses platform-appropriate temp directories
67+
- **HTTP error semantics**: 4xx responses map to `client_error`, 5xx to `server_error` in evidence envelopes
6568
- **No eval**: Conditional evaluators use closed-vocabulary parsers, never dynamic code execution
6669

6770
## Packages
@@ -86,12 +89,12 @@ npm install toolclad # JavaScript / npm
8689
Each implementation provides:
8790

8891
- **Manifest parsing** -- load and validate `.clad.toml` files (oneshot, session, browser modes)
89-
- **14 type validators** -- 10 core + 4 extended, all with injection sanitization
92+
- **14 built-in type validators** -- all with injection sanitization, plus custom types via `toolclad.toml`
9093
- **Command construction** -- template interpolation with mappings, conditionals, defaults
91-
- **Execution** -- direct argv dispatch, process group kill on timeout, SHA-256 evidence hashing
94+
- **Execution** -- direct argv dispatch, real timeout enforcement with process group kill, SHA-256 evidence hashing
9295
- **Output parsers** -- builtin:json, builtin:xml, builtin:csv, builtin:jsonl, builtin:text, custom scripts
9396
- **Output schema validation** -- validates parsed results against `[output.schema]`
94-
- **MCP schema generation** -- auto-generate inputSchema + outputSchema for LLM tool use
97+
- **MCP schema generation** -- rich inputSchema + outputSchema with format/pattern constraints for LLM tool use
9598
- **Evidence envelopes** -- structured JSON with scan_id, timestamps, exit_code, stderr, output_hash
9699
- **CLI** -- `validate`, `run`, `schema`, `test` (dry run) subcommands
97100

SKILL.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: toolclad
33
title: ToolClad
44
description: Declarative tool interface contracts for agentic runtimes — oneshot CLI, interactive session (PTY), and browser (CDP/Playwright) modes with typed parameters, per-interaction Cedar gating, evidence envelopes
5-
version: 0.5.1
5+
version: 0.5.2
66
---
77

88
# ToolClad Development Skills Guide
@@ -20,7 +20,7 @@ ToolClad is a declarative manifest format (`.clad.toml`) that defines the comple
2020
- **Browser**: Maintain a governed headless browser session where navigation, clicks, form submission, and JS execution are typed, scoped, and policy-gated via CDP/Playwright.
2121

2222
All three modes share:
23-
- **Typed Parameters**: 10 built-in types with injection sanitization
23+
- **Typed Parameters**: 14 built-in types (10 core + 4 extended) with injection sanitization, plus custom types via `toolclad.toml`
2424
- **Per-Interaction Cedar Gating**: Every command/action evaluated against policies
2525
- **Evidence Envelopes**: Every execution wrapped in JSON with scan_id, timestamps, SHA-256 hash
2626
- **Scope Enforcement**: URL/target scope checking against allow-lists
@@ -108,6 +108,12 @@ description = "Tool output"
108108
| `path` | No traversal (`../`) | |
109109
| `ip_address` | Valid IPv4/IPv6 | |
110110
| `cidr` | Valid CIDR notation | |
111+
| `msf_options` | Semicolon-delimited `set KEY VALUE` | Metasploit options |
112+
| `credential_file` | Relative path + must exist | Username/password lists |
113+
| `duration` | Integer with suffix (`30`, `5m`, `2h`) | Timeout overrides |
114+
| `regex_match` | Matches declared `pattern` (required) | Module paths |
115+
116+
Custom types can be defined in `toolclad.toml` at the project root with a `base` type and additional constraints.
111117

112118
All types reject shell metacharacters (`;|&$\`(){}[]<>!`) by default.
113119

TOOLCLAD_DESIGN_SPEC.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ToolClad: Declarative Tool Interface Contracts for Agentic Runtimes
22

3-
**Version**: 0.5.1
3+
**Version**: 0.5.2
44
**Status**: Release Candidate
55
**Author**: Jascha Wanger / ThirdKey AI
66
**Date**: 2026-03-21
@@ -1981,6 +1981,19 @@ The 80/20 split from symbi-redteam confirms this: ~14 of 19 tools are pure templ
19811981

19821982
## Changelog
19831983

1984+
### v0.5.2 (2026-03-22)
1985+
1986+
- HTTP body JSON-escaping for injection safety in body templates
1987+
- Platform-aware evidence directories (OS-appropriate temp dirs)
1988+
- HTTP error semantics: 4xx maps to `client_error`, 5xx to `server_error`
1989+
- Real timeout enforcement with process group kill across all implementations
1990+
- Rich MCP schema generation with format/pattern constraints
1991+
- `[command]` section is now optional for HTTP-only and MCP-only manifests
1992+
- Custom types via `toolclad.toml` with `load_custom_types` and `validate_arg_with_custom_types` APIs
1993+
- Full feature parity across Rust, Python, JavaScript, and Go implementations
1994+
- All 14 built-in types fully implemented (no stubs)
1995+
- All 5 output parsers (json, jsonl, csv, xml, text) fully implemented
1996+
19841997
### v0.5.1 (2026-03-21)
19851998

19861999
- Adopted CDP-direct as primary browser backend (direct WebSocket to Chrome debug port, persistent daemon per tab, no Puppeteer/Playwright overhead). Playwright remains as optional convenience layer.

docs/api-reference.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ assert!(toolclad::validator::validate_arg("scan_type", &def, "ping").is_ok());
6060
assert!(toolclad::validator::validate_arg("scan_type", &def, "exploit").is_err());
6161
```
6262

63+
#### `validator::validate_arg_with_custom_types(name, def, value, custom_types) -> Result<()>`
64+
65+
Validate a single argument value against its type definition, resolving custom types from a loaded `toolclad.toml`. If the type is not a built-in type, it is looked up in `custom_types` and validated against the base type with any additional constraints.
66+
67+
```rust
68+
let custom_types = toolclad::load_custom_types("toolclad.toml")?;
69+
toolclad::validator::validate_arg_with_custom_types("service", &def, "ssh", &custom_types)?;
70+
```
71+
72+
#### `load_custom_types(path) -> Result<HashMap<String, CustomTypeDef>>`
73+
74+
Load custom type definitions from a `toolclad.toml` file. Returns a map of type name to definition (base type + constraints).
75+
76+
```rust
77+
let custom_types = toolclad::load_custom_types("toolclad.toml")?;
78+
// custom_types["service_protocol"] -> base: "enum", allowed: ["ssh", "ftp", ...]
79+
```
80+
6381
#### `executor::build_command(manifest, args) -> Result<Vec<String>>`
6482

6583
Construct the command argument array from a manifest and validated arguments. Does not execute. Returns the argv array that would be passed to `execve`.

docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
ToolClad is the tool execution layer of the [ThirdKey](https://thirdkey.ai) trust stack: [SchemaPin](https://schemapin.org) (tool integrity) / [AgentPin](https://agentpin.org) (agent identity) / **ToolClad** (tool contracts) / [Symbiont](https://symbiont.dev) (runtime).
66

7-
**Version**: 0.5.1 | **Status**: Release Candidate | **License**: MIT (spec), Apache 2.0 (Symbiont integration)
7+
**Version**: 0.5.2 | **Status**: Release Candidate | **License**: MIT (spec), Apache 2.0 (Symbiont integration)
88

99
---
1010

@@ -21,7 +21,7 @@ A ToolClad manifest answers four questions:
2121

2222
## Key Features
2323

24-
- **14 typed validators** -- 10 core + 4 extended types with shell injection sanitization on all string-based types
24+
- **14 built-in type validators** -- all with shell injection sanitization, plus custom types via `toolclad.toml`
2525
- **Five execution backends** -- Shell command, HTTP API, MCP proxy, PTY session, CDP browser
2626
- **Command templates** -- `{arg_name}` interpolation with mappings, conditionals, and defaults; no `sh -c`
2727
- **MCP schema generation** -- Auto-generate `inputSchema` + `outputSchema` from manifest declarations

docs/security-model.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,24 @@ sh -c "nmap -sT -sV --max-rate 1000 10.0.1.0/24"
4646

4747
Array-based execution means that even if a metacharacter somehow passed validation (it cannot, but defense in depth), the shell would never interpret it. There is no shell.
4848

49+
## HTTP Body JSON-Escaping
50+
51+
When values are interpolated into HTTP body templates (`[http].body_template`), they are JSON-escaped before substitution. This prevents injection attacks where an agent-supplied value could break out of a JSON string field and alter the structure of the request body. Quotes, backslashes, newlines, and control characters are all escaped.
52+
53+
## Platform-Aware Evidence Directories
54+
55+
Evidence output directories use platform-appropriate temporary directories (`/tmp` on Linux/macOS, `%TEMP%` on Windows) when no explicit `output_dir` is configured. This ensures evidence capture works correctly across operating systems without hardcoded paths.
56+
57+
## HTTP Error Semantics
58+
59+
HTTP backend responses are classified by status code:
60+
61+
- **2xx**: `success` status in the evidence envelope
62+
- **4xx**: `client_error` status -- the request was malformed or unauthorized
63+
- **5xx**: `server_error` status -- the upstream service failed
64+
65+
This classification gives LLM agents actionable error semantics for self-correction.
66+
4967
## Process Group Kill
5068

5169
Tools are spawned in a new process group (PGID). When a timeout fires, the executor kills the entire process group, not just the top-level process. This prevents:

js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "toolclad",
3-
"version": "0.5.1",
3+
"version": "0.5.2",
44
"type": "module",
55
"description": "Declarative tool interface contracts for agentic runtimes — typed parameters, command templates, evidence envelopes, session and browser modes",
66
"main": "src/index.js",

python/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "toolclad"
7-
version = "0.5.1"
7+
version = "0.5.2"
88
description = "Declarative tool interface contracts for agentic runtimes — typed parameters, command templates, evidence envelopes, session and browser modes"
99
readme = "README.md"
1010
requires-python = ">=3.9"

rust/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)