Skill: jolestar/uxc (version 1.0.4)

--- name: uxc description: Discover and call remote schema-exposed interfaces with UXC. Use when an agent or skill needs to list operations, inspect operation schemas, and execute OpenAPI, GraphQL, gRPC, MCP, or JSON-RPC calls via one CLI contract. metadata: short-description: Discover and call remote schema APIs via UXC --- # UXC Skill Use this skill when a task requires calling a remote interface and the endpoint can expose machine-readable schema metadata. ## When To Use - You need to call APIs/tools from another skill and want one consistent CLI workflow. - The interface may be OpenAPI, GraphQL, gRPC reflection, MCP, or JSON-RPC/OpenRPC. - You need deterministic, machine-readable output (`ok`, `kind`, `data`, `error`). Do not use this skill for pure local file operations with no remote interface. ## Prerequisites - `uxc` is installed and available in `PATH`. - For gRPC runtime calls, `grpcurl` is installed and available in `PATH`. ### Install uxc Choose one of the following methods: **Homebrew (macOS/Linux):** ```bash brew tap holon-run/homebrew-tap brew install uxc ``` **Install Script (macOS/Linux, review before running):** ```bash curl -fsSL https://raw.githubusercontent.com/holon-run/uxc/main/scripts/install.sh -o install-uxc.sh # Review the script before running it less install-uxc.sh bash install-uxc.sh ``` **Cargo:** ```bash cargo install uxc ``` For more options, see the [Installation](https://github.com/holon-run/uxc#installation) section in the UXC README. ## Core Workflow 1. Discover operations: - `uxc <host> -h` 2. Inspect a specific operation: - `uxc <host> <operation> -h` 3. Execute with structured input: - `uxc <host> <operation> key=value` - `uxc <host> <operation> '<payload-json>'` 4. Parse result as JSON envelope: - Success: `.ok == true`, consume `.data` - Failure: `.ok == false`, inspect `.error.code` and `.error.message` 5. For disambiguation, use operation-level help first: - `uxc <host> <operation> -h` 6. For auth-protected endpoints, use the right auth track: - simple bearer / single-secret API key: see `references/auth-configuration.md` - multi-field auth or request signing: see `references/auth-configuration.md` - OAuth flows: see `references/oauth-and-binding.md` ## Link-First Workflow For Wrapper Skills Wrapper skills should default to a fixed local link command instead of calling `uxc <host> ...` directly on every step. 1. Pick a fixed command name during skill development: - naming convention: `<provider>-mcp-cli` - examples: `notion-mcp-cli`, `context7-mcp-cli`, `deepwiki-mcp-cli` 2. Check whether the command already exists: - `command -v <link_name>` 3. If command is missing, create it: - `uxc link <link_name> <host>` - For OpenAPI services whose schema is hosted at a separate fixed URL, create the link with `uxc link <link_name> <host> --schema-url <schema_url>` - For stdio hosts that need credential-driven child env auth, create the link with `uxc link <link_name> <host> --credential <credential_id> --inject-env NAME={{secret}}` 4. Validate link command: - `<link_name> -h` 5. Use only the link command for the rest of the skill flow. ### Naming Governance - Link naming is a skill author decision, not a runtime agent decision. - Resolve ecosystem conflicts during skill development/review. - Do not implement dynamic rename logic inside runtime skill flow. - If runtime detects a command conflict that cannot be safely reused, stop and ask for skill maintainer intervention. ### Equivalence Rule - `<link_name> <operation> ...` is equivalent to `uxc <host> <operation> ...`. - If the link was created with `--schema-url <schema_url>`, it is equivalent to `uxc <host> --schema-url <schema_url> <operation> ...`. - If the link was created with `--credential <credential_id> --inject-env NAME={{secret}}`, it is equivalent to `uxc --auth <credential_id> --inject-env NAME={{secret}} <host> <operation> ...`. - Callers can still override that persisted schema by passing `--schema-url <other_url>` explicitly at runtime. - Use `uxc <host> ...` only as a temporary fallback when link setup is unavailable. ## Input Modes - Preferred (simple payload): key/value - `uxc <host> <operation> field=value` - Bare JSON positional: - `uxc <host> <operation> '{"field":"value"}'` Do not pass raw JSON through `--args`; use positional JSON. ## Output Contract For Reuse Other skills should treat this skill as the interface execution layer and consume only the stable envelope: - Success fields: `ok`, `kind`, `protocol`, `endpoint`, `operation`, `data`, `meta` - Failure fields: `ok`, `error.code`, `error.message`, `meta` Default output is JSON. Do not use `--text` in agent automation paths. ## Reuse Rule For Other Skills - If a skill needs remote API/tool execution, reuse this skill instead of embedding protocol-specific calling logic. - Wrapper skills should adopt a fixed link command (`<provider>-mcp-cli`) as the default invocation path. - Upstream skill inputs should be limited to: - target host - operation id/name - JSON payload - required fields to extract from `.data` ## Reference Files (Load On Demand) - Workflow details and progressive invocation patterns: - `references/usage-patterns.md` - Protocol operation naming quick reference: - `references/protocol-cheatsheet.md` - Public endpoint examples and availability notes: - `references/public-endpoints.md` - Authentication configuration (simple `secret`, named `fields`, headers/query params, and request signers): - `references/auth-configuration.md` - OAuth and credential/binding lifecycle: - `references/oauth-and-binding.md` - Failure handling and retry strategy: - `references/error-handling.md`

path: agents/openai.yaml
content: interface:
  display_name: "UXC"
  short_description: "Discover and call remote schema APIs via UXC"
  default_prompt: "Use $uxc to discover operations and call remote interfaces with the UXC CLI."


path: references/auth-configuration.md
content: # Authentication Configuration Guide

Use this guide for non-OAuth authentication. The model now has two tracks:

- simple auth: one primary `secret`
- complex auth: multiple named `fields`

Bindings can optionally attach a typed signer for APIs that require request signing.

## The Two Tracks

### Track 1: Simple `secret`

Keep using `--secret`, `--secret-env`, or `--secret-op` when the provider only needs one secret value.

Good fits:

- bearer tokens
- one API key header
- one API key query param
- stdio `--inject-env NAME={{secret}}`

Examples:

```bash
uxc auth credential set deepwiki \
  --auth-type bearer \
  --secret-env DEEPWIKI_TOKEN

uxc auth credential set okx-market \
  --auth-type api_key \
  --secret-env OKX_ACCESS_KEY \
  --api-key-header OK-ACCESS-KEY

uxc auth credential set flipside \
  --auth-type api_key \
  --query-param "[REDACTED_SECRET]" \
  --secret-env FLIPSIDE_API_KEY
```

### Track 2: Named `fields`

Use `--field` when one credential needs multiple values.

Good fits:

- `api_key + secret_key`
- `api_key + private_key`
- `api_key + passphrase`
- multiple headers that should draw from different values
- signer-backed APIs

Example:

```bash
uxc auth credential set exchange \
  --auth-type api_key \
  --field [REDACTED_SECRET] \
  --field secret_key=env:EXCHANGE_SECRET_KEY
```

## Credential Sources And Templates

### Primary secret sources

`--secret`, `--secret-env`, and `--secret-op` are mutually exclusive.

- literal:
  ```bash
  --secret "actual_secret_value"
  ```
- env:
  ```bash
  --secret-env CREDENTIAL_NAME
  ```
- 1Password:
  ```bash
  --secret-op "op://Vault/item/field"
  ```

### Named field sources

`--field` is repeatable. Each field uses an explicit source form:

```bash
--field [REDACTED_SECRET]
--field [REDACTED_SECRET]
--field private_key=op://Trading/binance/private_key
```

`--field` is not supported for OAuth credentials.

### Template syntax

- `{{secret}}`: primary secret source
- `{{field:<name>}}`: named field on the credential
- `{{env:VAR_NAME}}`: direct environment variable lookup
- `{{op://...}}`: direct 1Password lookup

Examples:

```bash
uxc auth credential set linear \
  --auth-type api_key \
  --header "Authorization:{{secret}}" \
  --secret-env LINEAR_API_KEY

uxc auth credential set complex-api \
  --auth-type api_key \
  --field [REDACTED_SECRET] \
  --field api_secret=env:API_SECRET \
  --header "X-[REDACTED_SECRET]" \
  --header "X-API-[REDACTED_SECRET]"
```

## Common Credential Patterns

### Bearer token

```bash
uxc auth credential set myapi \
  --auth-type bearer \
  --secret-env MYAPI_TOKEN
```

### Raw token in `Authorization`

Use this when the provider rejects `Bearer ` prefix:

```bash
uxc auth credential set linear \
  --auth-type api_key \
  --header "Authorization:{{secret}}" \
  --secret-env LINEAR_API_KEY
```

### API key in one custom header

```bash
uxc auth credential set custom-api \
  --auth-type api_key \
  --header "X-[REDACTED_SECRET]" \
  --secret-env CUSTOM_API_KEY
```

### Multiple headers from different values

```bash
uxc auth credential set okx-advanced \
  --auth-type api_key \
  --field access_key=env:OKX_ACCESS_KEY \
  --field passphrase=env:OKX_PASSPHRASE \
  --header "OK-ACCESS-KEY:{{field:access_key}}" \
  --header "OK-ACCESS-PASSPHRASE:{{field:passphrase}}"
```

### Query-string API key

```bash
uxc auth credential set flipside \
  --auth-type api_key \
  --query-param "[REDACTED_SECRET]" \
  --secret-env FLIPSIDE_API_KEY
```

## Bindings

Credentials do nothing until they are bound to endpoint patterns:

```bash
uxc auth binding add \
  --id <binding_id> \
  --host <api_host> \
  --path-prefix <path_prefix> \
  --scheme https \
  --credential <credential_id> \
  --priority 100
```

Resolution order:

1. explicit `--auth <credential_id>`
2. best binding match by `scheme + host + path_prefix + priority`
3. first match wins if all else is equal

Check the effective match:

```bash
uxc auth binding match <endpoint>
```

## Request Signers

Some HTTP APIs need more than static headers. In those cases:

- store values on the credential as `fields`
- attach the signer on the binding with `--signer-json`

Current typed signer kinds:

- `hmac_query_v1`
- `ed25519_query_v1`

### HMAC signed query example

```bash
uxc auth credential set binance-hmac \
  --auth-type api_key \
  --field [REDACTED_SECRET] \
  --field secret_key=env:BINANCE_SECRET_KEY

uxc auth binding add \
  --id binance-hmac \
  --host api.binance.com \
  --path-prefix /api/v3 \
  --scheme https \
  --credential binance-hmac \
  --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \
  --priority 100
```

### Ed25519 signed query example

```bash
uxc auth credential set binance-ed25519 \
  --auth-type api_key \
  --field [REDACTED_SECRET] \
  --field private_key=env:BINANCE_ED25519_PRIVATE_KEY

uxc auth binding add \
  --id binance-ed25519 \
  --host api.binance.com \
  --path-prefix /api/v3 \
  --scheme https \
  --credential binance-ed25519 \
  --signer-json '{"kind":"ed25519_query_v1","algorithm":"ed25519","signing_field":"private_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"base64","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \
  --priority 100
```

## Troubleshooting

### Error: "Bearer token" prefix rejected

Cause: using `--auth-type bearer` when the provider expects a raw token in `Authorization`.

Use:

```bash
uxc auth credential set myapi \
  --auth-type api_key \
  --header "Authorization:{{secret}}" \
  --secret "token"
```

### Error: Credential not found

```bash
uxc auth credential list
```

### Error: No binding matched

```bash
uxc auth binding list
uxc auth binding match <endpoint>
```

### Error: Environment variable not set

If the credential uses env-backed `secret` or `fields`, export the variable and restart daemon:

```bash
export MY_API_KEY="value"
uxc daemon restart
```

### Error: `-1022` or provider-specific invalid signature

Check all three:

1. the binding matched the intended path
2. the `API key` and signing material come from the same provider key record
3. the signer kind matches the provider contract

Useful checks:

```bash
uxc auth credential info <credential_id>
uxc auth binding match <endpoint>
```

### Error: 1Password CLI not found

Install `op`, ensure it is on the daemon's `PATH`, and authenticate before runtime use.

## Verification Steps

After configuring auth:

1. inspect the credential
   ```bash
   uxc auth credential info <credential_id>
   ```
2. inspect binding match
   ```bash
   uxc auth binding match <endpoint>
   ```
3. test a read operation first
   ```bash
   uxc <endpoint> <read_operation>
   ```
4. optionally force the credential explicitly
   ```bash
   uxc --auth <credential_id> <endpoint> <read_operation>
   ```

## Best Practices

1. Keep `--secret` for single-secret auth. Do not force everything into `fields`.
2. Use `fields` for multi-value credentials and signer-backed APIs.
3. Attach signers to bindings, not to endpoint URLs or shell wrappers.
4. Prefer environment variables or 1Password over literal values.
5. Test with reads before writes.
6. Restart daemon after environment changes.

## See Also

- OAuth flow: `oauth-and-binding.md`
- Error handling: `error-handling.md`
- Usage patterns: `usage-patterns.md`


path: references/error-handling.md
content: # Error Handling

## Envelope-First Handling

Always parse `ok` first.

- `ok=true`: consume `data`
- `ok=false`: branch by `error.code`

## Common Failure Classes

1. Discovery failure
- Symptoms: `list` fails, protocol not detected, endpoint mismatch
- Actions:
  - verify host URL/scheme/port
  - run with `RUST_LOG=debug`
  - for OpenAPI schema separation, provide `--schema-url` or mapping if needed

2. Operation not found
- Symptoms: operation help or runtime call reports unknown operation
- Actions:
  - refresh with `-h` on endpoint
  - check exact operation naming convention per protocol

3. Input validation failure
- Symptoms: invalid argument / missing field
- Actions:
  - inspect operation schema via `<operation> -h`
  - start from minimal required payload
  - prefer `key=value` or bare positional JSON for primary calls

4. Runtime transport failure
- Symptoms: timeout, connection reset, TLS error
- Actions:
  - retry with bounded attempts
  - verify endpoint health with native tooling (`curl`, `grpcurl`)

5. OAuth authentication failure
- Symptoms: `OAUTH_REQUIRED`, `OAUTH_REFRESH_FAILED`, `401 invalid_token`
- Actions:
  - verify binding with `uxc auth binding match <endpoint>`
  - inspect credential with `uxc auth oauth info <credential_id>`
  - run `uxc auth oauth refresh <credential_id>`
  - if refresh fails, run login again

6. OAuth scope failure
- Symptoms: `OAUTH_SCOPE_INSUFFICIENT`, HTTP `403`
- Actions:
  - login again with broader scopes
  - confirm provider/workspace policy grants requested scopes

## OAuth Code Playbooks

`OAUTH_REQUIRED`:
1. verify endpoint/credential mapping with binding match
2. login with the expected credential
3. retry original read operation

`OAUTH_DISCOVERY_FAILED`:
1. check endpoint and network reachability
2. retry login
3. if needed, use explicit provider metadata flags supported by CLI

`OAUTH_TOKEN_EXCHANGE_FAILED`:
1. ensure callback URL/code is complete and unmodified
2. restart login flow

`OAUTH_REFRESH_FAILED`:
1. retry refresh once manually
2. if still failing, re-login (refresh token may be revoked/expired)

`OAUTH_SCOPE_INSUFFICIENT`:
1. login with required scopes
2. rerun original operation

## MCP Probe Note

- For MCP HTTP endpoints, `uxc` may refresh OAuth during protocol probe when probe receives `401`.
- If refresh still fails, expect OAuth-related errors instead of a generic protocol mismatch.

## Retry Guidance

- Retry only idempotent read-like operations by default.
- Suggested backoff: 1s, 2s, 4s (max 3 attempts).
- Do not retry validation errors without payload change.


path: references/oauth-and-binding.md
content: # OAuth And Binding

Use this guide for OAuth-backed endpoints across protocols and providers.

## Credential And Binding Model

- Credential stores auth material (`oauth`, bearer, api key).
- Binding maps endpoint patterns to credential IDs.
- Runtime resolution order:
  1. explicit `--auth <credential_id>`
  2. binding match by `scheme + host + path_prefix + priority`

## Setup Flow

1. Login. Prefer the two-step flow for agents and any multi-turn workflow:

```bash
uxc auth oauth start <credential_id> \
  --endpoint <endpoint> \
  --redirect-uri <callback_uri>
```

After the user finishes browser authorization:

```bash
uxc auth oauth complete <credential_id> \
  --session-id <session_id> \
  --authorization-response '<callback_url_or_code>'
```

Single-process interactive fallback:

```bash
uxc auth oauth login <credential_id> \
  --endpoint <endpoint> \
  --flow authorization_code
```

2. Bind endpoint to credential:

```bash
uxc auth binding add \
  --id <binding_id> \
  --host <host> \
  --path-prefix <path_prefix> \
  --scheme <scheme> \
  --credential <credential_id> \
  --priority 100
```

3. Verify binding:

```bash
uxc auth binding match <endpoint>
```

`<endpoint>` accepts either:
- shorthand host/path like `mcp.notion.com/mcp`
- full URL like `https://mcp.notion.com/mcp`

## Validation Strategy

- Prefer local precheck with `binding match`.
- Do not add redundant preflight read calls by default.
- Use first real read operation as runtime validation.

## Auto Refresh Behavior

For OAuth credentials, `uxc` may refresh automatically:

1. before request when token is near expiry
2. after a `401` retry path in runtime calls
3. during MCP HTTP probe when endpoint returns `401` and OAuth profile is available

If refresh succeeds, call continues with new token.

## Manual Recovery Commands

```bash
uxc auth oauth info <credential_id>
uxc auth oauth refresh <credential_id>
uxc auth oauth logout <credential_id>
```

Use manual `refresh` when troubleshooting or when auto-refresh cannot recover.

## Multi-Binding Troubleshooting

If auth failures persist:

1. list bindings:
   - `uxc auth binding list`
2. confirm current default match:
   - `uxc auth binding match <endpoint>`
3. verify candidate credentials explicitly:
   - `uxc --auth <credential_id> <endpoint> <same_read_operation> ...`
4. remove only bindings confirmed stale/invalid.

## Common Error Codes

- `OAUTH_REQUIRED`
- `OAUTH_DISCOVERY_FAILED`
- `OAUTH_SESSION_NOT_FOUND`
- `OAUTH_SESSION_EXPIRED`
- `OAUTH_TOKEN_EXCHANGE_FAILED`
- `OAUTH_REFRESH_FAILED`
- `OAUTH_SCOPE_INSUFFICIENT`

See `references/error-handling.md` for full recovery playbooks.


path: references/protocol-cheatsheet.md
content: # Protocol Cheatsheet

UXC operation names follow protocol-native conventions.

## OpenAPI

- Operation id format: `method:/path`
- Example:
  - `get:/users/{id}`
  - `post:/pet`

## gRPC

- Operation id format: `Service/Method`
- Example:
  - `addsvc.Add/Sum`

## GraphQL

- Operation id format: `<operation_type>/<field>`
- Example:
  - `query/viewer`
  - `mutation/addStar`
  - `subscription/onEvent`

## MCP

- Operation id format: tool name
- Example:
  - `ask_question`
  - `list_directory`

## JSON-RPC (OpenRPC-driven)

- Operation id format: method name
- Example:
  - `eth_getBalance`
  - `net_version`

## Generic Command Templates

```bash
uxc <host> -h
uxc <host> <operation> -h
uxc <host> <operation> field=value
uxc <host> <operation> '{"field":"value"}'
```


path: references/public-endpoints.md
content: # Public Endpoints

The following endpoints are practical no-key baselines for smoke checks. Availability can change over time.

## OpenAPI

- Endpoint: `petstore3.swagger.io/api/v3`
- Check:

```bash
uxc petstore3.swagger.io/api/v3 -h
uxc petstore3.swagger.io/api/v3 get:/store/inventory
```

## GraphQL

- Endpoint: `countries.trevorblades.com`
- Check:

```bash
uxc countries.trevorblades.com -h
uxc countries.trevorblades.com query/country code=US
```

## gRPC

- Endpoint: `grpcb.in:9000` (plaintext), `grpcb.in:9001` (TLS)
- Prerequisite: `grpcurl` installed
- Check:

```bash
uxc grpcb.in:9000 -h
uxc grpcb.in:9000 addsvc.Add/Sum a=1 b=2
```

## MCP (HTTP)

- Endpoint: `mcp.deepwiki.com/mcp`
- Check:

```bash
uxc mcp.deepwiki.com/mcp -h
uxc mcp.deepwiki.com/mcp ask_question -h
```

## JSON-RPC

- Constraint: UXC JSON-RPC discovery requires `openrpc.json`, `/.well-known/openrpc.json`, or `rpc.discover`.
- Current status: no stable, keyless public endpoint is curated in this repository.
- Recommended baseline for reliable tests:
  - use a controlled endpoint that exposes OpenRPC/rpc.discover
  - or run local/self-hosted JSON-RPC with OpenRPC enabled


path: references/usage-patterns.md
content: # Usage Patterns

## Progressive Flow (Default)

1. Discover operations:

```bash
uxc <host> -h
```

2. Inspect operation input/output shape:

```bash
uxc <host> <operation> -h
```

3. Execute with minimal valid payload:

```bash
uxc <host> <operation> field=value
```

4. Parse success/failure envelope:

```bash
uxc <host> <operation> field=value | jq '.ok, .kind, .data'
```

## Wrapper Pattern (Link-First)

For provider-specific wrapper skills, use a fixed local link command as the default interface:

```bash
command -v <provider>-mcp-cli
# If missing:
uxc link <provider>-mcp-cli <host>
<provider>-mcp-cli -h
<provider>-mcp-cli <operation> -h
<provider>-mcp-cli <operation> field=value
```

For OpenAPI services whose runtime URL and schema URL differ, persist the schema on the link itself:

```bash
uxc link <provider>-openapi-cli <host> --schema-url <schema_url>
<provider>-openapi-cli -h
```

For stdio hosts that expect credentials in child-process env vars, persist credential selection and env injection on the link:

```bash
uxc auth credential set <credential_id> --secret-env <ENV_NAME>
uxc link <provider>-mcp-cli <stdio_command> --credential <credential_id> --inject-env <ENV_NAME>={{secret}}
<provider>-mcp-cli -h
```

For MCP HTTP or other HTTP endpoints that require API keys in the URL query string, configure the credential with `--query-param` and keep the endpoint itself clean:

```bash
uxc auth credential set flipside --auth-type api_key --query-param "[REDACTED_SECRET]" --secret-env FLIPSIDE_API_KEY
uxc auth binding add --id flipside-mcp --host mcp.flipsidecrypto.xyz --path-prefix /mcp --scheme https --credential flipside --priority 100
uxc https://mcp.flipsidecrypto.xyz/mcp -h
```

For multi-part auth, keep one credential and store extra values as named `fields`:

```bash
uxc auth credential set exchange \
  --auth-type api_key \
  --field [REDACTED_SECRET] \
  --field secret_key=env:EXCHANGE_SECRET_KEY
```

For signed HTTP APIs, attach the signer to the binding instead of hardcoding signing into the endpoint URL:

```bash
uxc auth binding add \
  --id exchange-signed \
  --host api.example.com \
  --path-prefix /v1 \
  --scheme https \
  --credential exchange \
  --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-API-KEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \
  --priority 100
```

Examples:

```bash
notion-mcp-cli -h
# Equivalent:
uxc mcp.notion.com/mcp -h
```

```bash
context7-mcp-cli query-docs libraryId=/reactjs/react.dev query=useState
# Equivalent:
uxc mcp.context7.com/mcp query-docs libraryId=/reactjs/react.dev query=useState
```

```bash
discord-openapi-cli get:/gateway
# Equivalent if the link was created with --schema-url:
uxc https://discord.com/api/v10 --schema-url <discord_openapi_spec> get:/gateway
```

### Conflict Handling For Wrapper Skills

- Fixed link command names are decided by skill authors at development time.
- Do not dynamically rename link commands at runtime.
- If a conflicting command name exists and cannot be safely reused, stop and ask a maintainer to update the skill's fixed command name.

## Input Modes

### Bare JSON positional payload

```bash
uxc <host> <operation> '{"field":"value"}'
```

### Key-value arguments

```bash
uxc <host> <operation> field=value
```

Do not pass raw JSON via `--args`; use bare JSON positional payload instead.

## Host-Level Help

```bash
uxc <host> -h
```

Use this when you need quick discovery context before choosing an operation.

## Auth-Protected Flow

1. Confirm mapping:

```bash
uxc auth binding match <endpoint>
```

For signer-backed HTTP auth, also inspect the credential and binding shape before the first live call:

```bash
uxc auth credential info <credential_id>
uxc auth binding list
```

2. Run intended read call directly (use as runtime validation).

3. If auth fails, recover in order:

```bash
uxc auth oauth info <credential_id>
uxc auth oauth refresh <credential_id>
uxc auth oauth start <credential_id> --endpoint <endpoint> --redirect-uri <callback_uri>
uxc auth oauth complete <credential_id> --session-id <session_id> --authorization-response '<callback_url_or_code>'
```

Use `uxc auth oauth login <credential_id> --endpoint <endpoint> --flow authorization_code` only when one interactive process can wait for the callback input.

4. If multiple bindings match, verify explicit credential:

```bash
uxc --auth <credential_id> <endpoint> <operation> '{...}'
```

## Automation Safety Rules

- Keep JSON as default output for machine parsing.
- Treat stderr logs as diagnostic only; parse stdout JSON envelope.
- Start with smallest valid payload before expanding optional fields.


path: scripts/validate.sh
content: #!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
SKILL_DIR="${ROOT_DIR}/skills/uxc"
SKILL_FILE="${SKILL_DIR}/SKILL.md"
OPENAI_FILE="${SKILL_DIR}/agents/openai.yaml"

fail() {
  printf '[validate] error: %s\n' "$*" >&2
  exit 1
}

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || fail "required command not found: $1"
}

# Check dependencies
need_cmd rg

required_files=(
  "${SKILL_FILE}"
  "${OPENAI_FILE}"
  "${SKILL_DIR}/references/usage-patterns.md"
  "${SKILL_DIR}/references/protocol-cheatsheet.md"
  "${SKILL_DIR}/references/public-endpoints.md"
  "${SKILL_DIR}/references/oauth-and-binding.md"
  "${SKILL_DIR}/references/error-handling.md"
)

for file in "${required_files[@]}"; do
  if [[ ! -f "${file}" ]]; then
    fail "missing required file: ${file}"
  fi
done

# Validate SKILL frontmatter minimum fields.
# Require the first line to be '---' and a subsequent closing '---'.
if ! head -n 1 "${SKILL_FILE}" | rg -q '^---$'; then
  fail "SKILL.md must include YAML frontmatter"
fi

if ! tail -n +2 "${SKILL_FILE}" | rg -q '^---$'; then
  fail "SKILL.md must include YAML frontmatter"
fi

if ! rg -q '^name:\s*uxc\s*$' "${SKILL_FILE}"; then
  fail "SKILL.md frontmatter must define: name: uxc"
fi

if ! rg -q '^description:\s*.+' "${SKILL_FILE}"; then
  fail "SKILL.md frontmatter must define a description"
fi

# Validate required invocation contract appears in SKILL text.
if ! rg -q 'uxc <host> -h' "${SKILL_FILE}"; then
  fail "SKILL.md must document help-first discovery workflow"
fi

if ! rg -q 'uxc <host> <operation> -h' "${SKILL_FILE}"; then
  fail "SKILL.md must document operation-level help workflow"
fi

if ! rg -q "uxc <host> <operation> key=value" "${SKILL_FILE}"; then
  fail "SKILL.md must document execute workflow"
fi

if ! rg -q "uxc <host> <operation> '<payload-json>'" "${SKILL_FILE}"; then
  fail "SKILL.md must document bare JSON execute workflow"
fi

if rg -q -- 'uxc <host> describe <operation>|uxc <host> call <operation>|--input-json' "${SKILL_FILE}" "${SKILL_DIR}/references/"*.md; then
  fail "uxc skill docs must not use describe/call/--input-json in default examples"
fi

if ! rg -q 'Link-First Workflow For Wrapper Skills' "${SKILL_FILE}"; then
  fail "SKILL.md must include Link-First workflow guidance for wrapper skills"
fi

if ! rg -q 'naming convention: `<provider>-mcp-cli`' "${SKILL_FILE}"; then
  fail "SKILL.md must define fixed wrapper link naming convention"
fi

if ! rg -q 'command -v <link_name>' "${SKILL_FILE}"; then
  fail "SKILL.md must include link existence check pattern"
fi

if ! rg -q '`<link_name> <operation> ...` is equivalent to `uxc <host> <operation> ...`' "${SKILL_FILE}"; then
  fail "SKILL.md must include link/uxc equivalence rule"
fi

if rg -q "execute notion" "${SKILL_FILE}"; then
  fail "SKILL.md must not document execute-form invocations"
fi

if rg -q -- "--args '\\{" "${SKILL_FILE}" "${SKILL_DIR}/references/"*.md; then
  fail "uxc docs must not pass raw JSON via --args"
fi

# Validate references linked from SKILL body.
for rel in \
  "references/usage-patterns.md" \
  "references/protocol-cheatsheet.md" \
  "references/public-endpoints.md" \
  "references/oauth-and-binding.md" \
  "references/error-handling.md"; do
  if ! rg -q "${rel}" "${SKILL_FILE}"; then
    fail "SKILL.md must reference ${rel}"
  fi
done

if ! rg -q -F 'Wrapper Pattern (Link-First)' "${SKILL_DIR}/references/usage-patterns.md"; then
  fail "uxc usage-patterns must include wrapper link-first pattern"
fi

if ! rg -q 'Do not dynamically rename link commands at runtime' "${SKILL_DIR}/references/usage-patterns.md"; then
  fail "uxc usage-patterns must forbid dynamic link renaming at runtime"
fi

# Validate openai.yaml minimum fields.
if ! rg -q '^\s*display_name:\s*"UXC"\s*$' "${OPENAI_FILE}"; then
  fail "agents/openai.yaml must define interface.display_name"
fi

if ! rg -q '^\s*short_description:\s*".+"\s*$' "${OPENAI_FILE}"; then
  fail "agents/openai.yaml must define interface.short_description"
fi

if ! rg -q '^\s*default_prompt:\s*".*\$uxc.*"\s*$' "${OPENAI_FILE}"; then
  fail 'agents/openai.yaml default_prompt must mention $uxc'
fi

echo "skills/uxc validation passed"


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)