Add your tools to Captain

Captain tools live in the Replynivo/tools repository on GitHub. Add a folder with a manifest and a README, open a pull request, and the Replynivo team reviews it. Merged tools appear in this catalog.

  1. Fork Replynivo/tools and add a folder

    Add one folder at the repository root for the service you are connecting. Its name becomes the page URL, so keep it short and lowercase, like shopify. Each folder needs a toolset.yml and a README.md, and the README becomes the page people read here.

    Optional: add logo.png and logo-dark.png beside the manifest. SVG, WebP, and AVIF are also supported. Use one file per variant, up to 2 MiB and 4096 by 4096 pixels. Logos are converted to WebP.

    Replynivo/tools
    tools/
    ├── stripe/
    └── shopify/
        ├── README.md
        ├── toolset.yml
        ├── logo.png       (optional)
        └── logo-dark.png  (optional)
  2. Declare the tools

    The manifest is data, and nothing in it executes. It has three parts: the settings and credentials an account must supply, the HTTP requests Captain is allowed to make, and the placeholders that wire the two together.

    Set author to your GitHub username or organization, without the @. It must be an existing GitHub account, and the catalog shows it with its avatar.

    Set one category using the exact spelling: Commerce, Payments & billing, Shipping, CRM, Engineering & status, Scheduling, Business data & research, Identity & access, Marketing, Others. If omitted, it defaults to Others. Custom categories and lists are rejected.

    Optional top-level headers apply to every tool. Use up to 16 HTTP field names with fixed string values of at most 1 KiB each. Quote dates in YAML, for example x-api-version: '2026-05-01'. Header names are case insensitive and cannot contain spaces or repeat. Captain reserves Authorization, Host, Content-Length, Content-Type, and any header starting with X-Replynivo. Keep credentials in secrets and auth_config; header values cannot contain placeholders or control characters.

    Every field is checked on build, and unknown fields are rejected. A typo in a field name keeps the whole manifest out of the catalog rather than publishing it half-read.

    shopify/toolset.yml
    version: 1.0.0kind: captain_toolsetname: Shopify Support Toolscategory: Commercedescription: Look up Shopify orders for support conversations.author: your-github-username inputs:  shop_domain:    label: Shopify store domain    type: string    required: true secrets:  admin_api_access_token:    label: Admin API access token    type: password    required: true tools:  - id: get_shopify_order    title: Get Shopify Order    description: Retrieve an order by its numeric resource ID.    http_method: GET    requires_email_verification: true    endpoint_url: https://${{ inputs.shop_domain }}/admin/api/orders/{{ order_id }}.json    auth_type: api_key    auth_config:      name: X-Shopify-Access-Token      key: ${{ secrets.admin_api_access_token }}    param_schema:      - name: order_id        type: integer        description: The numeric Shopify order resource ID.        required: true

    The two placeholders

    ${{ inputs.name }} ${{ secrets.name }}
    Filled in once, when someone installs your tools. Pulls from the values they entered for your inputs and secrets. Works in the URL, in auth_config, and in a request body.
    {{ order_id }}
    Filled in on every call, by Captain. Each one needs a matching param_schema entry. Captain picks the value out of the conversation using the description you write there.
  3. Protect customer data

    If a tool returns or changes a customer's own data, such as orders, billing, or bookings, it should run only after the customer verifies their email with a one-time code. Set requires_email_verification: true on the tool. If the tool looks the customer up by email, give that parameter source: verified.email instead. Replynivo then fills in the verified email, and Captain can't pass a different one.

    stripe/toolset.yml
    tools:  - id: find_customers_by_email    title: Find Customers by Email    description: Find Stripe customers by email address.    http_method: GET    requires_email_verification: true    endpoint_url: https://api.stripe.com/v1/customers/search?query=email:"{{ email | url_encode }}"    auth_type: bearer    auth_config:      token: ${{ secrets.api_key }}    param_schema:      - name: email        type: string        description: The customer's email address.        required: true        source: verified.email
  4. Validate the manifest

    Paste toolset.yml into the validator and resolve every reported issue. It uses the same schema and Liquid checks as catalog indexing.

  5. Open a pull request

    Open a pull request against Replynivo/tools. The Replynivo team reviews every tool, and once it is merged it appears in this catalog.

    • Short, lowercase folder name
    • author set to your GitHub account
    • README covers setup and permissions
    • No credentials in the manifest
    • Semantic version in toolset.yml
    • Read-only calls unless a write is needed
    • Customer data tools require a verified email

Give this to your coding agent

Paste these instructions into a coding agent in your fork of Replynivo/tools. It will ask which service you want to support, then add a valid folder for it.

Help me add Captain tools to this repository, a fork of https://github.com/chatwoot/tools.

Start by asking me which service the tools should support and which GitHub username or organization to credit as the author. Do not make any files or assumptions until I answer.

Before writing files, inspect the service's official API documentation and the existing folders in this repository. Do not invent endpoints, authentication fields, parameters, or response behavior.

Create one short, lowercase, URL-safe folder at the repository root named after the service, for example stripe. It must not already exist. The folder contains:
- toolset.yml: the strict Captain manifest
- README.md: setup instructions, required permissions, and a concise description of every tool

Follow this manifest contract:
- The schema is implicitly v1. Do not add schema_version or toolset_version.
- Set version to a semantic release version such as 1.0.0.
- Set kind to exactly captain_toolset.
- Set author to the GitHub username or organization I gave you, without the @. It must be an existing GitHub account.
- Include name, description, and 1–50 tools. inputs and secrets are optional maps.
- Choose one category using its exact spelling: Commerce, Payments & billing, Shipping, CRM, Engineering & status, Scheduling, Business data & research, Identity & access, Marketing, Others. Omitted category defaults to Others; custom values and lists are rejected.
- Use inputs for non-sensitive configuration and secrets for credentials.
- Optional top-level headers apply to every tool. Use fixed string values only, with no credentials, control characters, or placeholders. Quote date-like YAML values, for example x-api-version: '2026-05-01'.
- Tool IDs must be stable snake_case matching ^[a-z][a-z0-9_]*$.
- Every tool needs id, title, description, http_method, endpoint_url, and auth_type.
- http_method must be GET, POST, PUT, PATCH, or DELETE.
- Use ${{ inputs.name }} and ${{ secrets.name }} for install-time values.
- Use {{ name }} for call-time values and declare each one in param_schema.
- Add request_template only when the request needs a body.
- Do not add undocumented fields or commit literal credentials.
- Write tool descriptions that explain when Captain should call the tool.

Exact schema:
- Top level: version (required semver string), kind (required literal captain_toolset), name (required, 1–100 characters), description (required, 1–500 characters), author (required GitHub username or organization, without the @), category (optional, one of the allowed categories above, defaults to Others), headers (optional map, defaults to {}), inputs (optional, defaults to {}), secrets (optional, defaults to {}), and tools (required, 1–50 items). No other top-level fields are valid.
- headers accepts up to 16 HTTP field names and literal string values of at most 1 KiB each. Names are case insensitive, cannot repeat, and must follow HTTP field name rules; no X- prefix is required. Authorization, Host, Content-Length, Content-Type, and any header starting with X-Chatwoot are reserved regardless of case. Values cannot contain control characters or placeholders.
- Each input or secret supports only label (required, 1–80 characters), type (optional: string, password, number, boolean, or select; defaults to string), placeholder (optional, up to 200 characters), required (optional boolean; defaults to false), and options (optional list of strings).
- Each tool supports only id, title, description, http_method, endpoint_url, auth_type, auth_config, param_schema, request_template, response_template, enabled, and requires_email_verification.
- Required tool fields: id; title (1–100 characters); description (1–500 characters); http_method; endpoint_url (1–2,000 characters); and auth_type (1–50 characters).
- Optional tool fields: auth_config (map), param_schema (list of maps), request_template (1–20,000 characters), response_template (Liquid string with no explicit length limit), enabled (boolean, defaults to true), and requires_email_verification (boolean, defaults to false).
- auth_config and each param_schema item are flexible maps interpreted by Chatwoot. The manifest, each input or secret, and each tool are strict objects.
- A param_schema item may have source: verified.email. In customer conversations, Chatwoot fills that parameter with the customer's verified email and hides it from Captain, so Captain cannot pass a different one. A parameter with a source must have type: string. verified.email is the only allowed source.
- A tool with a source parameter requires email verification even if requires_email_verification is false.

Placeholder rules:
- Every install-time placeholder must reference a declared input or secret.
- Every call-time placeholder must have a param_schema item with the same name.
- Placeholders may appear in endpoint_url, auth_config values, and request_template.
- response_template formats the HTTP response as plain text using strict Liquid. Its syntax, global variables, and filters are validated when the catalog indexes the manifest.
- In response_template, response contains the parsed JSON body or raw response string; r is an alias for the same value.
- If response_template is omitted or blank, Captain receives the raw response body.
- Response status and headers are not available to the Liquid template.

Use this minimal valid manifest as a structural reference:

version: 1.0.0
kind: captain_toolset
name: Example Support Tools
category: Others
description: Look up account information for support conversations.
author: your-github-username

headers:
  x-api-version: '2026-05-01'

secrets:
  api_token:
    label: API token
    type: password
    required: true

tools:
  - id: get_account
    title: Get Account
    description: Retrieve an account when support needs current account details.
    http_method: GET
    endpoint_url: https://api.example.com/accounts/{{ account_id }}
    auth_type: bearer
    auth_config:
      token: ${{ secrets.api_token }}
    param_schema:
      - name: account_id
        type: string
        description: The account identifier supplied by the customer.
        required: true
    enabled: true

Keep the first version focused on safe, useful support workflows. Prefer read operations unless a write action is explicitly requested.

Protect customer data. If a tool returns or changes a customer's own data, such as billing, bookings, or CRM records, set requires_email_verification: true so it runs only after the customer verifies their email with a one-time code. If the tool looks the customer up by email, give that parameter source: verified.email instead.

Before finishing:
1. Validate the completed manifest with:
   curl -X POST /api/captain/tools/validate -H 'Content-Type: application/yaml' --data-binary @path/to/toolset.yml
   Resolve every returned issue and repeat until the response has valid: true.
2. Check the YAML for duplicate keys and aliases; neither is allowed.
3. Check every object against the exact allowed fields above.
4. Check every placeholder against its input, secret, or param_schema declaration.
5. Confirm every endpoint, method, authentication setting, and parameter against official documentation.
6. Summarize the files, tools, inputs, and secrets you added. Do not commit or open a pull request unless asked.

Ready when you are

Open a pull request against Replynivo/tools. The existing folders show how other tools are laid out.

Logo guidelines

Add optional logo.png and logo-dark.png files beside toolset.yml. No manifest field is needed.

  • Each variant supports PNG, SVG, WebP, or AVIF. The regular and dark logos can use different formats.
  • Use one file per variant. If multiple formats exist, the order is SVG, PNG, WebP, then AVIF, and the build logs a warning.
  • Use static images up to 2 MiB and 4096 by 4096 pixels.
  • Logos are converted to WebP within 256 by 256 pixels, preserving aspect ratio and transparency.
  • SVGs must be self-contained. External resources are not loaded.
  • A missing or invalid regular logo uses the default icon. A missing or invalid dark logo uses the regular logo. Invalid files produce a build warning.

The website uses the regular logo on its light background. Both JSON endpoints provide logo_url and logo_dark_url hosted by the catalog.