Files
optimclaw/tools-src/slack
3fdb187796 refactor(tools): auto-compact WASM tool schemas, add descriptions, improve credential prompts (#1525)
* fix(tools): add missing description, parameters, and improve credential prompts

Silence three categories of startup warnings emitted by
CapabilitiesFile::validate() and WasmToolLoader:

1. "description" field missing → add tool descriptions to all manifests
2. "parameters" field missing → add action-enum parameter schemas
3. Short credential prompts (<30 chars) → append source URLs

Affects: github, gmail, google-calendar, google-docs, google-drive,
google-sheets, google-slides, slack, telegram, llm-context, feishu.

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* refactor(tools): auto-compact WASM tool schemas from module exports

Replace the manual `parameters` field in capabilities JSON with automatic
schema compaction. WasmToolSchemas::compact_schema() derives a compact
advertised schema from the WASM module's schema() export by keeping only
required and enum-constrained properties. The full schema remains
available via tool_info(detail: "schema").

This eliminates:
- The `parameters` field from CapabilitiesFile and all 11 sidecar JSONs
- The "missing parameters" startup warning from the loader
- Manual maintenance of duplicate schema data

The `description` field in capabilities JSON is retained.

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(tests): remove cap_file.parameters reference in test_rig

The parameters field was removed from CapabilitiesFile in the previous
commit. Update test_rig.rs to match — schema is now auto-compacted from
the WASM module export, no sidecar override needed.

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(tools): handle oneOf schemas in compact_schema, add tool name to warning

Address PR review feedback:
- compact_schema now collects properties from oneOf/anyOf/allOf variants,
  fixing GitHub-style schemas that have no top-level properties
- Use HashSet for required lookup instead of Vec::contains
- Add tool name to "Capabilities file not found" warning for consistency

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(tools): merge oneOf const values into enum, cap property collection

Address review feedback from @serrrfirat:

1. Merge const values across oneOf variants into a single enum array,
   so the LLM sees all valid actions (not just the first variant's const).
2. Cap property collection at 100 to bound allocations.
3. Also keep properties with const constraint (single-variant case).
4. Update doc comment to describe variant collection and design choices
   around variant-level required fields.

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-23 21:59:14 -07:00
..

Slack WASM Tool

A standalone WASM component that provides Slack integration for IronClaw. This serves as both a functional tool and a template for building custom WASM tools.

Features

  • send_message: Send messages to channels or threads
  • list_channels: List channels the bot has access to
  • get_channel_history: Retrieve recent messages from a channel
  • post_reaction: Add emoji reactions to messages
  • get_user_info: Get information about Slack users

Prerequisites

  1. Rust toolchain with WASM target:

    rustup target add wasm32-wasip2
    
  2. cargo-component for building WASM components:

    cargo install cargo-component
    
  3. Slack Bot Token with the following OAuth scopes:

    • chat:write - Send messages
    • channels:read - List public channels
    • channels:history - Read channel history
    • groups:read - List private channels
    • groups:history - Read private channel history
    • reactions:write - Add reactions
    • users:read - Get user information

Building

cd tools-src/slack
cargo component build --release

The compiled WASM component will be at:

target/wasm32-wasip2/release/slack_tool.wasm

Installation

Option A: File-based (Development)

Copy the WASM and capabilities files to the agent's tools directory:

mkdir -p ~/.ironclaw/tools
cp target/wasm32-wasip2/release/slack_tool.wasm ~/.ironclaw/tools/slack.wasm
cp slack.capabilities.json ~/.ironclaw/tools/

Option B: Database Storage (Production)

Use the agent CLI or API to store the tool:

ironclaw tool install \
  --name slack \
  --wasm target/wasm32-wasip2/release/slack_tool.wasm \
  --capabilities slack.capabilities.json

Configuration

Store your Slack bot token as a secret:

ironclaw secret set slack_bot_token "xoxb-your-token-here"

Or via SQL:

INSERT INTO secrets (user_id, name, encrypted_value, key_salt)
VALUES ('your_user_id', 'slack_bot_token', ...);

Usage Examples

Send a Message

{
  "action": "send_message",
  "channel": "#general",
  "text": "Hello from IronClaw!"
}

Reply in a Thread

{
  "action": "send_message",
  "channel": "C1234567890",
  "text": "This is a thread reply",
  "thread_ts": "1234567890.123456"
}

List Channels

{
  "action": "list_channels",
  "limit": 50
}

Get Channel History

{
  "action": "get_channel_history",
  "channel": "C1234567890",
  "limit": 10
}

Add a Reaction

{
  "action": "post_reaction",
  "channel": "C1234567890",
  "timestamp": "1234567890.123456",
  "emoji": "thumbsup"
}

Get User Info

{
  "action": "get_user_info",
  "user_id": "U1234567890"
}

Security Model

This tool runs in a sandboxed WASM environment with strict capability controls:

  1. HTTP Allowlist: Can only access slack.com/api/*
  2. Credential Injection: The bot token is injected by the host runtime; the WASM code never sees it
  3. Rate Limiting: 50 requests/minute, 1000 requests/hour
  4. No Filesystem Access: Cannot read/write files except through workspace capability
  5. No Network Access: Beyond the allowlisted endpoints

Capabilities File

The slack.capabilities.json file declares what this tool needs:

{
  "http": {
    "allowlist": [
      { "host": "slack.com", "path_prefix": "/api/", "methods": ["GET", "POST"] }
    ],
    "credentials": {
      "slack_bot_token": {
        "secret_name": "slack_bot_token",
        "location": { "type": "bearer" },
        "host_patterns": ["slack.com"]
      }
    },
    "rate_limit": { "requests_per_minute": 50, "requests_per_hour": 1000 }
  },
  "secrets": {
    "allowed_names": ["slack_bot_token"]
  }
}

Building Your Own Tool

Use this as a template for creating new WASM tools:

  1. Copy this directory
  2. Update Cargo.toml with your tool name
  3. Modify src/types.rs with your action types
  4. Implement API calls in src/api.rs
  5. Update the action dispatch in src/lib.rs
  6. Create your *.capabilities.json file
  7. Build with cargo component build --release

Key Files

  • Cargo.toml - Rust package config with WASM target
  • src/lib.rs - WIT bindings and main dispatch
  • src/types.rs - Request/response types
  • src/api.rs - API implementation
  • *.capabilities.json - Security capabilities declaration

WIT Interface

Tools implement the sandboxed-tool world from wit/tool.wit:

world sandboxed-tool {
    import host;   // log, http-request, secret-exists, etc.
    export tool;   // execute, schema, description
}

Troubleshooting

"Slack bot token not configured"

Ensure you've stored the secret:

ironclaw secret set slack_bot_token "xoxb-..."

"Endpoint not in allowlist"

Check that slack.capabilities.json includes the endpoint you're trying to access.

"Rate limit exceeded"

The tool has a default rate limit of 50 requests/minute. Wait and retry.

Build errors

Ensure you have the WASM target and cargo-component installed:

rustup target add wasm32-wasip2
cargo install cargo-component

License

MIT OR Apache-2.0