Agent skill

Validate Integration

by simstudioai in simstudioai/sim

Validate an existing Sim integration (tools, block, registry, and resolved-secret/model-input boundaries) against the service's API docs and Sim execution conventions

Apache-2.0Auto-check passedDevelopment

Install Validate Integration

skills CLI
$ npx skills add simstudioai/sim --skill validate-integration -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install simstudioai/sim validate-integration --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/validate-integration .claude/skills/validate-integration && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
validate-integration
GitHub stars
30k
Token cost
~8.7k tokens
SKILL.md length
4,025 words
Files
2
Skills in repo
40
Repo updated
First seen
Licence
Apache-2.0

At a glance

Validate an existing Sim integration (tools, block, registry, and resolved-secret/model-input boundaries) against the service's API docs and Sim execution conventions

  • Works in 10 steps: Gather All Files → Pull API Documentation → Validate Tools → …
  • Tasks that involve Technical documentation
  • SKILL.md covers Your Task, Step 1: Gather All Files, Step 2: Pull API Documentation and Step 3: Validate Tools, plus 5 more sections
  • Calls bun, npx and git; reaches docs.sim.ai

What it does

Validate Integration is an agent skill from simstudioai/sim. Validate an existing Sim integration (tools, block, registry, and resolved-secret/model-input boundaries) against the service's API docs and Sim execution conventions

Its SKILL.md is about 8.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `agents/openai.yaml`).

It sits in Development, covering Technical documentation. The repository describes itself as: Sim is the collaborative workspace to build, deploy, and monitor AI agents and workflows. Used by 100,000+ builders. The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Technical documentation

Example prompts

  • “/validate-integration”

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. Gather All Files
  2. Pull API Documentation
  3. Validate Tools
  4. Validate Block
  5. Validate OAuth Scopes (if OAuth service)
  6. Validate Deployment Availability (if OAuth service)
  7. Validate Pagination Consistency
  8. Validate Memory Load Safety
  9. Validate Error Handling
  10. Report and Fix

What it can do on your machine

Read from SKILL.md and the folder at commit 546d4e7. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • bun
    • npx
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • docs.sim.ai

    Also links to:

    • api.service.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Validate Integration loads about 8.7k tokens when it runs. Until then it costs about 47 tokens; SKILL.md has 4,025 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~47
When it runs · the whole SKILL.md, loaded when a task matches
~8.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from simstudioai/sim at commit 546d4e7, republished under its Apache-2.0 licence (© simstudioai). 4,025 words, ~8,667 tokens.

Download SKILL.mdSave it as .claude/skills/validate-integration/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
validate-integration
description
Validate an existing Sim integration (tools, block, registry, and resolved-secret/model-input boundaries) against the service's API docs and Sim execution conventions
argument-hint
<service-name> [api-docs-url]

Validate Integration Skill

You are an expert auditor for Sim integrations. Your job is to thoroughly validate that an existing integration is correct, complete, and follows all conventions.

Your Task

When the user asks you to validate an integration:

  1. Read the service's API documentation (via WebFetch or Context7)
  2. Read every tool, the block, and registry entries
  3. Cross-reference everything against the API docs and Sim conventions
  4. Report all issues found, grouped by severity (critical, warning, suggestion)
  5. Fix all issues after reporting them

Step 1: Gather All Files

Read every file for the integration — do not skip any:

apps/sim/tools/{service}/          # All tool files, types.ts, index.ts
apps/sim/blocks/blocks/{service}.ts # Block definition
apps/sim/tools/registry.ts          # Tool registry entries for this service
apps/sim/blocks/registry-maps.ts    # Block + meta registry entry (BLOCK_REGISTRY / BLOCK_META_REGISTRY)
apps/sim/components/icons.tsx        # Icon definition
apps/sim/lib/auth/connectors/providers.ts # Better Auth connector providers (buildConnectorProviders) — should use getCanonicalScopesForProvider()
apps/sim/lib/oauth/oauth.ts         # OAuth provider config — single source of truth for scopes
apps/sim/lib/oauth/utils.ts         # Scope utilities, SCOPE_DESCRIPTIONS for modal UI
packages/deployment-config/src/env-capabilities.ts # OAuth client runtime capability source of truth
apps/sim/lib/core/config/env.ts     # Runtime env schema for capability fields
packages/sim-setup/src/capability-config.ts # Exhaustive CLI input-mode mapping for OAuth fields
packages/deployment-config/src/integrations.json # Generated client-safe integration catalog
packages/deployment-config/src/service-account-providers.generated.ts # Generated provider-ID facts
packages/deployment-config/src/service-account-metadata.ts # Handwritten deployment policy

If the block, its triggers, or connector fields use a selectorKey, also apply the validate-selector skill and read the key's entry in apps/sim/lib/selectors/manifest.ts, its server attachment and provider listing primitive, and the shared context builder. Selector provider logic runs only server-side through selectors.execute.

Step 2: Pull API Documentation

Fetch the official API docs for the service. This is the source of truth for:

  • Endpoint URLs, HTTP methods, and auth headers
  • Required vs optional parameters
  • Parameter types and allowed values
  • Response shapes and field names
  • Pagination patterns (which param name, which response field)
  • Rate limits and error formats
Hard Rule: No Guessed Response Schemas

If the official docs do not clearly show the response JSON shape for an endpoint, you MUST tell the user instead of guessing.

  • Do NOT assume field names from nearby endpoints
  • Do NOT infer nested JSON paths without evidence
  • Do NOT treat "likely" fields as confirmed outputs
  • Do NOT accept implementation guesses as valid just because they are defensive

If a response schema is unknown, the validation must explicitly call that out and require:

  1. sample responses from the user,
  2. live test credentials for verification, or
  3. trimming the tool/block down to only documented fields.

Step 3: Validate Tools

For every tool file, check:

Tool ID and Naming
  • Tool ID uses snake_case: {service}_{action} (e.g., x_create_tweet, slack_send_message)
  • Tool name is human-readable (e.g., 'X Create Tweet')
  • Tool description is a concise one-liner describing what it does
  • Tool version is set ('1.0.0' or '2.0.0' for V2)
Params
  • All required API params are marked required: true
  • All optional API params are marked required: false
  • Every param has explicit required: true or required: false — never omitted
  • Param types match the API ('string', 'number', 'boolean', 'json')
  • Visibility is correct:
    • 'hidden' — ONLY for OAuth access tokens and system-injected params
    • 'user-only' — for API keys, credentials, and account-specific IDs the user must provide
    • 'user-or-llm' — for everything else (search queries, content, filters, IDs that could come from other blocks)
  • Every param has a description that explains what it does
Request
  • URL matches the API endpoint exactly (correct base URL, path segments, path params)
  • HTTP method matches the API spec (GET, POST, PUT, PATCH, DELETE)
  • Headers include correct auth pattern:
    • OAuth: Authorization: Bearer ${params.accessToken}
    • API Key: correct header name and format per the service's docs
  • Content-Type header is set for POST/PUT/PATCH requests
  • Body sends all required fields and only includes optional fields when provided
  • For GET requests with query params: URL is constructed correctly with query string
  • ID fields in URL paths are .trim()-ed to prevent copy-paste whitespace errors
  • Path params use template literals correctly: `https://api.service.com/v1/${params.id.trim()}`
Response / transformResponse
  • Correctly parses the API response (await response.json())
  • Extracts the right fields from the response structure (e.g., data.data vs data vs data.results)
  • All nullable fields use ?? null
  • All optional arrays use ?? []
  • Error cases are handled: checks for missing/empty data and returns meaningful error
  • Does NOT do raw JSON dumps — extracts meaningful, individual fields
  • Every extracted field is backed by official docs or live-verified sample payloads
Outputs
  • All output fields match what the API actually returns
  • No fields are missing that the API provides and users would commonly need
  • No phantom fields defined that the API doesn't return
  • optional: true is set on fields that may not exist in all responses
  • When using type: 'json' and the shape is known, properties defines the inner fields (tool outputs only — block outputs do not support properties)
  • When using type: 'array', items defines the item structure with properties (tool outputs only)
  • Field descriptions are accurate and helpful
Types (types.ts)
  • Has param interfaces for every tool (e.g., XCreateTweetParams)
  • Has response interfaces for every tool (extending ToolResponse)
  • Optional params use ? in the interface (e.g., replyTo?: string)
  • Field names in types match actual API field names
  • Shared response types are properly reused (e.g., XTweetResponse shared across tweet tools)
Barrel Export (index.ts)
  • Every tool is exported
  • All types are re-exported (export * from './types')
  • No orphaned exports (tools that don't exist)
Tool Registry (tools/registry.ts)
  • Every tool is imported and registered
  • Registry keys use snake_case and match tool IDs exactly
  • Entries are in alphabetical order within the file
Resolved-Secret Provenance and Model Input

For every request field, determine whether it is ordinary API input, model-visible text/structured content, opaque model input, or a value persisted into Sim-owned durable storage.

Treat model-input provenance as opt-in. Require official documentation or an unambiguous local execution path proving that the exact field reaches an AI model. If the evidence is ambiguous, leave the integration unchanged; do not infer a model boundary merely from natural-language, search, extraction, or "AI-powered" marketing terminology.

  • AI-consumed text/structured fields use request.modelInput with mode: 'project' and a minimal exact selector; nested/JSON-string adapters preserve shape through applyProjected
  • Ordinary external URLs, domains, resource IDs, and control fields retain normal request semantics unless the exact field is proven model-visible; an AI-backed provider or later model processing of the referenced resource is not sufficient evidence
  • Serialized content proven to be sent directly to an external model is selected by request.modelInput, projected before the existing formatter parses it, and has deterministic formatter behavior when a whole-value placeholder is invalid for the serialized grammar
  • Actual inline/raw AI-consumed bytes owned by a registered in-process operation use operation.modelInput with privateInputPaths (or mode: 'private-provenance'), and the operation calls validateOpaqueModelInputProvenance before model egress; storage keys, paths, signed URLs, and ordinary remote URLs are not treated as byte provenance, while tracked stored bytes are authorized independently at the owning model-egress boundary
  • Persisted workspace-file contents are checked with the shared provenance guard only when their bytes or decoded content cross into a model/tool-result boundary; ordinary file APIs remain unchanged. Unsupported secret-bearing file paths are rejected at file_write
  • Sim-owned durable writes and internal execution handoffs that can enter workflows/models use field-scoped operation.secretProvenance; the owning operation validates the exact selection and scope, strip private metadata, and persist, import, or propagate it at the owning boundary
  • Private provenance is never attached to external URLs; registered in-process operations preserve it through operation.modelInput / operation.secretProvenance, while proven model-visible external fields use request projection and other external inputs remain unchanged
  • No tool performs raw secret plaintext/source substitution or serializes plaintext provenance
  • No transformResponse or tool-local helper blanket-sanitizes ordinary third-party results; only execution-scoped, activated Sim provenance is projected at shared model/log boundaries
  • Private headers/envelopes are produced and stripped by the shared tool executor, never hand-rolled or returned as functional output
  • Every added provenance hook has a concrete Sim {{...}} resolution path and a later persistence/model/log crossing; there is no generic handling for arbitrary filenames, metadata, provider results, or API payloads
  • Diagnostic projection is applied only to values carrying execution-scoped provenance; ordinary provider responses, filenames, URLs, and errors are unchanged
  • Tests cover named {{NAME}} projection, unproven identical public text, nested and serialized shape handling, unchanged ordinary external inputs, malformed/incomplete metadata, headerless legacy requests, metadata stripping, and durable legacy/stale/scope cases when applicable

Treat a missing or bypassed model, durable, or internal-execution provenance boundary as critical. Do not fix it with a tool-specific string replacer or by sanitizing every provider result; repair the shared request, in-process operation, persistence, or re-entry boundary that owns the data.

Step 4: Validate Block

Block ↔ Tool Alignment (CRITICAL)

This is the most important validation — the block must be perfectly aligned with every tool it references.

For each tool in tools.access:

  • The operation dropdown has an option whose ID matches the tool ID (or the tools.config.tool function correctly maps to it)
  • Every required tool param (except accessToken) has a corresponding subBlock input that is:
    • Shown when that operation is selected (correct condition)
    • Marked as required: true (or conditionally required)
  • Every optional tool param has a corresponding subBlock input (or is intentionally omitted if truly never needed)
  • Every subBlock id is unique (duplicates collide silently; the last definition wins). blocks.test.ts fails a duplicate within one condition unless the copies are a basic/advanced mode-swap pair, one basic plus trigger-mode copies, or all carry canonicalParamId. The only sanctioned cross-condition reuse is the hosted-key apiKey pair (add-hosted-key skill)
  • The tools.config.tool function returns the correct tool ID for every possible operation value
  • Each subBlock (or its canonicalParamId) is named exactly after the tool param it fills. A required user-only param that is only renamed in tools.config.params fails bun run apps/sim/scripts/check-block-registry.ts origin/staging; remap only optional or user-or-llm params
SubBlocks
  • Operation dropdown lists ALL tool operations available in tools.access
  • Dropdown option labels are human-readable and descriptive
  • Conditions use correct syntax:
    • Single value: { field: 'operation', value: 'x_create_tweet' }
    • Multiple values (OR): { field: 'operation', value: ['x_create_tweet', 'x_delete_tweet'] }
    • Negation: { field: 'operation', value: 'delete', not: true }
    • Compound: { field: 'op', value: 'send', and: { field: 'type', value: 'dm' } }
  • Condition arrays include ALL operations that use that field — none missing
  • dependsOn is set for fields that need other values (selectors depending on credential, cascading dropdowns)
  • SubBlock types match tool param types:
    • Enum/fixed options → dropdown
    • Free text → short-input
    • Long text/content → long-input
    • True/false → switch (a Yes/No dropdown only when the tool needs a third "unset" state)
    • Credentials → oauth-input with correct serviceId
  • Dropdown value: () => 'default' is set for dropdowns with a sensible default
  • Every short-input, long-input, code, and selector subBlock has a placeholder — including password fields (Enter your API key). Formatted values show the shape (2023-01-01T00:00:00Z); optional fields with a server default name it. See add-integration → Step 3
Advanced Mode
  • Optional, rarely-used fields are set to mode: 'advanced':
    • Pagination tokens / next tokens
    • Time range filters (start/end time)
    • Sort order / direction options
    • Max results / per page limits
    • Reply settings / threading options
    • Rarely used IDs (reply-to, quote-tweet, etc.)
    • Exclude filters
  • Required fields are NEVER set to mode: 'advanced'
  • Fields that users fill in most of the time are NOT set to mode: 'advanced'
WandConfig
  • Timestamp fields have wandConfig with generationType: 'timestamp'
  • Comma-separated list fields have wandConfig with a descriptive prompt
  • Complex filter/query fields have wandConfig with format examples in the prompt
  • All wandConfig prompts end with an explicit Return ONLY the <format> instruction so the generated value can be pasted directly into the field
  • wandConfig.placeholder describes what to type in natural language
Tools Config
  • tools.access lists every tool ID the block can use — none missing
  • tools.config.tool returns the correct tool ID for each operation
  • Type coercions are in tools.config.params (runs at execution time), NOT in tools.config.tool (runs at serialization time before variable resolution — coercing there destroys dynamic references like <Block.output>)
  • tools.config.params handles:
    • Number() conversion for numeric params that come as strings from inputs
    • Boolean / string-to-boolean conversion for toggle params
    • Empty string → undefined conversion for optional dropdown values
    • SubBlock ID → tool param name remapping only for optional or user-or-llm params
Block Outputs
  • Outputs cover the key fields returned by ALL tools (not just one operation)
  • Output types are correct ('string', 'number', 'boolean', 'json', 'file', 'file[]')
  • type: 'json' outputs describe inner fields in the description string: 'User profile (id, name, username, bio)' or '[{address, status, type}]' for arrays
  • Do NOT add a properties: {...} field on block outputs. Block-level OutputFieldDefinition (from @sim/workflow-types/blocks) only accepts { type, description?, condition?, hiddenFromDisplay? }. Nested properties is a tool-level construct (OutputProperty) — adding it to a block output will fail TypeScript at build time
  • No opaque type: 'json' with vague descriptions like 'Response data'
  • Outputs that only appear for certain operations use condition if supported, or document which operations return them
Block Metadata
  • type is snake_case (e.g., 'x', 'cloudflare')
  • name is human-readable (e.g., 'X', 'Cloudflare')
  • description is a concise one-liner
  • longDescription provides detail for docs
  • docsLink points to 'https://docs.sim.ai/integrations/{service}'
  • category is 'tools'
  • bgColor uses the service's brand color hex
  • icon references the correct icon component from @/components/icons
  • authMode is set correctly (AuthMode.OAuth or AuthMode.ApiKey)
  • Block + meta are registered in blocks/registry-maps.ts (BLOCK_REGISTRY / BLOCK_META_REGISTRY) alphabetically
BlockMeta
  • {Service}BlockMeta is exported in the same file as the block
  • Has at least 7 templates, each with icon, title, prompt, modules, category, and tags
  • Prompts describe concrete use cases, not generic descriptions of what the service does
  • alsoIntegrations is set on any template whose prompt references another service
  • skills present (3–5 mainstream, 2–3 niche), each grounded in tools.access — flag any skill implying an unsupported action
  • Each skill is real, not hallucinated — web-search and confirm it maps to a popular use case attested online (vendor use-case pages, official docs describing the workflow, reputable "top automations" articles); rewrite/remove any you cannot source
  • Each skill has a kebab-case name (≤64 chars, unique), a one-line description, and markdown content with # Title + ## Steps + an output/guidance section
Block Inputs
  • inputs section lists all subBlock params that the block accepts
  • Input types match the subBlock types
  • When using canonicalParamId, inputs list the canonical ID (not the raw subBlock IDs)
Dynamic Selectors
  • Every remote selectorKey is classified in the browser-safe manifest and has exactly one server attachment
  • The manifest allowlists the minimal active dependsOn context and matches list/search/detail, pagination, scope, and stale-time behavior
  • Canonical basic/advanced and trigger/action modes project only their active values; exact {{KEY}} references remain unresolved in the browser
  • Stored credentials are bound to the actor, workspace, and trusted provider/service
  • Each attachment declares and enforces a fixed, credential-bound, or explicitly reviewed user-controlled destination policy
  • Provider results are explicitly projected to safe option fields; secrets, tokens, credential IDs, context values, and raw upstream errors do not enter responses, logs, or query keys
  • No selector provider module, provider fetch, or OAuth-token request runs in the browser, and no selector-only provider route remains

Step 5: Validate OAuth Scopes (if OAuth service)

Scopes are centralized — the single source of truth is OAUTH_PROVIDERS in lib/oauth/oauth.ts.

  • Scopes defined in lib/oauth/oauth.ts under OAUTH_PROVIDERS[provider].services[service].scopes
  • lib/auth/connectors/providers.ts (buildConnectorProviders) uses getCanonicalScopesForProvider(providerId) — NOT a hardcoded array
  • Block requiredScopes uses getScopesForService(serviceId) — NOT a hardcoded array
  • No hardcoded scope arrays in lib/auth/connectors/providers.ts or block files (should all use utility functions)
  • Each scope has a human-readable description in SCOPE_DESCRIPTIONS within lib/oauth/utils.ts
  • No excess scopes that aren't needed by any tool
Show full SKILL.md (1,673 more words)Show less

Step 6: Validate Deployment Availability (if OAuth service)

The deployment UI and setup CLI do not infer OAuth client fields from scopes. They resolve the block's generated oauthServiceId through the shared deployment capability catalog.

  • The visible integration block has exactly one distinct oauth-input.serviceId
  • resolveOAuthClientCapabilityId(serviceId) returns the intended provider capability
  • The resolved provider exists in OAUTH_CLIENT_CAPABILITIES
  • Every field listed by that capability exists in apps/sim/lib/core/config/env.ts
  • Every capability field has the correct text or secret entry in OAUTH_CLIENT_SETUP_FIELDS; no CLI naming heuristic is required
  • Shared Google/Microsoft service IDs resolve to their provider capability rather than duplicate entries
  • npx sim-setup add integration <capabilityId> is the command emitted by availability; the CLI has only the exhaustive input-mode projection, not a second runtime provider definition
  • If the canonical OAuth service declares serviceAccountProviderId, the generated SERVICE_ACCOUNT_PROVIDER_BY_OAUTH_SERVICE_ID[serviceId] has the same provider ID
  • The service-account deploymentRequirement matches how that credential actually works: omitted for an independent path, 'oauth-client' when it needs the OAuth client fields, or 'preview-gated' when controlled by a preview block

Treat a missing capability as critical: runtime availability intentionally throws instead of silently exposing an unusable integration.

Step 7: Validate Pagination Consistency

If any tools support pagination:

  • Pagination param names match the API docs (e.g., pagination_token vs next_token vs cursor)
  • Different API endpoints that use different pagination param names have separate subBlocks in the block
  • Pagination response fields (nextToken, cursor, etc.) are included in tool outputs
  • Pagination subBlocks are set to mode: 'advanced'

Step 8: Validate Memory Load Safety

If any tool lists, searches, exports, imports, downloads, uploads, paginates, batches, transforms arrays, or reads file/HTTP bodies, read .agents/skills/memory-load-check/SKILL.md and apply it to the integration.

  • List/search tools expose API limits and do not auto-fetch every page into memory
  • Transform logic does not build unbounded arrays, maps, sets, or Promise.all fan-outs
  • File and HTTP body reads use explicit byte caps or existing stream-limit helpers
  • Internal file results reach createInternalToolFileResult / createInternalToolFilesResult before JSON serialization; external raw downloads explicitly use request.responseType: 'binary' and return a buffered output.file. Provider base64 JSON needs separate handling
  • Transforms retain stored UserFile identity/access fields, and tests cover a >10 MiB file crossing executor admission without another upload. New file outputs contain references only, without inline content aliases; preserve legacy versions when removing existing inline fields
  • Scan every file-producing path, including attachment fetches inside transformResponse, URL descriptors, export operations, and old/new block versions; checking download-named tools alone misses late reads that occur after the first response admission
  • Late attachment reads share a per-call byte budget, bound actual streamed bytes independently of provider size metadata, and forward ToolResponseContext.signal through every fetch/read
  • Both workflow and Copilot tests produce compact UserFile outputs; nested message attachment aliases reference the same stored files, with no duplicate upload or raw bytes left behind
  • New output contracts omit redundant copies of file name, MIME type, size, URL, and success; retained provider metadata has a distinct purpose, and types match the stored-file runtime shape
  • Large result payloads are summarized, paginated, referenced, or capped rather than raw-dumped
  • Pagination and download tests cover caps, early stop behavior, or partial-result preservation when relevant

Step 9: Validate Error Handling

  • transformResponse checks for error conditions before accessing data
  • Error responses include meaningful messages (not just generic "failed")
  • HTTP error status codes are handled (check response.ok or status codes)

Step 10: Report and Fix

Report Format

Group findings by severity:

Critical (will cause runtime errors or incorrect behavior):

  • Wrong endpoint URL or HTTP method
  • Missing required params or wrong required flag
  • Incorrect response field mapping (accessing wrong path in response)
  • Missing error handling that would cause crashes
  • Tool ID mismatch between tool file, registry, and block tools.access
  • OAuth scopes missing in lib/auth/connectors/providers.ts that tools need
  • OAuth integration serviceId missing from the deployment capability catalog
  • Capability references an env field absent from the runtime env schema
  • Service-account metadata disagrees with the canonical OAuth service configuration
  • tools.config.tool returning wrong tool ID for an operation
  • Type coercions in tools.config.tool instead of tools.config.params
  • Proven model-visible request fields bypass the shared projection or private-provenance boundary
  • Opaque model input is downloaded or sent before provenance and workspace-file checks
  • A Sim-owned durable sink or internal execution handoff drops encrypted provenance or breaks legacy headerless/NULL data
  • A tool substitutes secret plaintext into source, leaks private metadata, or generically sanitizes unrelated third-party results
  • A selector resolves shared secret plaintext in the browser, lacks credential provider binding or destination enforcement, or returns provider payloads or protected values across the selector boundary

Warning (follows conventions incorrectly or has usability issues):

  • Optional field not set to mode: 'advanced'
  • Missing wandConfig on timestamp/complex fields
  • Wrong visibility on params (e.g., 'hidden' instead of 'user-or-llm')
  • Missing optional: true on nullable outputs
  • Opaque type: 'json' without property descriptions
  • Missing .trim() on ID fields in request URLs
  • Missing ?? null on nullable response fields
  • Block condition array missing an operation that uses that field
  • Hardcoded scope arrays instead of using getScopesForService() / getCanonicalScopesForProvider()
  • Missing scope description in SCOPE_DESCRIPTIONS within lib/oauth/utils.ts

Suggestion (minor improvements):

  • Better description text
  • Inconsistent naming across tools
  • Missing longDescription or docsLink
  • Pagination fields that could benefit from wandConfig
Fix All Issues

After reporting, fix every critical and warning issue. Apply suggestions where they don't add unnecessary complexity.

Regenerate Derived Artifacts

Several files are generated from tool and block definitions. Editing a tool or block WITHOUT regenerating them fails CI, so run these before pushing:

bash
bun run tool-metadata:generate       # repo root — apps/sim/tools/generated/*
bun run scripts/generate-docs.ts     # docs .mdx + deployment-config/integrations.json + docs icons
bun run deployment-config:generate  # canonical OAuth registry + catalog → provider-ID facts
bun run integration-catalog:check    # registry ↔ committed deployment metadata drift
bun run docs:check                   # committed docs ↔ what the generator renders today
bun run deployment-config:check     # OAuth registry/catalog ↔ provider-ID fact drift
bun run check:audits                 # every audit CI enforces, including docs:check
bun run apps/sim/scripts/check-block-registry.ts origin/staging  # block ↔ tool param coverage (CI, not in check:audits)
  • tool-metadata:generate — required whenever a tool's outputs, params, or descriptions change. CI enforces this with bun run tool-metadata:check, which fails with "Generated tool metadata is stale". This is the easiest gate to miss, because nothing in the tool file hints that a generated artifact mirrors it.
  • generate-docs — required whenever block metadata changes (bgColor, name, description, operations, outputs). Regenerates the integration .mdx, packages/deployment-config/src/integrations.json, and the docs copy of components/icons.tsx.
  • deployment-config:generate — required for OAuth or service-account changes. Regenerates provider-ID facts from the canonical OAuth registry and integration catalog; special deployment requirements remain handwritten policy.
  • integration-catalog:check — loads the executable block registry, derives visible integration deployment fields, and compares them with the committed catalog. It catches missing/unexpected entries and stale auth/service IDs without loading the executable registry in client code.
  • docs:check — check mode of generate-docs.ts: renders every generated docs artifact in memory and fails listing any committed file that differs. Runs in CI via check:audits.

Always diff the regen output before committing — but commit all of it. These generators rewrite every file they own, so they also true up drift that accumulated on the base branch (pages whose source changed without a regen). That catch-up is correct output, not a regression: docs:check fails CI on any page left stale, so reverting swept-in hunks with git checkout -- reintroduces the failure. Review the diff to confirm each hunk is explained by a real source change (yours or an upstream PR that skipped regeneration), and investigate anything that looks like content loss — a page losing a section usually means its source block moved or a generator input broke, not that the hunk should be reverted.

The integration's page must carry a {/* MANUAL-CONTENT-START:intro */} section directly under <BlockInfoCard />. If it is missing, write one using the template in add-integration → Step 8, and check an existing intro against what the block actually ships (no removed or unshipped operations).

If an icon changed, apps/sim/components/icons.tsx is the source of truth and apps/docs/components/icons.tsx is its generated mirror — they must end up byte-identical for that component.

Validation Output

After fixing, confirm:

  1. bun run lint passes with no fixes needed
  2. TypeScript compiles clean (no type errors) — check the error list is empty for the files you touched; pre-existing unrelated errors in a worktree usually mean workspace packages resolve to the main checkout
  3. The integration's tests pass, and any test you added actually fails without its fix (revert it once and watch it go red)
  4. Derived artifacts regenerated and their diffs reviewed (see above)
  5. bun run integration-catalog:check passes
  6. bun run docs:check passes
  7. bun run apps/sim/scripts/check-block-registry.ts origin/staging passes
  8. For OAuth or service-account changes, bun run deployment-config:check passes
  9. For OAuth or service-account changes, bun run --cwd apps/sim test lib/integrations/availability.server.test.ts passes
  10. Re-read all modified files to verify fixes are correct
  11. Any remaining unknown response schemas were explicitly reported to the user instead of guessed

Checklist Summary

  • Read ALL tool files, block, types, index, and registries
  • Pulled and read official API documentation
  • Validated every tool's ID, params, request, response, outputs, and types against API docs
  • Validated block ↔ tool alignment (every tool param has a subBlock, every condition is correct)
  • Validated advanced mode on optional/rarely-used fields
  • Validated every text-entry and selector subBlock has a placeholder
  • Validated wandConfig on timestamps and complex inputs
  • Validated tools.config mapping, tool selector, and type coercions
  • Validated block outputs match what tools return, with typed JSON where possible
  • Validated OAuth scopes use centralized utilities (getScopesForService, getCanonicalScopesForProvider) — no hardcoded arrays
  • Validated scope descriptions exist in SCOPE_DESCRIPTIONS within lib/oauth/utils.ts for all scopes
  • Validated OAuth serviceId resolves to the intended OAUTH_CLIENT_CAPABILITIES entry and all capability fields exist in the env schema
  • Validated service-account projection and deployment requirement against the canonical OAuth service config
  • Regenerated deployment config when block/OAuth metadata changed and ran both catalog checks
  • Validated pagination consistency across tools and block
  • Validated memory load safety using .agents/skills/memory-load-check/SKILL.md when tools list/search/download/import/export/batch data
  • Validated error handling (error checks, meaningful messages)
  • Validated registry entries (tools and block, alphabetical, correct imports)
  • Validated model-visible/opaque inputs and Sim-durable/internal-execution provenance at their owning boundaries
  • Confirmed legacy persisted data keeps working and tracked invalid provenance fails closed
  • Confirmed ordinary third-party results remain unchanged absent activated Sim provenance
  • Validated {Service}BlockMeta exported with at least 7 templates
  • Validated every dynamic selector through the shared manifest, server attachment, and selectors.execute boundary
  • Reported all issues grouped by severity
  • Fixed all critical and warning issues
  • Ran bun run tool-metadata:generate if any tool outputs/params changed, and confirmed bun run tool-metadata:check passes
  • Ran bun run scripts/generate-docs.ts if any block metadata changed, and committed the full generated diff — including stale-page catch-up for other integrations (bun run docs:check fails CI on reverted generator output)
  • Validated the docs page has an accurate MANUAL-CONTENT-START:intro section
  • Ran bun run lint after fixes
  • Verified TypeScript compiles clean
  • Verified added tests fail without their fix

© simstudioai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in .agents/skills/validate-integration of simstudioai/sim.

  • SKILL.md
  • agents/openai.yaml

Open the folder on GitHubat commit 546d4e7

Compare with similar skills

Validate Integration next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Validate Integration compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Validate Integration this skillsimstudioai/sim30k—~8.7kAutomated safety check: PassApache-2.0
Diagram Designcathrynlavery/diagram-design44k1 repos~7.5kAutomated safety check: PassMIT
Simple Englishmoeru-ai/airi50k2 repos~4.6kAutomated safety check: PassMIT
Get API Docs with chubandrewyng/context-hub14k2 repos~775Automated safety check: PassMIT
Doc SyncJetBrains/ideavim10k2 repos~2.6kAutomated safety check: PassMIT
Mailspring App ScreenshotsFoundry376/Mailspring18k—~1.4kAutomated safety check: PassGPL-3.0

Similar skills

  • Diagram Design

    cathrynlavery/diagram-design

    Creates branded diagrams, from architecture, flowchart and sequence to charts and maps, as self-contained HTML with inline SVG, with import from draw.io, Mermaid and Excalidraw.

    44k GitHub starsUsed in 1 repo~7.5k tokens
    DevelopmentAuto-check passed
  • Simple English

    moeru-ai/airi

    Write or rewrite technical text with the rules of ASD-STE100 Simplified Technical English so it is clear, unambiguous, and free of AI slop.

    50k GitHub starsUsed in 2 repos~4.6k tokens
    DevelopmentAuto-check passed
  • Get API Docs with chub

    andrewyng/context-hub

    Fetches current documentation for third-party APIs and SDKs with the chub CLI before the agent writes code against them, instead of relying on remembered API shapes.

    14k GitHub starsUsed in 2 repos~775 tokens
    DevelopmentAuto-check passed
  • Doc Sync

    JetBrains/ideavim

    Official

    Keeps IdeaVim documentation in sync with code changes. An agent skill from JetBrains/ideavim.

    10k GitHub starsUsed in 2 repos~2.6k tokens
    DevelopmentAuto-check passed
  • Mailspring App Screenshots

    Foundry376/Mailspring

    Captures screenshots of the running Mailspring dev app for docs, PRs or visual checks by launching it with a debugging port, driving the UI and clipping to an element.

    18k GitHub stars~1.4k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Draw.io Diagram Studio

    Agents365-ai/drawio-skill

    Creates and edits editable draw.io diagrams from descriptions, code, infrastructure files, SQL and API schemas, with sync, review, test and export tools.

    10k GitHub stars~2.4k tokensUpdated 5 days ago
    DevelopmentAuto-check: notes

More from simstudioai/sim

All 40 skills in this repo
  • Sim Helm

    simstudioai/sim

    Install, upgrade, and operate the Sim Helm chart on Kubernetes.

    30k GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Add Column Type

    simstudioai/sim

    Add a new table column type to Sim — registry entry, icon, storage shape, coercion, and the behavioral hooks the grid and API read.

    30k GitHub stars~2.9k tokensUpdated today
    Auto-check passed
  • Add Enrichment

    simstudioai/sim

    Add a code-defined table enrichment (registry entry) under apps/sim/enrichments/ backed by an ordered provider cascade, ensuring every provider tool it calls has hosted-key support.

    30k GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Add Hosted Key

    simstudioai/sim

    Add hosted API key support to a tool so Sim provides the key (metered and billed to the workspace) when a user has not brought their own.

    30k GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Add Managed CLI

    simstudioai/sim

    Add or upgrade a curated, immutable managed CLI for Sim Function sandboxes, including client-safe catalog metadata, a pinned server-only installation recipe, checksum and executable verification…

    30k GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Add Selector

    simstudioai/sim

    Add or update a Sim dynamic selector using the shared manifest, server attachment, and selectors.execute path.

    30k GitHub stars~1.7k tokensUpdated today
    Auto-check passed

Categories

Questions about Validate Integration

What does Validate Integration do?

Validate an existing Sim integration (tools, block, registry, and resolved-secret/model-input boundaries) against the service's API docs and Sim execution conventions. Validate Integration is an agent skill from simstudioai/sim.

When should I use Validate Integration?

Validate Integration fits situations like: tasks that involve Technical documentation.

How do I install Validate Integration in Claude Code?

Run `npx skills add simstudioai/sim --skill validate-integration -a claude-code`. Or copy the skill folder (.agents/skills/validate-integration in simstudioai/sim) into .claude/skills/validate-integration in your project. Claude Code loads it when a task matches its description.

How do I install Validate Integration in Codex?

Run `npx skills add simstudioai/sim --skill validate-integration -a codex`. Or copy the skill folder (.agents/skills/validate-integration in simstudioai/sim) into .agents/skills/validate-integration in your project. Codex loads it when a task matches its description.

Can I use Validate Integration in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add simstudioai/sim --skill validate-integration -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/validate-integration, .gemini/skills/validate-integration, .github/skills/validate-integration and .opencode/skills/validate-integration in your project.

What does Validate Integration need to run?

Going by SKILL.md and its folder, Validate Integration needs the command-line tools its instructions call (bun, npx and git).

Does Validate Integration access the network?

SKILL.md names 2 domains. In commands or code: docs.sim.ai; the agent is likely to contact it when it follows the instructions. As links in the text: api.service.com. This is read from the text; nothing was executed.

Is Validate Integration safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Validate Integration use?

Validate Integration is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Validate Integration use?

About 8.7k tokens (SKILL.md is roughly 35k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Validate Integration?

Skills that share tags, products or a category with Validate Integration: Diagram Design (cathrynlavery/diagram-design, 44k stars), Simple English (moeru-ai/airi, 50k stars), Get API Docs with chub (andrewyng/context-hub, 14k stars) and Doc Sync (JetBrains/ideavim, 10k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Validate Integration?

simstudioai (a GitHub organization) maintains it in simstudioai/sim, which has 29,785 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on October 7, 2026.

Source: simstudioai/sim on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.