Meilisearch PHP PHPDoc Writer
meilisearch/meilisearch-php
Documents public methods of the meilisearch-php SDK with compact PHPDoc, including @see links, @since tags and the experimental-feature notice.
Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions.
$ npx skills add simstudioai/sim --skill add-integration -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install simstudioai/sim add-integration --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/add-integration .claude/skills/add-integration && rm -rf skills-srcUse ~/.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/
Install the "add-integration" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integration into .claude/skills/add-integration/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-integration", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integrationType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add simstudioai/sim --skill add-integration -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install simstudioai/sim add-integration --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/add-integration .agents/skills/add-integration && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "add-integration" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integration into .agents/skills/add-integration/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-integration", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add simstudioai/sim --skill add-integration -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install simstudioai/sim add-integration --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/add-integration .cursor/skills/add-integration && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "add-integration" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integration into .cursor/skills/add-integration/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-integration", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/simstudioai/sim.git --path .agents/skills/add-integration--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add simstudioai/sim --skill add-integration -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install simstudioai/sim add-integration --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/add-integration .gemini/skills/add-integration && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "add-integration" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integration into .gemini/skills/add-integration/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-integration", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install simstudioai/sim add-integrationInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add simstudioai/sim --skill add-integration -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/add-integration .github/skills/add-integration && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "add-integration" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integration into .github/skills/add-integration/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-integration", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add simstudioai/sim --skill add-integration -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install simstudioai/sim add-integration --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/add-integration .opencode/skills/add-integration && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "add-integration" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/add-integration into .opencode/skills/add-integration/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-integration", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
add-integrationAdd a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions.
Add Integration is an agent skill from simstudioai/sim. Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions. Use when introducing a new service under apps/sim/tools, apps/sim/blocks, and apps/sim/triggers.
Its SKILL.md is about 7.5k 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.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 546d4e7. It shows what the files ask for, not the result of running them.
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.
Shell commands in SKILL.md call:
bunFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
w3.orgservice.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Add Integration loads about 7.5k tokens when it runs. Until then it costs about 73 tokens; SKILL.md has 2,988 words of instructions outside code blocks.
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.
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.
The full file from simstudioai/sim at commit 546d4e7, republished under its Apache-2.0 licence (© simstudioai). 2,988 words, ~7,461 tokens.
.claude/skills/add-integration/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.You are an expert at adding complete integrations to Sim. This skill orchestrates the full process of adding a new service integration.
Adding an integration involves these steps in order:
Before writing any code:
mcp__context7__resolve-library-id, then fetch with mcp__context7__query-docsIf the official docs do not clearly show the response JSON shape for an endpoint, you MUST stop and tell the user exactly which outputs are unknown.
transformResponse against unverified payload shapesIf response schemas are missing or incomplete, do one of the following before proceeding:
apps/sim/tools/{service}/
├── index.ts # Barrel exports
├── types.ts # TypeScript interfaces
├── {action1}.ts # Tool for action 1
├── {action2}.ts # Tool for action 2
└── ...Choose the tool boundary before writing the declaration:
InternalToolConfig.operation for same-process Sim/provider work. Put the handler under
apps/sim/lib/internal/{service}/execute-tool.ts and register every ID in
apps/sim/lib/internal/tool-operations/registry.server.ts.ToolConfig.request only for an absolute external HTTP(S) provider endpoint.Never point a tool at /api/..., construct an absolute URL back to Sim, declare
request.internal, add a directExecution property (it fails bun run check:tool-request-boundary), or add an API route merely to reuse code, normalize files, or authorize
resources. A real external/browser route and an in-process tool may share the same operation, but
neither calls the other. Follow the full transport and handler rules in the add-tools skill.
types.ts:
import type { ToolResponse } from '@/tools/types'
export interface {Service}{Action}Params {
accessToken: string // For OAuth services
// OR
apiKey: string // For API key services
requiredParam: string
optionalParam?: string
}
export interface {Service}{Action}Response extends ToolResponse {
output: {
// Define output structure
}
}Declare one response interface per tool, imported by that tool's ToolConfig<Params, Response> (or InternalToolConfig for in-process work). Never add an umbrella {Service}Response union: nothing imports it.
Tool file pattern: an external provider API uses ToolConfig with request (absolute https:// URL, headers, body, transformResponse); same-process Sim work uses InternalToolConfig with operation. Both full templates, param visibility rules, and output typing live in .agents/skills/add-tools/SKILL.md — read it before writing the first tool.
visibility: 'hidden' for OAuth tokensvisibility: 'user-only' for API keys and user credentialsvisibility: 'user-or-llm' for operation parameters?? null for nullable API response fields?? [] for optional array fieldsoptional: true for outputs that may not existtype: 'json' and you know the object shape, define properties with the inner fields so downstream consumers know the structure. Only use bare type: 'json' when the shape is truly dynamicClassify every request field (ordinary provider input / AI-consumed text / opaque model bytes /
Sim-durable storage) before implementing the tool and apply the shared projection or provenance
mechanism only where a concrete Sim {{...}} resolution path reaches a later model or log boundary.
Full rules and the required tests are in .agents/skills/add-tools/SKILL.md → "Resolved Secrets and
Provenance Boundaries".
apps/sim/blocks/blocks/{service}.ts
Follow .agents/skills/add-block/SKILL.md for the block structure, subBlock types,
condition/dependsOn/required/mode syntax, outputs, canvasPresentation sentences, and the
{Service}BlockMeta export (minimum 7 templates, plus url and skills). Every block declares
canvasPresentation; bun run apps/sim/scripts/check-canvas-sentences.ts --block={service} must
pass (CI runs check:canvas-sentences --require-coverage).
Three rules that are easy to get wrong when copying from existing blocks:
selectorKey must use the unified server selector path. Apply the add-selector skill:
add browser-safe metadata to apps/sim/lib/selectors/manifest.ts, reuse or extract a server-only
provider listing primitive, and add a credential- and destination-bound server attachment. Do not
add a client provider fetcher, a provider-specific query key, browser token acquisition, or a
selector-only API route. The shared context builder sends only active dependsOn values and
preserves exact {{KEY}} environment references for server-side resolution.canonicalParamId; its constraints are in
.claude/rules/sim-integrations.md and the add-block skill → canonicalParamId Pattern.short-input, long-input, code) and every selector declares a
placeholder; an empty box tells the user nothing. Secrets read Enter your {thing} (e.g.
Enter your API key), free text names what to type (Enter branch name), and formatted values
show the shape (2023-01-01T00:00:00Z, 1 to 1000). An optional field with a server-side default
names that default (Defaults to the database region). Dropdowns, switches, and oauth-input do
not need one.apps/sim/components/icons.tsx
export function {Service}Icon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
{/* SVG paths from user-provided SVG */}
</svg>
)
}Do not search for icons yourself. At the end of implementation, ask the user to paste the service's SVG (usually on its brand/press kit page).
Once the user provides the SVG:
The icon renders both inside its colored bgColor tile AND "bare" (no tile) on a
neutral page — e.g. the home Suggested actions list — in both light and dark
mode. A monochrome logo whose paths hardcode a single near-white or near-black
fill is invisible bare on the matching background (white-on-white in light mode,
black-on-black in dark mode).
Rules when adding the SVG:
fill='currentColor', not fill='#fff' / fill='#000000'. It then inherits
white inside dark tiles, near-black inside light tiles (via
getTileIconColorClass), and the theme-aware var(--text-icon) bare — legible
everywhere. Do NOT set iconColor for these.iconColor (a vivid brand hex, never a
near-black/near-white tile color) if the bare icon should adopt a brand tint.currentColor.Verify with bun run check:bare-icons (also runs in CI). It flags purely
monochrome hazards; for partial-accent logos, eyeball the suggested-actions list
in both light and dark mode.
If the service supports webhooks or needs polling, follow .agents/skills/add-trigger/SKILL.md
(directory layout, buildTriggerSubBlocks, provider handler, polling handler); then wire
triggers.enabled / triggers.available into the block and spread each trigger's
getTrigger(id).subBlocks after the tool subBlocks.
apps/sim/tools/registry.ts)// Add import (alphabetically)
import {
{service}Action1Tool,
{service}Action2Tool,
} from '@/tools/{service}'
// Add to tools object (alphabetically)
export const tools: Record<string, ExecutableToolConfig> = {
// ... existing tools ...
{service}_action1: {service}Action1Tool,
{service}_action2: {service}Action2Tool,
}Then regenerate the generated tool metadata and commit it:
bun run tool-metadata:generateClient code reads params/outputs from these artifacts rather than importing
the registry, so a tool you add, change or remove is invisible to the UI until they are regenerated,
and CI fails on stale ones. See .agents/skills/tool-registry-boundary/SKILL.md.
apps/sim/blocks/registry-maps.ts)The data maps (BLOCK_REGISTRY + BLOCK_META_REGISTRY) live in registry-maps.ts; registry.ts holds only the accessor functions. Add the import and an entry to each map alphabetically:
// Add import (alphabetically)
import { {Service}Block, {Service}BlockMeta } from '@/blocks/blocks/{service}'
// Add to the config map (alphabetically)
export const BLOCK_REGISTRY: Record<string, BlockConfig> = {
// ... existing blocks ...
{service}: {Service}Block,
}
// Add to the catalog-meta map (alphabetically)
export const BLOCK_META_REGISTRY: Record<string, BlockMeta> = {
// ... existing metas ...
{service}: {Service}BlockMeta,
}apps/sim/triggers/registry.ts) - If triggers exist// Add import (alphabetically)
import {
{service}EventATrigger,
{service}EventBTrigger,
{service}WebhookTrigger,
} from '@/triggers/{service}'
// Add to TRIGGER_REGISTRY (alphabetically)
export const TRIGGER_REGISTRY: TriggerRegistry = {
// ... existing triggers ...
{service}_event_a: {service}EventATrigger,
{service}_event_b: {service}EventBTrigger,
{service}_webhook: {service}WebhookTrigger,
}Do this for every visible OAuth integration. API-key and unauthenticated integrations do not need an OAuth client capability.
The block's oauth-input.serviceId is the canonical link between the generated integration catalog,
the OAuth service configuration, deployment availability, and the setup CLI.
serviceId and that it matches the canonical
service entry in apps/sim/lib/oauth/oauth.ts.resolveOAuthClientCapabilityId(serviceId) resolves to the intended provider entry in
OAUTH_CLIENT_CAPABILITIES in packages/deployment-config/src/env-capabilities.ts. Google and
Microsoft service IDs deliberately share provider-level capabilities.OAUTH_CLIENT_CAPABILITIES, add
every referenced field to the env schema in apps/sim/lib/core/config/env.ts, and add the
matching text or secret entries to OAUTH_CLIENT_SETUP_FIELDS in
packages/sim-setup/src/capability-config.ts. Do not create integration-specific setup logic or
infer secret fields from naming; the CLI mapping is exhaustively checked against the runtime
fields.serviceAccountProviderId, run
bun run deployment-config:generate to refresh
packages/deployment-config/src/service-account-providers.generated.ts; never hand-edit the
generated provider-ID map. In packages/deployment-config/src/service-account-metadata.ts, use:deploymentRequirement when the service-account path works independently of OAuth client fields;'oauth-client' when it requires the same deployment OAuth client fields;'preview-gated' when availability is controlled by the service-account preview block.Never add a permissive fallback for missing capability metadata. A visible OAuth integration without a resolvable capability must fail validation.
Run bun run tool-metadata:generate, bun run scripts/generate-docs.ts,
bun run deployment-config:generate, then bun run check:audits (see the validate-integration
skill → Regenerate Derived Artifacts for the full list and what each check verifies).
The docs generator creates apps/docs/content/docs/integrations/{service}.mdx — one page per service carrying the block's Actions and, if it has one, its Triggers section. Never hand-edit generated pages; the only editable region is the {/* MANUAL-CONTENT */} block (see scripts/README.md).
Every generated integration page carries a hand-written intro directly under <BlockInfoCard />. The
generator preserves it across regenerations, so write it once after the first generate:
{/* MANUAL-CONTENT-START:intro */}
[{Service}](https://service.com/) is {one sentence on what the service is}.
With the {Service} block, you can:
- **{Capability}**: {what the operations in this group do}
- **{Capability}**: {...}
{How to connect: which credential to create and where, if it is not OAuth.}
In Sim, the {Service} block lets your agents {concrete workflow uses}.
{/* MANUAL-CONTENT-END */}Group the bullets by what the user gets done, not one bullet per tool. Only describe operations the
block actually ships. Follow .claude/rules/constitution.md for voice. Re-run
bun run scripts/generate-docs.ts afterwards and confirm the section survived unchanged.
The docs generator refreshes packages/deployment-config/src/integrations.json, and the deployment
config generator projects service-account provider IDs from that catalog plus the canonical OAuth
registry. The checks compare both committed projections with their sources. Review the generated
diff and keep only intentional changes.
If creating V2 versions (API-aligned outputs):
V2 Tools - Add _v2 suffix, version 2.0.0, flat outputs
V2 Block - Add _v2 type, use createVersionedToolSelector
V1 Block - Add (Legacy) to name, set hideFromToolbar: true, and add
sunset: { status: 'legacy', replacedBy: '{service}_v2' } — check-block-registry
fails a legacy block with no replacedBy, and the amber legacy badge plus its
click-to-upgrade action read from that field.
Only add replacedBy once the target is GA. The same check also fails when
the target is unregistered, itself sunset, or still preview: true. If v2 is
preview-gated, leave v1 alone until GA and drop preview in the same commit
that adds the sunset — splitting them breaks the build in between.
Registry - Register both versions
// In registry
{service}: {Service}Block, // V1 (legacy, hidden)
{service}_v2: {Service}V2Block, // V2 (visible)tools/{service}/ directorytypes.ts with all interfacesInternalToolConfig.operation or absolute
external HTTP(S) ToolConfig.request/api/..., constructs a URL back to Sim, declares request.internal or a
directExecution property (fails bun run check:tool-request-boundary), or has an HTTP fallback for an in-process operation?? nulloptional: trueindex.ts barrel exporttools/registry.tsbun run tool-metadata:generate and committed the regenerated artifactsbun run check:tool-request-boundary passesblocks/blocks/{service}.tsintegrationType to the correct IntegrationType enum value{Service}BlockMeta.tags lists every applicable IntegrationTag (tags live on the meta, not the block)requiredScopes: getScopesForService('{service}')short-input, long-input, code, and selector subBlock has a placeholderselectorKey exists in the shared manifest and has one server attachment with
trusted credential provider binding and a fixed, credential-bound, or explicitly reviewed
user-controlled destination policyblocks/registry-maps.ts (BLOCK_REGISTRY / BLOCK_META_REGISTRY)triggers.enabled and triggers.availablegetTrigger(){Service}BlockMeta with at least 7 templatescanvasPresentation.sentences covers every operation; bun run apps/sim/scripts/check-canvas-sentences.ts --block={service} passes{Service}BlockMeta also sets url (verified external homepage) and skills (grounded in tools.access, sourced from real use cases) — see add-block → BlockMetalib/oauth/oauth.ts under OAUTH_PROVIDERSSCOPE_DESCRIPTIONS within lib/oauth/utils.tsgetCanonicalScopesForProvider() in lib/auth/connectors/providers.ts (never hardcode)getScopesForService() in block requiredScopes (never hardcode)oauth-input.serviceIdresolveOAuthClientCapabilityId(serviceId) resolves to the intended OAUTH_CLIENT_CAPABILITIES entryapps/sim/lib/core/config/env.tsOAUTH_CLIENT_CAPABILITIES; matching CLI input modes live in the exhaustively checked OAUTH_CLIENT_SETUP_FIELDSserviceAccountProviderId is configured, SERVICE_ACCOUNT_METADATA_BY_OAUTH_SERVICE_ID has the matching projection and deployment requirementcomponents/icons.tsxfill='currentColor' (not hardcoded white/black) so the icon renders bare in light AND dark mode — verified with bun run check:bare-iconstriggers/{service}/ directoryutils.ts with options, instructions, and extra fields helpersincludeDropdown: trueincludeDropdownbuildTriggerSubBlocks helperindex.ts barrel exporttriggers/registry.tsbun run scripts/generate-docs.tsbun run deployment-config:generate for OAuth or service-account changes{/* MANUAL-CONTENT-START:intro */} section under <BlockInfoCard /> and confirmed it survives a regeneratepackages/deployment-config/src/integrations.json changebun run integration-catalog:check passesbun run docs:check passes — CI fails on stale generated docs, so commit the full generator
output, including catch-up regeneration for pages another PR left stale (never revert it as
"unrelated drift")bun run deployment-config:check passestools.config.params correctly maps and coerces all param typestransformResponse path against documented or live-verified JSON responses{Service}BlockMeta exported with at least 7 templates, each having icon, title, prompt, modules, category, and tagsWhen your integration handles file uploads or downloads, follow these patterns to work with UserFile objects consistently.
UserFile (apps/sim/executor/types.ts) is the standard file representation in Sim — id, name, an access url (not guaranteed presigned — remoteUrl is the short-lived signed one, set only for providers that fetch by URL), size, MIME type, storage key, and optional inline base64 / provider file handles. Read file bytes through the documented upload helpers, never by fetching url directly. Read the interface rather than relying on a copy here.
File authorization, normalization, storage reads, provider upload, and response mapping belong in a registered in-process operation. Do not create an internal API route for file tools.
Use the basic/advanced mode pattern:
// Basic mode: File upload UI
{
id: 'uploadFile',
title: 'File',
type: 'file-upload',
canonicalParamId: 'file', // Maps to 'file' param
placeholder: 'Upload file',
mode: 'basic',
multiple: false,
required: true,
condition: { field: 'operation', value: 'upload' },
},
// Advanced mode: Reference from previous block
{
id: 'fileRef',
title: 'File',
type: 'short-input',
canonicalParamId: 'file', // Same canonical param
placeholder: 'Reference file (e.g., {{file_block.output}})',
mode: 'advanced',
required: true,
condition: { field: 'operation', value: 'upload' },
},Critical: canonicalParamId must NOT match the id of a subblock outside its canonical group.
tools.config.tool selects the tool before variable resolution and must not mutate or coerce input.
Use tools.config.params, which runs after variable resolution, to normalize all file variants:
import { normalizeFileInput } from '@/blocks/utils'
tools: {
config: {
tool: (params) => `{service}_${params.operation}`,
params: (params) => {
// Serialization collapses the basic/advanced pair into the canonical `file` key.
const normalizedFile = normalizeFileInput(params.file, { single: true })
return normalizedFile ? { file: normalizedFile } : {}
},
},
}export const {service}UploadTool: InternalToolConfig<Params, Response> = {
id: '{service}_upload',
// ...
params: {
file: { type: 'file', required: false, visibility: 'user-or-llm' },
},
operation: {
input: (params) => ({
accessToken: params.accessToken,
file: params.file,
}),
},
}Implement apps/sim/lib/internal/{service}/execute-tool.ts and keep the file/provider work in typed
operations beside it. The handler validates request.input, derives storage authority only from
trusted request.context, authorizes every stored file before reading bytes, forwards
request.signal, enforces declared and actual byte caps, and returns the canonical tool response.
Register {service}_upload in apps/sim/lib/internal/tool-operations/registry.server.ts; the
sweep in apps/sim/tools/request-transport.test.ts fails a forgotten registration
(registry.server.test.ts checks registered ids are canonical with loadable handlers). For anything more, run the
test-audit gate. There is no HTTP fallback.
Declare a file / file[] output on the tool. For a raw binary endpoint, set
request.responseType: 'binary' and return output.file = { name, mimeType, data: buffer, size }
from transformResponse(response, params?, context?). The executor's FileToolProcessor stores it
and replaces it with a UserFile; tools never call it.
In an operation handler, return createInternalToolFileResult / createInternalToolFilesResult
from lib/internal/tool-operations/file-result.ts — never base64 JSON. See the add-tools skill →
File Downloads and Generated Files.
| Helper | Location | Purpose |
|---|---|---|
normalizeFileInput | @/blocks/utils | Normalize file params in block config |
processFilesToUserFiles | @/lib/uploads/utils/file-utils | Convert raw inputs to UserFile[] |
downloadFileFromStorage | @/lib/uploads/utils/file-utils.server | Get file Buffer from UserFile |
FileToolProcessor | @/executor/utils/file-tool-processor | Executor-side; stores declared file outputs (not called by tools) |
isUserFile | @/lib/core/utils/user-file | Type guard for UserFile objects |
FileInputSchema | @/lib/uploads/utils/file-schemas | Zod schema for file validation |
Optional fields that are rarely used should be set to mode: 'advanced' so they don't clutter the basic UI. Examples: pagination tokens, time range filters, sort order, max results, reply settings.
Use wandConfig for fields that are hard to fill out manually:
generationType: 'timestamp' to inject current date context into the AI promptgenerationType: 'json-object' for structured data{
id: 'startTime',
title: 'Start Time',
type: 'short-input',
mode: 'advanced',
wandConfig: {
enabled: true,
prompt: 'Generate an ISO 8601 timestamp. Return ONLY the timestamp string.',
generationType: 'timestamp',
},
}Scopes are maintained in a single source of truth and reused everywhere:
lib/oauth/oauth.ts under OAUTH_PROVIDERS[provider].services[service].scopesSCOPE_DESCRIPTIONS within lib/oauth/utils.ts for the OAuth modal UIlib/auth/connectors/providers.ts (buildConnectorProviders) using getCanonicalScopesForProvider(providerId) from @/lib/oauth/utilsgetScopesForService(serviceId) from @/lib/oauth/utilsNever hardcode scope arrays in the Better Auth connector providers or block requiredScopes. Always import from the centralized source.
// In lib/auth/connectors/providers.ts (Better Auth connector providers)
scopes: getCanonicalScopesForProvider('{service}'),
// In block credential sub-block
requiredScopes: getScopesForService('{service}'),serviceId in oauth-input must match the OAuth provider configurationnew Uint8Array(buffer) for TypeScript compatibilityfileContent params - Only an existing tool that already accepted base64 fileContent keeps that hidden param; new tools take file only© 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
SKILL.md and 1 other file in .agents/skills/add-integration of simstudioai/sim.
Open the folder on GitHubat commit 546d4e7
Add 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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Add Integration this skillsimstudioai/sim | 30k | — | ~7.5k | Automated safety check: Pass | Apache-2.0 | |
| Meilisearch PHP PHPDoc Writermeilisearch/meilisearch-php | 757 | — | ~569 | Automated safety check: Pass | MIT | |
| DDNS Provider DevelopmentNewFuture/DDNS | 4.7k | — | ~558 | Automated safety check: Pass | MIT | |
| Human Writingkataras/jwt | 212 | — | ~1.9k | Automated safety check: Pass | MIT | |
| API Generatinghuangjia2019/claude-code-engineering | 1.1k | 1 repos | ~426 | Automated safety check: Pass | None | |
| Nacos API Doc Updatenacos-group/nacos-group.github.io | 115 | — | ~3.3k | Automated safety check: Pass | Apache-2.0 |
meilisearch/meilisearch-php
Documents public methods of the meilisearch-php SDK with compact PHPDoc, including @see links, @since tags and the experimental-feature notice.
NewFuture/DDNS
Adds or changes a DNS provider in the DDNS project while keeping its code, schemas, tests and Chinese and English docs consistent.
kataras/jwt
A skill your agent uses when writing or editing any prose in this repository - the book's preface, its chapters and epilogue, the brand kit notes, the agent skill documents, the changelog, and the…
huangjia2019/claude-code-engineering
Generate API endpoint documentation from Express route files.
nacos-group/nacos-group.github.io
Updates Nacos API documentation from Swagger api.json. An agent skill from nacos-group/nacos-group.github.io.
ethereum-optimism/superchain-ops
Mark one or more superchain-ops tasks as EXECUTED by updating each task README's Status line to link the on-chain execution transaction, then open a PR.
simstudioai/sim
Install, upgrade, and operate the Sim Helm chart on Kubernetes.
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.
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.
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.
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…
simstudioai/sim
Add or update a Sim dynamic selector using the shared manifest, server attachment, and selectors.execute path.
Categories
Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions. Add Integration is an agent skill from simstudioai/sim. Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions.
Add Integration fits situations like: introducing a new service under apps/sim/tools; apps/sim/blocks; apps/sim/triggers.
Run `npx skills add simstudioai/sim --skill add-integration -a claude-code`. Or copy the skill folder (.agents/skills/add-integration in simstudioai/sim) into .claude/skills/add-integration in your project. Claude Code loads it when a task matches its description.
Run `npx skills add simstudioai/sim --skill add-integration -a codex`. Or copy the skill folder (.agents/skills/add-integration in simstudioai/sim) into .agents/skills/add-integration in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add simstudioai/sim --skill add-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/add-integration, .gemini/skills/add-integration, .github/skills/add-integration and .opencode/skills/add-integration in your project.
Going by SKILL.md and its folder, Add Integration needs the command-line tools its instructions call (bun).
SKILL.md names 2 domains. In commands or code: w3.org and service.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
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.
Add 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.
About 7.5k tokens (SKILL.md is roughly 30k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Add Integration: Meilisearch PHP PHPDoc Writer (meilisearch/meilisearch-php, 757 stars), DDNS Provider Development (NewFuture/DDNS, 4.7k stars), Human Writing (kataras/jwt, 212 stars) and API Generating (huangjia2019/claude-code-engineering, 1.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
simstudioai (a GitHub organization) maintains it in simstudioai/sim, which has 29,792 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on October 8, 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.