Agent skill

Tool Registry Boundary

by simstudioai in simstudioai/sim

Keep the executable tool registry out of client-reachable module graphs — when to read @/tools/metadata instead of getTool, how to measure whether an import edge pulls the registry, and how to…

Apache-2.0Auto-check passed

Install Tool Registry Boundary

skills CLI
$ npx skills add simstudioai/sim --skill tool-registry-boundary -a claude-code

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

GitHub CLI
$ gh skill install simstudioai/sim tool-registry-boundary --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/tool-registry-boundary .claude/skills/tool-registry-boundary && 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
tool-registry-boundary
GitHub stars
30k
Token cost
~1.9k tokens
SKILL.md length
968 words
Files
1
Skills in repo
40
Repo updated
First seen
Licence
Apache-2.0

At a glance

Keep the executable tool registry out of client-reachable module graphs — when to read @/tools/metadata instead of getTool, how to measure whether an import edge pulls the registry, and how to…

  • Works in 3 steps: From the entry you care about, follow… → Check whether apps/sim/tools/registry.ts… → Compare the reachable module count…
  • Touching apps/sim/tools/registry.ts
  • SKILL.md covers The rule, Which module to import, The generated artifacts and Testing code that reads tool…, plus 3 more sections
  • Calls bun and tsc

What it does

Tool Registry Boundary is an agent skill from simstudioai/sim. Keep the executable tool registry out of client-reachable module graphs — when to read @/tools/metadata instead of getTool, how to measure whether an import edge pulls the registry, and how to regenerate the metadata artifacts. Use when touching apps/sim/tools/registry.ts, tools/utils.ts, tools/params.ts, or anything that calls getTool.

Its SKILL.md is about 1.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

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

  • Touching apps/sim/tools/registry.ts
  • Tools/params.ts
  • Anything that calls getTool

Example prompts

  • “/tool-registry-boundary”

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. From the entry you care about, follow import and export … from (skipping import type), resolving @/ against apps/sim.
  2. Check whether apps/sim/tools/registry.ts is in the reachable set, and print the parent chain if it is.
  3. Compare the reachable module count before and after.

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
    • tsc

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

  • Network

    No URLs in SKILL.md.

    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

Tool Registry Boundary loads about 1.9k tokens when it runs. Until then it costs about 93 tokens; SKILL.md has 968 words of instructions outside code blocks.

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

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). 968 words, ~1,941 tokens.

Download SKILL.mdSave it as .claude/skills/tool-registry-boundary/SKILL.md (or your agent's skills folder).
name
tool-registry-boundary
description
Keep the executable tool registry out of client-reachable module graphs — when to read `@/tools/metadata` instead of `getTool`, how to measure whether an import edge pulls the registry, and how to regenerate the metadata artifacts. Use when touching `apps/sim/tools/registry.ts`, `tools/utils.ts`, `tools/params.ts`, or anything that calls `getTool`.

Tool Registry Boundary Skill

You keep the 5,000+-tool executable registry out of module graphs that don't execute tools.

The rule

Client-reachable code reads tool metadata. Only code that actually executes a tool imports the registry.

@/tools/registry is a 10,000+-line barrel importing every tool. External ToolConfig entries mix plain data (params, outputs, name) with request/response closures, while InternalToolConfig entries contain semantic input projection and load their server implementation through lib/internal/tool-operations/registry.server.ts. Request closures can still reach SDK clients, API helpers, and parsers, which is what makes the executable barrel expensive: reaching it costs roughly 4,700 additional modules (measured; re-measure with --verbose).

getTool() returns the whole ExecutableToolConfig, so a single getTool import anywhere in a client-reachable file drags all of it in.

Which module to import

you needimportnotes
whether a tool id existshasToolId from @/tools/tool-ids~110 KB — the cheapest module
to resolve an unversioned nameresolveToolId from @/tools/tool-ids
every tool idgetToolIds from @/tools/tool-ids
a tool's paramsgetToolParams / getToolMetadata from @/tools/metadata~4 MB
a tool's declared outputsgetToolOutputsMetadata from @/tools/metadata-outputs~4 MB, separate on purpose
to execute a toolgetTool from @/tools/utils, or getToolAsync from @/tools/utils.server (async/workspace-context lookup)server paths only

Three modules, cheapest first. Ids are their own artifact because resolution and existence checks need only the key set; outputs are their own because they are the larger half of the data with a single consumer. @/tools/metadata and @/tools/metadata-outputs both resolve ids through @/tools/tool-ids, which is what keeps them independent of each other — do not "helpfully" re-export one from another, or every caller pays for all three.

All lookups guard with Object.hasOwn. JSON.parse yields an object with the normal prototype, so a bare bracket lookup returns inherited members: a bare bracket lookup would answer getToolMetadata('constructor') with a function typed as tool metadata.

The generated artifacts

apps/sim/tools/generated/tool-ids.ts, tool-metadata.ts and tool-outputs.ts are produced by scripts/sync-tool-metadata.ts:

bash
bun run tool-metadata:generate   # after adding/changing a tool
bun run tool-metadata:check      # what CI runs; fails if stale

Never hand-edit them. If you add a tool or change a tool's params/outputs, regenerate and commit the result, or CI fails.

Four non-obvious properties, each of which was measured and is easy to undo by accident:

  • The data is a JSON string parsed at runtime, not an imported .json and not an object literal. With resolveJsonModule (which this repo enables), a .json import makes TypeScript infer a literal type for all 5,000+ entries and takes tsc --noEmit from 12.6s to 8m07s — a 38x regression. An ambient declare module does not short-circuit it, and an object literal costs the same. A single string literal is one cheap token for both the compiler and the bundler, and JSON.parse beats evaluating the equivalent literal at runtime. Do not "clean this up" into a .json import.
  • The generator refuses to emit function values. If you add a field to METADATA_FIELDS that contains a closure, generation fails loudly rather than shipping executable config to the client. hosting and schemaEnrichment are excluded for exactly this reason (hosting.enabled, pricing, and enrichSchema are functions) — they are server-only.
  • Empty param entries are stripped. The registry contains one (stt_deepgram_v2), which crashes callers that read param.type while iterating.
  • Lookups resolve versions. getTool maps an unversioned name onto the newest version, and a few hundred tools are versioned. A plain key lookup would silently report them missing — a quiet correctness bug, not a crash. resolveToolId reproduces that against the id set and is differentially tested against the original.
Show full SKILL.md (418 more words)Show less

Testing code that reads tool metadata

Mock the module the code under test actually reads. @/tools/metadata and @/tools/metadata-outputs are mocked globally in apps/sim/vitest.setup.ts and return undefined; never vi.mock them again (check:test-patterns fails a global-remock). Install fixtures on the global mock instead:

ts
import { toolsMetadataMock } from '@sim/testing/mocks/blocks.mock'
import { getToolMetadata } from '@/tools/metadata'

vi.mocked(getToolMetadata).mockImplementation(toolsMetadataMock.getToolMetadata)

Do the same for getToolParams. vi.mock('@/tools/utils', () => toolsUtilsMock) controls only getTool. Both mocks share mockToolConfigs, so together they give one consistent tool universe. If you are unsure whether a mock is load-bearing, change a fixture value to a sentinel and confirm the test fails.

The guard

bun run check:tool-registry-boundary (run in CI by check:audits) walks the module graph from each workspace route and fails if @/tools/registry is reachable, printing the exact import chain that reintroduced it.

If it fails, do not add the entry to an allowlist — there isn't one. Find the symbol the offending file actually needs and move it to a registry-free module (e.g. tools/merge-params.ts).

Run it with --verbose to print per-route module counts, which is also the quickest way to see whether a change moved the graph.

The same command also ratchets those counts against check-tool-registry-boundary.baseline.json. --check (what CI runs) fails when an entry exceeds its baseline by more than max(25 modules, 2%), naming the import chain responsible. The baseline also catches graph growth that never touches @/tools/registry.

Re-record with --update-baseline and commit the JSON when growth is deliberate. A shrink passes but is reported — re-record then too, or the win is silently spendable again.

How to verify an edge actually got cut

Do not eyeball imports — the registry is reached through several redundant paths, so cutting one buys nothing while another survives. Walk the graph:

  1. From the entry you care about, follow import and export … from (skipping import type), resolving @/ against apps/sim.
  2. Check whether apps/sim/tools/registry.ts is in the reachable set, and print the parent chain if it is.
  3. Compare the reachable module count before and after.

A route can reach the registry through several redundant edges; cutting one changes nothing until all are gone, so measure the route, not the file you edited.

When adding a new caller

Ask what the caller does with the config. If it reads params, outputs, name, description or just checks existence, it belongs on @/tools/metadata — no exceptions, even on a path you believe is server-only today, because a future client import will silently re-attach the registry to the graph.

If it genuinely executes — builds an external request, transforms a response, or dispatches a registered internal operation — use getTool, and keep that file off client-reachable paths.

© 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

Just SKILL.md in .agents/skills/tool-registry-boundary of simstudioai/sim.

Open the folder on GitHubat commit 546d4e7

Compare with similar skills

Tool Registry Boundary 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.

Tool Registry Boundary compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Tool Registry Boundary this skillsimstudioai/sim30k—~1.9kAutomated safety check: PassApache-2.0
Executealirezarezvani/claude-skills28k—~831Automated safety check: PassMIT
Debugging Executionsn8n-io/n8n207k—~2.6kAutomated safety check: PassCustom licence
Mas Module BoundaryAUTO-MAS-Project/AUTO-MAS708—~1.6kAutomated safety check: PassAGPL-3.0
Executing Plans Inlineobra/superpowers296k2 repos~5.1kAutomated safety check: PassMIT
Es Modulesthedaviddias/Front-End-Checklist74k—~482Automated safety check: PassMIT

Similar skills

  • Execute

    alirezarezvani/claude-skills

    /cs:execute <decision — Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision.

    28k GitHub stars~831 tokensUpdated 1 mo ago
    Product & Project ManagementAuto-check passed
  • Official

    Debug failed or wrong-output workflow executions using executions tools.

    207k GitHub stars~2.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Mas Module Boundary

    AUTO-MAS-Project/AUTO-MAS

    Define and enforce backend module boundaries for Python services.

    708 GitHub stars~1.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Executing Plans Inline

    obra/superpowers

    Has the agent carry out an implementation plan itself, task by task in the current session, keeping a ledger, proving each step with a test and ending with one whole-branch review.

    296k GitHub starsUsed in 2 repos~5.1k tokens
    Agent WorkflowsAuto-check passed
  • Es Modules

    thedaviddias/Front-End-Checklist

    A skill your agent uses when reviewing scripts, client components, bundles, or runtime behavior related to Use ES modules (import/export).

    74k GitHub stars~482 tokensUpdated yesterday
    Auto-check passed
  • Ulw Execute

    code-yeongyu/oh-my-openagent

    Executes a written ulw-plan work plan with Boulder state, evidence ledger, worktree discipline, and parallel subagents.

    70k GitHub stars~6.3k tokensUpdated today
    Agent WorkflowsAuto-check passed

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

Questions about Tool Registry Boundary

What does Tool Registry Boundary do?

Keep the executable tool registry out of client-reachable module graphs — when to read @/tools/metadata instead of getTool, how to measure whether an import edge pulls the registry, and how to…. Tool Registry Boundary is an agent skill from simstudioai/sim. Keep the executable tool registry out of client-reachable module graphs — when to read @/tools/metadata instead of getTool, how to measure whether an import edge pulls the registry, and how to regenerate the metadata artifacts.

When should I use Tool Registry Boundary?

Tool Registry Boundary fits situations like: touching apps/sim/tools/registry.ts; tools/params.ts; anything that calls getTool.

How do I install Tool Registry Boundary in Claude Code?

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

How do I install Tool Registry Boundary in Codex?

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

Can I use Tool Registry Boundary 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 tool-registry-boundary -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/tool-registry-boundary, .gemini/skills/tool-registry-boundary, .github/skills/tool-registry-boundary and .opencode/skills/tool-registry-boundary in your project.

What does Tool Registry Boundary need to run?

Going by SKILL.md and its folder, Tool Registry Boundary needs the command-line tools its instructions call (bun and tsc).

Does Tool Registry Boundary access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Tool Registry Boundary 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 Tool Registry Boundary use?

Tool Registry Boundary 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 Tool Registry Boundary use?

About 1.9k tokens (SKILL.md is roughly 7.8k 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 Tool Registry Boundary?

Skills that share tags, products or a category with Tool Registry Boundary: Execute (alirezarezvani/claude-skills, 28k stars), Debugging Executions (n8n-io/n8n, 207k stars), Mas Module Boundary (AUTO-MAS-Project/AUTO-MAS, 708 stars) and Executing Plans Inline (obra/superpowers, 296k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Tool Registry Boundary?

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.