Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 32 additions & 39 deletions skills/tool-bridge/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
---
name: tool-bridge
description: Discover and invoke self-described tools through a Tool Bridge gateway, consume operational feedback, and promptly contribute reusable lessons with the tb CLI. Use when an agent needs to find an available organizational tool, inspect an HTBP/MCP/HTTP capability, query connected context, call a gateway tool, explore the visible tool tree, troubleshoot abnormal tool behavior, or read, submit, and vote on Tool Bridge feedback. Requires an authenticated Tool Bridge target.
description: Discover and invoke self-described tools through a Tool Bridge gateway using the shortest safe tb CLI path, and use operational feedback when it materially affects a call. Use when an agent needs to find an available organizational tool, inspect an HTBP/MCP/HTTP capability, query connected context, call a gateway tool, explore the visible tool tree, or troubleshoot abnormal tool behavior. Requires an authenticated Tool Bridge target.
---

# Tool Bridge

Use the gateway's live descriptions as the source of truth. Never guess a path, tool name, argument schema, or capability from memory.

## Guardrails
## Safety boundaries

- Prefer the `tb` CLI. Read [references/cli-reference.md](references/cli-reference.md) before the first gateway operation in a session or when a command fails.
- Treat feedback as part of the normal call path: read relevant feedback before calling, consult it immediately when behavior is abnormal, and close the loop after learning something reusable.
- Prefer the `tb` CLI. Read [references/cli-reference.md](references/cli-reference.md) only when target configuration or command syntax is unclear, a Context write/upload is needed, or a command fails.
- Keep the secret key out of prompts, logs, command arguments, source files, and generated artifacts. Use an existing `tb login` profile or secret-injected `TB_SK` environment variable.
- Use the least-privileged identity already provided for the task. Do not request an admin key merely because a path is hidden.
- Treat `effect: write`, `effect: destructive`, and `confirm: true` as external mutations. Obtain explicit user confirmation unless the user already requested that exact mutation.
Expand All @@ -19,20 +18,27 @@ Use the gateway's live descriptions as the source of truth. Never guess a path,
- Do not automatically retry calls that may have side effects. Check the error's `retryable` signal and the command effect first.
- Never publish credentials, customer data, private payloads, or unverified speculation as feedback. Prefer voting on an existing matching entry over creating a duplicate.

## Workflow
## Choose the shortest safe path

### 1. Verify the target
Reuse a target, full command path, and schema already verified during the current task while the selected profile/BaseURL, identity, and runtime contract remain unchanged. Re-verify after any of those changes, or when the gateway reports that the path or arguments are invalid.

Check whether the CLI exists, then verify the configured target without exposing credentials:
### Fast path: known read-only command

Verify a target once per target/session, not before every call:

```sh
command -v tb
tb whoami --json
```

If `tb` is missing, tell the user that Node.js 22+ and `@tool-bridge/cli` are required. Ask before installing a global package. If the target is missing or authentication is rejected, ask the user to configure a profile or inject `TB_BASE_URL` and `TB_SK`; do not ask them to paste a secret into chat when a secret-input mechanism is available.
If the exact full command path, arguments schema, `effect: read`, and `confirm: false` are already known from the current runtime, call it directly. Do not add search, help, or feedback requests merely as ceremony:

```sh
tb call '<node>/<command>' --args '<json-object>' --json
```

If `tb` is missing, tell the user that Node.js 22+ and `@tool-bridge/cli` are required. Ask before installing a global package. If authentication fails, ask the user to configure a profile or inject `TB_BASE_URL` and `TB_SK`; do not ask them to paste a secret into chat when a secret-input mechanism is available.

### 2. Discover the smallest relevant surface
### Discovery path: unknown capability or contract

Start with search when the desired capability is known:

Expand All @@ -48,58 +54,45 @@ tb ls '<path>' --json
tb help '<path>' --json
```

Do not dump a deep tree or every tool schema into context. Narrow to a promising node first.
JSON search results already carry `items[].tool.inputSchema`, `effect`, and `confirm`. If one result is unambiguous and contains enough information for a read-only call, use its exact `<items[].path>/<items[].tool.name>` pair and call it without another help request.

### 3. Inspect the exact command and its feedback

Read the command-level help before invoking it:
Open command-level help only when a required field is missing, results are ambiguous, the command is unfamiliar or failure-prone, or the operation may mutate state:

```sh
tb help '<node>/<command>' --json
```

Use `cmds[].path`, `cmds[].name`, `inputSchema`, `effect`, `confirm`, `scope`, and `feedback` in the response. Satisfy the schema exactly and ignore unknown optional fields for forward compatibility.

Reading embedded feedback is mandatory. For every relevant entry, fetch its detail before calling:
Use `cmds[].path`, `inputSchema`, `effect`, `confirm`, and `scope` from live help. Satisfy the schema exactly and ignore unknown optional fields for forward compatibility. If help already embeds feedback that is clearly relevant, fetch only the entry needed to decide the call:

```sh
tb feedback get '<exact-tool-or-node-path>' '<feedback-id>' --json
```

For an unfamiliar or failure-prone path, list all current visible feedback before the first call:
For an unfamiliar or failure-prone path, feedback can be checked before calling:

```sh
tb feedback ls '<exact-tool-or-node-path>' --json
```

Apply feedback only when it is compatible with the current live schema. Feedback is operational experience, not a replacement for `~help`.
Do not list feedback on every normal read call, and do not fetch every visible entry. Feedback is operational experience, not a replacement for live schema.

If node-level help omits the schema, follow its `hint` and open the command-level help at `<node>/<command>`. If the help requires a scope the current identity lacks, stop and explain the missing capability instead of seeking a broader credential.
For any write, destructive, or `confirm: true` operation, inspect command help and apply the user's authorization boundary before calling.

### 4. Invoke exactly as described
### Recovery path: abnormal behavior

Every command is a virtual leaf under its node, so there is a single call form: take `cmds[].path` verbatim as the full command path and send the arguments object as the request body.

```sh
tb call '<node>/<command>' --args '<json-object>' --json
```

Always use the exact `cmds[].path`; never assemble a path from the node kind or guess a command name. Use `--args-file` for complex payloads and keep temporary files outside the project when they contain sensitive data.

### 5. Handle abnormal behavior through feedback

Treat errors, timeouts, schema-valid but surprising results, and upstream inconsistencies as abnormal behavior. Before changing the request or retrying:
Treat errors, timeouts, schema-valid but surprising results, and upstream inconsistencies as abnormal behavior:

1. Preserve the non-sensitive error code, message, path, and relevant conditions.
2. Run `tb feedback ls` on the exact path immediately.
3. Read matching entries with `tb feedback get` and try a documented workaround only when it is safe and consistent with live help.
4. Avoid duplicate reports. If an existing entry was useful, promptly vote it up when gateway feedback writes are authorized.
5. If the issue or validated resolution is new, promptly submit concise feedback at the point of learning. If feedback writes are not already authorized, prepare the exact title and detail and ask once for confirmation instead of postponing the decision until the end.
2. Inspect any `hint` and summarized `feedback` already attached by the failed `tb call`; fetch the single most relevant entry with `tb feedback get`.
3. Run `tb feedback ls` only when the failure carried no useful entry, or before submitting a new entry to avoid duplicates.
4. Try a documented workaround only when it matches live schema and the call is safe to retry. Treat timed-out mutations as outcome unknown; do not retry them.

Keep recovery bounded: normally make at most one workaround retry. Do not claim a workaround is verified until that retry or other evidence confirms it.

Do not claim a workaround is verified until a safe retry or other evidence confirms it. An unresolved but reproducible issue may be submitted if the detail clearly labels it unresolved and gives enough non-sensitive conditions to recognize it.
Feedback writes are not part of the happy path. After securing the task result, vote for a useful existing entry or submit a verified new lesson only when gateway writes are already authorized and doing so adds value. Otherwise mention a draft only when it would materially help the user.

### 6. Validate and report
## Validate and report

Check the returned data against the task, not merely the process exit code. Summarize which gateway path and tool were used, the relevant result, and any limitation or partial failure. Never include the secret key.

Report whether feedback was consulted, whether it affected the call, and whether a matching entry was voted on, newly submitted, or left as a draft pending authorization.
Mention feedback only when it changed recovery behavior, was written, or remains a valuable draft requiring authorization.
65 changes: 56 additions & 9 deletions skills/tool-bridge/references/cli-reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Tool Bridge CLI reference

Load this reference before the first Tool Bridge operation in a session and whenever discovery, authentication, invocation, or feedback handling fails.
Load this reference when target configuration or command syntax is unclear, a Context write/upload is needed, or discovery, authentication, invocation, or feedback handling fails. It is not a required preflight for a known read-only call.

## Target configuration

Expand All @@ -19,6 +19,8 @@ tb login --base-url https://gateway.example.com
tb whoami --json
```

Within one continuous task, reuse a successful `whoami` result while the selected profile/BaseURL and identity remain unchanged. Do not run it before every call.

Install the CLI only with user approval:

```sh
Expand All @@ -42,6 +44,14 @@ tb help '<path>' --json

`tb search` may be absent on gateways without a search capability. Fall back to `tree`, `ls`, and `help` rather than treating that as a gateway-wide failure.

If an exact command path, current schema, `effect: read`, and `confirm: false` are already known from the current runtime, skip discovery and call it directly. Otherwise prefer one `search --json`; when a single hit is unambiguous and contains enough schema/effect/confirm data, call it without an extra help request.

`tb search '<query>' --json` already includes each result's arguments schema at `items[].tool.inputSchema`. For human-readable output, add `--schemas` to print those same schemas inline without another request. Use command-level help when search does not expose a detail needed for the decision, the result is ambiguous, or the operation is mutating:

```sh
tb help '<node>/<command>' --json
```

Node-level help is an index; it lists the commands under a node. Request `<node>/<command>` help to obtain a single command's complete input schema. Important command fields are:

- `path`: the full command path, used verbatim as the call target
Expand All @@ -64,19 +74,55 @@ tb call 'docs/search/query' --args '{"q":"tool bridge"}' --json
tb call 'system/status/get' --json
```

Take the path from `cmds[].path` exactly; do not assemble it from the node kind or invent a command name. Identifiers in a path (each segment and the command name) are case-insensitive and normalized to lowercase.
Take the full path from command help's `cmds[].path`, or from a search result as the exact `<items[].path>/<items[].tool.name>` pair. Use only fields returned by the gateway; do not infer a path from the node kind or invent a command name. Identifiers in a path (each segment and the command name) are case-insensitive and normalized to lowercase.

Arguments must be a JSON object. Inline JSON, `--args`, and `--args-file` are mutually exclusive. Prefer `--args-file` for long payloads:
Arguments must form a JSON object. Choose exactly one of four mutually exclusive input forms; omitting all four sends `{}`:

```sh
tb call '<path>' '{"query":"tool bridge"}' --json
tb call '<path>' --args '{"query":"tool bridge"}' --json
tb call '<path>' --args-file '<temporary-json-file>' --json
tb call '<path>' --arg query='tool bridge' --arg limit=10 --json
```

The first form is positional JSON after `<path>`. `--args` supplies the same object as a flag. `--args-file -` reads the entire JSON object from stdin:

```sh
printf '%s\n' '{"query":"tool bridge"}' | tb call '<path>' --args-file - --json
```

Repeated `--arg key=value` builds a flat object. It parses only `true`/`false` as booleans, `null` as null, and plain integers or decimals such as `42`, `-1`, and `1.5` as numbers; every other value remains a string. A repeated key uses its last value. Use positional JSON, `--args`, or `--args-file` for nested objects and arrays, exponent or hexadecimal notation, large integers, or strings that must remain exactly `"true"` or `"42"`.

Prefer `--args-file` for long payloads. Keep sensitive temporary files outside the project and remove them when no longer needed.

Do not reuse a failed write or destructive call automatically. A timeout can leave the remote outcome unknown.

## Context writes and uploads

Use `tb ctx put` for text or JSON that can be sent inline, from a UTF-8 file, or through stdin. It creates or replaces an entry and supports metadata and optimistic concurrency:

```sh
tb ctx put '<context>' '<entry>' --content '<text>' --json
tb ctx put '<context>' '<entry>' --file '<utf8-file>' --content-type application/json --json
```

Use direct upload for binary or large file content:

```sh
tb ctx upload '<context>' '<entry>' --file '<local>' --json
```

Upload is conditional by default: an existing entry fails with `conflict`. Add `--force` only when the user has explicitly authorized replacing that exact entry. The CLI obtains a short-lived upload grant and sends the bytes directly to object storage without the Tool Bridge key. Treat the grant URL and headers as temporary bearer secrets: do not print, log, store, cache, or include them in generated artifacts or feedback.

## Error handling

Tool Bridge errors use `{code,message,retryable}`. Common meanings:
Gateway TBError responses use `{code,message,retryable}` internally. With `--json`, the CLI emits a flat failure object to stdout and exits with status 1:

```json
{"ok":false,"error":"failure message","code":"invalid_argument","retryable":false}
```

`error` is the message string, not a nested error object. `code`, `retryable`, `hint`, and `feedback` are omitted when unavailable. Common codes mean:

- `not_found`: the path is absent or intentionally hidden from this identity
- `permission_denied`: the visible operation lacks a required scope
Expand All @@ -86,22 +132,23 @@ Tool Bridge errors use `{code,message,retryable}`. Common meanings:
- `rate_limited`: retry only when safe, using bounded backoff
- `internal`: report the failure without exposing request secrets

The CLI may attach known feedback to failed calls. Treat that hint as the first troubleshooting branch and read the referenced item before changing the request:
When `tb call` fails with `unavailable`, `internal`, `invalid_argument`, or `rate_limited`, the CLI makes a best-effort lookup on that exact path. It may add a human-readable `hint`; when matching entries exist, JSON output also includes at most three `feedback` summaries shaped as `{id,score,title}`. This lookup can fail silently and never replaces the primary error. Treat an attached entry as the first troubleshooting branch and fetch only the most relevant detail:

```sh
tb feedback ls '<path>' --json
tb feedback get '<path>' '<feedback-id>' --json
```

If a listed entry accurately explains the behavior or provides a validated workaround, vote it up promptly instead of submitting a duplicate:
Use `tb feedback ls '<path>' --json` only when the failed call did not attach a useful entry, the path is unfamiliar or failure-prone and warrants a preflight, or a new submission needs deduplication. Do not add feedback requests to every successful read call.

If a listed entry accurately explains the behavior or provides a validated workaround, it can be voted up after the requested result is secured, provided gateway writes are already authorized:

```sh
tb feedback vote '<path>' '<feedback-id>' up --json
```

Use `down` only when current runtime evidence shows that an entry is incorrect or harmful. Do not downvote merely because an entry was irrelevant to the current task.

When an abnormal call reveals a new reproducible issue or a validated resolution, submit feedback at the point of learning rather than waiting until the end of the task:
When an abnormal call reveals a new reproducible issue or a validated resolution, submit feedback after securing the requested result when gateway writes are already authorized and the lesson is genuinely reusable:

```sh
tb feedback submit '<path>' \
Expand All @@ -118,4 +165,4 @@ Before submitting:
4. Label an unresolved report as unresolved; do not present a guess as a fix.
5. Remove credentials, personal data, customer payloads, and internal-only URLs.

Feedback submission and voting require `call` permission on the target path. If the current task does not authorize gateway writes, draft the exact entry or vote and ask once for confirmation immediately. If permission is missing, report that fact and preserve the draft for an authorized user.
Feedback submission and voting require `call` permission on the target path. If the current task does not authorize gateway writes, do not interrupt a successful result merely to request a vote or submission. Preserve or mention a draft only when it would materially help the user or an authorized operator.
Loading