Stop Calling Skills. Start Calling Tools
You've seen the folder.
~/.agents/skills
One skill for GitHub. One for Gmail. One for browser automation. One for the weird internal workflow you only remember because you wrote a 200-line markdown file explaining it to future-you.
It feels great at first.
Skills are human-readable. They hold the context. They say when to use a thing, what to avoid, what command to run, what prompt to send, what file to read after the command finishes.
Then the folder grows.
Now you have:
- A GitHub skill
- A GitHub PR review skill
- A GitHub CI skill
- A GitHub release skill
- A
ghCLI wrapper - A GitHub MCP server
- A browser workflow that logs into GitHub
- A local script from six months ago that still has a token in it
The problem is not that skills are bad.
The problem is that skills quietly become tool registries.
And markdown is a terrible database.
The Skill Problem
A skill is supposed to answer a workflow question:
"When I want to triage a PR, what process should I follow?"
But it often ends up answering an infrastructure question:
"Which exact GitHub API call should I make, with which auth, through which transport, using which schema?"
Those are different jobs.
The first job belongs in a skill.
The second job belongs in a tool catalog.
This gets painful the moment you have duplicates. Personal GitHub and work GitHub. Production Stripe and test Stripe. Gmail through Google Discovery and Gmail through an MCP server. A read-only source and a write-capable source.
"Use the GitHub skill" is not precise enough anymore.
Which GitHub?
Which account?
Which transport?
Which permissions?
Which schema?
Which policy?
You don't feel the ambiguity when you're the one typing. You feel it when an agent is trying to help and it reaches for the friendly name instead of the exact capability.
That's how you get the worst kind of automation bug: the agent did exactly what you asked, but against the wrong surface.
The Executor Shift
Executor changes the center of gravity.
Instead of treating a skill as the thing you call, you treat Executor as the catalog of what exists.
The skill becomes the wrapper around judgment.
Executor owns:
- Sources
- Tools
- Schemas
- Auth
- Policies
- Invocation
- Approval and resume flows
The skill owns:
- When to use the tool
- Which source to prefer
- What safety rules apply
- How to sequence multiple calls
- What evidence to collect
- What to do when the call pauses or fails
That's the mindset shift.
Skills are playbooks.
Executor is the tool bench.
The Old Loop
The old loop looks like this:
- User asks for a GitHub task.
- Agent finds the GitHub skill.
- Agent reads markdown.
- Markdown says to run some command or call some MCP tool.
- Agent hopes the command still works.
This is fine until the command drifts.
The schema changes. The MCP server changes. The token moves. The account changes. The skill still looks confident because markdown always looks confident.
The New Loop
The Executor loop is more explicit:
executor tools sources --query github --limit 20executor tools search "create issue" --namespace github_acme_openapi_prod_rw --limit 10executor tools describe github_acme_openapi_prod_rw.issues.createexecutor call github_acme_openapi_prod_rw issues create '{...}'
Search is discovery.
Describe is verification.
Call is execution.
Resume is approval.
That one sequence fixes a surprising amount of agent confusion.
The agent is no longer trying to infer "GitHub" from a skill name. It is resolving a canonical path:
github_acme_openapi_prod_rw.issues.create
That path says more than "GitHub."
It says account, transport, environment, permission shape, resource, operation.
That is the thing you want an agent to call.
Not a vibe. Not a folder name. The exact tool.
The Pinning Trick
The bridge from skill-world to Executor-world is a tool pin.
Keep the skill. Add exact paths.
## Executor Tool Pins- Source: `github_acme_openapi_prod_rw`- Path: `github_acme_openapi_prod_rw.issues.create`- Verify: `executor tools describe github_acme_openapi_prod_rw.issues.create`- Search fallback: `executor tools search "create issue" --namespace github_acme_openapi_prod_rw --limit 10`- Invoke: `executor call github_acme_openapi_prod_rw issues create '{...}'`- Policy: writes require explicit approval
Now the skill is not pretending to be the implementation.
It is a policy wrapper over a real catalog entry.
The difference feels small. It is not.
It means the skill can say:
"For work repos, use this source."
"For personal repos, ask first."
"For production writes, require approval."
"If the path fails, verify it with describe before searching broader."
That is what skills are good at.
They encode judgment.
They should not be the place where stale tool calls go to hide.
Source Names Matter
The first time you add a source, you'll want to call it github.
Don't.
That name expires the moment you add another GitHub.
Use names that carry the context an agent would otherwise have to guess:
github_acme_openapi_prod_rwgithub_john_openapi_personal_rwgmail_acme_google_work_rostripe_acme_openapi_test_rwlinear_acme_mcp_work_rw
It looks verbose because it is doing work.
github is a brand.
github_acme_openapi_prod_rw is an operational boundary.
An agent can reason about the second one.
It can see "prod." It can see "rw." It can see "acme." It can see "openapi."
Those words are not decoration. They're guardrails.
Search Is Not Permission
Natural-language search is addictive.
executor tools search "send email"
Great for discovery.
Terrible as the final routing step.
In a real catalog, "send email" might return personal Gmail, work Gmail, a CRM, a marketing system, a support desk, Slack DM, or an MCP tool with a suspiciously friendly description.
The rule is:
Search broad when learning.
Search narrow when acting.
executor tools search "send email" --namespace gmail_acme_google_work_rw --limit 5executor tools describe gmail_acme_google_work_rw.messages.send
Then call the exact path.
Never let "first search result wins" become your automation policy.
That is how a convenience feature becomes a footgun.
What Stays in Skills
Some skills should not become tools.
A GitHub PR triage skill is a good example.
It is not just "call GitHub."
It might list open PRs. It might inspect CI. It might read review comments. It might check the diff. It might decide whether the right next step is to reply, patch code, rerun a check, ask the author a question, or do nothing.
Some of those are safe reads.
Some are writes.
Some are public.
Some should require approval.
That is a workflow.
The skill should pin the Executor paths it uses:
## Executor Tool Pins- List PRs: `github_acme_openapi_prod_rw.pulls.list`- Read PR: `github_acme_openapi_prod_rw.pulls.get`- List checks: `github_acme_openapi_prod_rw.checks.listForRef`- List review comments: `github_acme_openapi_prod_rw.pulls.listReviewComments`- Create review comment: `github_acme_openapi_prod_rw.pulls.createReviewComment`- Verify:- `executor tools describe github_acme_openapi_prod_rw.pulls.list`- `executor tools describe github_acme_openapi_prod_rw.pulls.createReviewComment`- Policy:- Reads are allowed.- Public comments require explicit approval.
But the skill still owns the pipeline.
Executor should not replace judgment. It should remove ambiguity from the calls that judgment chooses.
The Migration Pass
The easiest way to convert a skill folder is not to rewrite everything.
Audit it.
For each skill, ask:
- Is this mostly workflow?
- Is this mostly an API wrapper?
- Does it embed auth?
- Does it hide a destructive operation?
- Does it call a provider that Executor can represent?
- Can I pin the exact tool path?
Then classify:
- Keep as skill
- Convert provider call into Executor source/tool
- Keep skill but add Executor pins
- Replace local script with
executor call - Retire because it duplicates the catalog
The goal is not fewer skills.
The goal is cleaner responsibility.
A good migrated skill should be boring at the call site:
executor tools describe exact.source.pathexecutor call exact source path '{...}'
The interesting part should be the policy around it.
The Meta-Pattern
This is not really about Executor.
It's about where you put truth.
Markdown is great for intent.
It is weak for state.
It can tell an agent what matters. It cannot reliably prove which tools exist, what schema they accept, which account they use, or whether a path is stale.
A catalog can.
The pattern works everywhere:
- Put workflow in readable docs.
- Put capability in a typed catalog.
- Put auth in the system that owns sources.
- Put policy on canonical paths.
- Put verification before execution.
The friction you've stopped noticing is that your agents are often calling names, not tools.
"Use the GitHub skill" feels clear because you know what you meant.
The agent does not.
Give it the path.
Let the skill explain why.
The Practical Rule
For every skill, add this section:
## Executor ContractSearch is for discovery.Describe is for verification.Call is for execution.Resume only after approval.Pinned paths:- ...
That's the small config change.
Not a new framework. Not a rewrite. Not a grand migration.
Just stop letting skills pretend to be tools.
Somewhere in your ~/.agents/skills folder is a markdown file that should be a playbook wrapped around a canonical tool path.
You'll know it when you see it.
It's the one with a shell command you don't quite trust anymore.