An agent asked to add a resource to your package will guess at the toolkit's API, and a guess is
drawn from whatever release happened to be in its training data. The toolkit therefore ships its own
documentation for agents, inside the package, so what the agent reads is the version in your
composer.lock.
One command wires up all of it:
vendor/bin/package-toolkit-ai install
Wiring agent support into /home/you/packages/blog-engine ✓ appended a block to AGENTS.md ✓ created .claude/skills/laravel-package-toolkit/SKILL.md ✓ registered the server in .mcp.json
It is idempotent — run it again and it rewrites what changed and reports the rest as unchanged.
status shows what is wired up, remove takes it back out, and --dry-run prints the changes
without writing them.
Nothing is required
Each of the three works on its own. Skip any of them with --no-guide / --no-skill / --no-mcp,
or write your own AGENTS.md pointing at the guide by hand — the file is just sitting in vendor/.
Keeping it current
Most of it keeps itself current. The AGENTS.md block and the .mcp.json entry hold paths into
vendor/, not copies of anything — so composer update replaces the guide and the MCP server where
they stand, and the next agent to read either one reads the new release. That is the whole reason
the guide ships inside the package instead of being copied into your repository.
Two things are real copies and do go stale: the skill file, and the prose of the managed block.
update rewrites them:
vendor/bin/package-toolkit-ai update
It differs from install in one way that matters: it refreshes what is already wired up and
nothing else. A project that installed with --no-mcp, or that deleted the skill on purpose, does
not silently get either one back at the next upgrade — and one that never installed anything gets
nothing, with a note and a zero exit code rather than an error.
That is what makes it safe to run unattended, which is where it belongs — in the package's own
composer.json:
{ "scripts": { "post-update-cmd": [ "@php vendor/bin/package-toolkit-ai update" ] }}
Composer runs post-update-cmd after composer update, so the skill is rewritten in the same
command that brought in the release it describes. It prints two lines and writes nothing when there
is nothing to write. Drop the line if you ever drop the toolkit — Composer fails the event when the
binary it names is gone.
What gets installed
The guide, referenced from AGENTS.md
AGENTS.md is the convention most coding agents read — Claude Code, Cursor, Codex, Copilot,
Windsurf and Zed among them. The installer adds a delimited block to yours (creating the file if
you have none) that points at the reference shipped in the package:
<!-- laravel-package-toolkit:start -->## Building this package with laravel-package-toolkit…[vendor/nyoncode/laravel-package-toolkit/ai/AGENTS.md](vendor/nyoncode/laravel-package-toolkit/ai/AGENTS.md)<!-- laravel-package-toolkit:end -->
The markers are what make the block safe: an upgrade rewrites only what is between them, remove
deletes only that, and everything you wrote around it is left alone.
That guide is the complete public API in one file — every builder, which resources load versus publish versus both, how paths resolve against the provider file, the publish-tag format, and the failures that are silent rather than loud.
A Claude Code skill
.claude/skills/laravel-package-toolkit/SKILL.md. A skill loads when the work calls for it rather
than on every turn, so the detail is there while an agent is writing a configure() body and out of
the way the rest of the time.
An MCP server
.mcp.json gains a laravel-package-toolkit entry running ai/mcp/server.mjs. It needs Node 18+
and has no dependencies of its own — the MCP stdio protocol is small enough that the server
implements it directly rather than vendoring an SDK inside vendor/.
Five tools:
| Tool | Answers |
|---|---|
search_docs |
"How do I…" — returns the matching documentation sections in full |
list_docs |
Every page available to get_doc |
get_doc |
One page, whole; get_doc("agent-guide") is the complete API in one read |
list_api |
Public methods, grouped by Packager / PackageServiceProvider / InstallCommand |
describe_api |
One method's exact signature, docblock and file:line |
list_api and describe_api parse the installed src/, so they describe the release you have
rather than the release the model remembers. Check it works with:
node vendor/nyoncode/laravel-package-toolkit/ai/mcp/server.mjs --self-test
Reading the documentation directly
The site publishes itself in machine-readable form as well, for an agent with web access and no toolkit installed yet:
| URL | What |
|---|---|
/llms.txt |
Index — every page as a link with its one-line description |
/llms-full.txt |
Every page concatenated, ~220 KB |
<page-url>.md |
The raw Markdown of any page — /assets.md, /publishing.md |
Every HTML page links its own Markdown twin from <head> as
<link rel="alternate" type="text/markdown">, and links inside the Markdown are absolute and point
at other .md files, so following one keeps you in Markdown.
Shipping agent support in your own package
Nothing here is toolkit-specific machinery you can reuse directly, but the shape transfers: put a
single Markdown file describing your package's API somewhere inside the published package, and
reference it from the consuming project's AGENTS.md rather than copying it. A copy goes stale at
the next release; a reference into vendor/ cannot.
If your package publishes stubs or generators an agent would otherwise have to guess at,
hasStubs() puts them somewhere it can read them.