agent-plugins 0.1.1__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/.agent-plugin/plugin.json +1 -0
- agent_plugins-0.2.0/.agent-plugin/skills/agent-plugins/SKILL.md +250 -0
- agent_plugins-0.2.0/PKG-INFO +206 -0
- agent_plugins-0.2.0/README.md +185 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/pyproject.toml +3 -1
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/pyproject.toml.orig +3 -1
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/__init__.py +6 -1
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_build/backend.py +3 -3
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_build/plan.py +9 -4
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_build/sdist.py +2 -0
- agent_plugins-0.2.0/src/agent_plugins/_build/wheel.py +541 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_cli.py +61 -2
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_files.py +69 -13
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_plugin.py +55 -6
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/__init__.py +2 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/json.py +1 -1
- agent_plugins-0.2.0/src/agent_plugins/_schema/mcp.py +283 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/models.py +15 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/skill.py +8 -1
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/v1/mcp.py +14 -4
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_skill.py +10 -1
- agent_plugins-0.1.1/.agent-plugin/skills/agent-plugins/SKILL.md +0 -195
- agent_plugins-0.1.1/PKG-INFO +0 -224
- agent_plugins-0.1.1/README.md +0 -205
- agent_plugins-0.1.1/src/agent_plugins/_build/wheel.py +0 -187
- agent_plugins-0.1.1/src/agent_plugins/_schema/mcp.py +0 -101
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/.agent-plugin/skills/agent-plugins/agents/openai.yaml +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/LICENSE +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/__main__.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_build/__init__.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_discovery.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_errors.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_marker.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/errors.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/lazy.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/manifest.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/v1/__init__.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_schema/v1/manifest.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/_tree.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/build/__init__.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/build/hatchling.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/build/uv_build.py +0 -0
- {agent_plugins-0.1.1 → agent_plugins-0.2.0}/src/agent_plugins/py.typed +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-plugins
|
|
3
|
+
description: Ship and inspect Agent Skills, MCP server configuration, and client extension files with a Python distribution. Use when adding an Agent Plugin to a Python project, attaching a prebuilt wheel, loading the exact project or installed selection, selecting a named skill, reading checked skill resources, resolving a stdio MCP launch, or verifying package artifacts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Plugins
|
|
7
|
+
|
|
8
|
+
Use `agent-plugins` when a Python distribution should carry the instructions and MCP
|
|
9
|
+
configuration that match its installed code version.
|
|
10
|
+
|
|
11
|
+
An [Agent Plugin](https://agent-plugins.org/) is an open, vendor-neutral
|
|
12
|
+
portable directory format for reusable agent components. Its fixed locations
|
|
13
|
+
let compatible clients find [Agent Skills](https://agentskills.io/specification)
|
|
14
|
+
and [Model Context Protocol (MCP)](https://modelcontextprotocol.io/specification)
|
|
15
|
+
server configuration in the same package. Distribution, permissions, and user
|
|
16
|
+
experience remain with each client.
|
|
17
|
+
|
|
18
|
+
## Build the plugin directory
|
|
19
|
+
|
|
20
|
+
Keep one Agent Plugin directory in the codebase:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
my-plugin/
|
|
24
|
+
├── plugin.json
|
|
25
|
+
├── skills/
|
|
26
|
+
│ └── use-my-package/
|
|
27
|
+
│ ├── SKILL.md
|
|
28
|
+
│ ├── scripts/
|
|
29
|
+
│ └── references/
|
|
30
|
+
├── mcp.json
|
|
31
|
+
└── com.example.client/
|
|
32
|
+
└── hooks/
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- `plugin.json` identifies the plugin and its Agent Plugins schema.
|
|
36
|
+
- `skills/` contains Agent Skills and their nested files.
|
|
37
|
+
- `mcp.json` describes stdio, Streamable HTTP, or legacy HTTP+SSE servers.
|
|
38
|
+
- Reverse-domain directories contain client extension files.
|
|
39
|
+
|
|
40
|
+
Create a minimal `plugin.json` at the plugin root:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
45
|
+
"name": "my-project"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Find the Python project's `pyproject.toml` and set
|
|
50
|
+
`[tool.agent-plugins].root` to the authored plugin root. Prefer a path relative
|
|
51
|
+
to `pyproject.toml`. For uv_build:
|
|
52
|
+
|
|
53
|
+
```toml
|
|
54
|
+
[build-system]
|
|
55
|
+
requires = ["agent-plugins", "uv_build"]
|
|
56
|
+
build-backend = "agent_plugins.build.uv_build"
|
|
57
|
+
|
|
58
|
+
[tool.agent-plugins]
|
|
59
|
+
root = "../.."
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For Hatchling:
|
|
63
|
+
|
|
64
|
+
```toml
|
|
65
|
+
[build-system]
|
|
66
|
+
requires = ["agent-plugins", "hatchling"]
|
|
67
|
+
build-backend = "agent_plugins.build.hatchling"
|
|
68
|
+
|
|
69
|
+
[tool.agent-plugins]
|
|
70
|
+
root = "../.."
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The build selects `plugin.json`, the complete `skills/` tree, and `mcp.json`
|
|
74
|
+
when present. Select other root-relative files explicitly:
|
|
75
|
+
|
|
76
|
+
```toml
|
|
77
|
+
[tool.agent-plugins]
|
|
78
|
+
root = "../.."
|
|
79
|
+
include = ["bin/**", "com.example.client/**"]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Every include pattern must stay within the plugin root and match at least one
|
|
83
|
+
filesystem entry. A matched directory contributes its regular files.
|
|
84
|
+
|
|
85
|
+
Use `attach_wheel()` when another build system already produced the wheel. It rewrites the input after the complete attached artifact succeeds. Pass `output_dir` to preserve the source.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import agent_plugins as ap
|
|
89
|
+
|
|
90
|
+
result = ap.attach_wheel(
|
|
91
|
+
"dist/my_package-1.0.0-py3-none-any.whl",
|
|
92
|
+
project="packages/python",
|
|
93
|
+
)
|
|
94
|
+
print(result.output)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The CLI exposes the same operation:
|
|
98
|
+
|
|
99
|
+
```console
|
|
100
|
+
agent-plugins attach-wheel dist/my_package-1.0.0-py3-none-any.whl \
|
|
101
|
+
--project packages/python
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Reuse a previously computed plan by passing it directly:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from pathlib import Path
|
|
108
|
+
|
|
109
|
+
plan = ap.build_plan("packages/python")
|
|
110
|
+
Path("dist/attached").mkdir(parents=True, exist_ok=True)
|
|
111
|
+
result = ap.attach_wheel(
|
|
112
|
+
"dist/my_package-1.0.0-py3-none-any.whl",
|
|
113
|
+
plan=plan,
|
|
114
|
+
output_dir="dist/attached",
|
|
115
|
+
)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The output directory receives the same filename. Inspect `result.replaced_existing_plugin` and `result.removed_signatures`. The CLI writes removed-signature warnings to stderr.
|
|
119
|
+
|
|
120
|
+
`agent_plugins.build.BuildBackend` provides the wheel, source distribution, and
|
|
121
|
+
editable hooks used by the bundled adapters. A custom delegate must also expose
|
|
122
|
+
the three corresponding `get_requires_for_build_*` hooks.
|
|
123
|
+
|
|
124
|
+
## Choose build-time or runtime access
|
|
125
|
+
|
|
126
|
+
Keeping `agent-plugins` in `[build-system].requires` makes it available during
|
|
127
|
+
the build. Add the package to `[project].dependencies` when installed Python
|
|
128
|
+
code needs to locate or inspect Agent Plugins:
|
|
129
|
+
|
|
130
|
+
```toml
|
|
131
|
+
[project]
|
|
132
|
+
dependencies = ["agent-plugins"]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Load the exact project selection before building. After installing a build from that selection, locate it with the Python distribution name used by pip:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
import agent_plugins as ap
|
|
139
|
+
|
|
140
|
+
source = ap.Plugin.from_project("packages/python")
|
|
141
|
+
plugin = ap.locate("my-package")
|
|
142
|
+
skill = source.skill("use-my-package")
|
|
143
|
+
|
|
144
|
+
print(source.path)
|
|
145
|
+
print(plugin.path)
|
|
146
|
+
print(plugin.manifest.path)
|
|
147
|
+
print(plugin.manifest.name)
|
|
148
|
+
print(skill.source)
|
|
149
|
+
print(skill.file("SKILL.md"))
|
|
150
|
+
|
|
151
|
+
if mcp := plugin.mcp:
|
|
152
|
+
for name, server in mcp.servers.items():
|
|
153
|
+
print(name, server)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`Plugin.from_project()` uses the build plan, so its files match the source
|
|
157
|
+
paths selected for packaging. `plugin.path` is the absolute installed plugin
|
|
158
|
+
root. Each item in
|
|
159
|
+
`plugin.skills` is an `ap.Skill` rooted at one immediate directory under
|
|
160
|
+
`skills/`. Use `plugin.skill(name)` for exact structural lookup. Use
|
|
161
|
+
`Path(skill)` or `skill.path` for that directory. Use `skill.file()` for a
|
|
162
|
+
selected instruction, reference, script, or asset:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
print(skill.file("SKILL.md"))
|
|
166
|
+
print(skill.file("references/api.md"))
|
|
167
|
+
print(skill.tree(max_depth=2))
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`skill.source` returns the complete `SKILL.md` text. Use `skill.frontmatter`
|
|
171
|
+
for the raw source text between the `---` delimiters and `skill.body` for the
|
|
172
|
+
Markdown after the frontmatter. The package checks UTF-8 text and delimiter
|
|
173
|
+
structure. It does not parse the frontmatter as YAML. The first access to any
|
|
174
|
+
source property reads and splits `SKILL.md`, then caches all three strings. Path
|
|
175
|
+
and tree access leave the document unread so an agent can choose which files
|
|
176
|
+
and content to load.
|
|
177
|
+
|
|
178
|
+
`plugin.manifest` is an `ap.Manifest`. `plugin.mcp` is an `ap.MCPConfig` when
|
|
179
|
+
`mcp.json` exists. Each object exposes `.path` immediately. Accessing a parsed
|
|
180
|
+
field such as `manifest.name` or `mcp.servers` reads, validates, and caches its
|
|
181
|
+
document. MCP access validates the manifest first.
|
|
182
|
+
|
|
183
|
+
MCP servers are frozen `ap.StdioServer`, `ap.StreamableHTTPServer`, or
|
|
184
|
+
`ap.SSEServer` values in a read-only mapping. `manifest.issues` records
|
|
185
|
+
non-fatal manifest violations. `mcp.issues` records invalid server entries
|
|
186
|
+
skipped during loading. Document-level failures raise `ap.ValidationError` on
|
|
187
|
+
parsed value access.
|
|
188
|
+
|
|
189
|
+
Resolve a validated stdio server after the client creates its plugin data directory:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from pathlib import Path
|
|
193
|
+
import os
|
|
194
|
+
|
|
195
|
+
data_dir = Path(".agent-data/my-package").resolve()
|
|
196
|
+
data_dir.mkdir(parents=True, exist_ok=True)
|
|
197
|
+
|
|
198
|
+
mcp = plugin.mcp
|
|
199
|
+
if mcp is not None:
|
|
200
|
+
launch = mcp.resolve_stdio(
|
|
201
|
+
"my-package",
|
|
202
|
+
data_dir=data_dir,
|
|
203
|
+
base_env={"PATH": os.environ.get("PATH", "")},
|
|
204
|
+
)
|
|
205
|
+
print(launch.command, launch.args, launch.cwd)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The client owns data retention, process creation, permissions, logging, and the MCP lifecycle. `resolve_stdio()` returns immutable subprocess inputs and performs one-pass Agent Plugins placeholder expansion.
|
|
209
|
+
|
|
210
|
+
Display the plugin to inspect its selected directory tree:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
print(plugin)
|
|
214
|
+
print(plugin.tree(max_depth=2))
|
|
215
|
+
print(plugin.tree(max_depth=None, max_files=None))
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
`Path(plugin)`, `Path(skill)`, and `Path(plugin.manifest)` use the native path
|
|
219
|
+
protocol. When `plugin.mcp` is present, `Path(plugin.mcp)` does too.
|
|
220
|
+
`ap.installed()` returns each discovered plugin keyed by Python distribution
|
|
221
|
+
name. Discovery is fail-fast when a marked distribution has unusable metadata
|
|
222
|
+
or selected files.
|
|
223
|
+
|
|
224
|
+
## Verify the package
|
|
225
|
+
|
|
226
|
+
Inspect the selected paths before building:
|
|
227
|
+
|
|
228
|
+
```console
|
|
229
|
+
agent-plugins plan path/to/python-project
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Then verify the package through its installation boundaries:
|
|
233
|
+
|
|
234
|
+
1. Build a wheel and source distribution through an adapter, or attach the Agent Plugin after an external wheel build.
|
|
235
|
+
2. Build a wheel from the source distribution.
|
|
236
|
+
3. Install the wheel in a clean environment.
|
|
237
|
+
4. Install the Python project as editable.
|
|
238
|
+
5. Compare `Plugin.from_project()` with `ap.locate()` by plugin-relative file inventory and public component values.
|
|
239
|
+
6. Access `plugin.manifest.name` and `plugin.mcp.servers` when MCP exists to run
|
|
240
|
+
the supported Agent Plugins JSON validation.
|
|
241
|
+
7. Confirm each `skill.path`, `skill.file("SKILL.md")`, and `skill.files` points to
|
|
242
|
+
the packaged skill tree.
|
|
243
|
+
8. Access `skill.source`, `skill.frontmatter`, and `skill.body` to verify UTF-8 text and the
|
|
244
|
+
packaged `SKILL.md` delimiter structure.
|
|
245
|
+
9. Run an Agent Skills validator to check frontmatter fields and other Agent
|
|
246
|
+
Skills rules.
|
|
247
|
+
|
|
248
|
+
Handle `ap.AgentPluginError` when a requested Python distribution or usable plugin
|
|
249
|
+
root is absent. Handle `ap.ValidationError` when an installed plugin document
|
|
250
|
+
or `SKILL.md` structure is invalid.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-plugins
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Ship Agent Plugins with Python packages and inspect their installed files
|
|
5
|
+
Author: Péter Ferenc Gyarmati
|
|
6
|
+
Author-email: Péter Ferenc Gyarmati <dev.petergy@gmail.com>
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Classifier: Typing :: Typed
|
|
15
|
+
Requires-Dist: tomli==2.3.1 ; python_full_version < '3.11'
|
|
16
|
+
Requires-Python: >=3.10, <3.15
|
|
17
|
+
Project-URL: Documentation, https://peter-gy.github.io/agent-plugins/
|
|
18
|
+
Project-URL: Issues, https://github.com/peter-gy/agent-plugins/issues
|
|
19
|
+
Project-URL: Source, https://github.com/peter-gy/agent-plugins
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<picture>
|
|
24
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-lockup-horizontal-dark.svg">
|
|
25
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-lockup-horizontal-light.svg">
|
|
26
|
+
<img alt="agent-plugins" src="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-lockup-horizontal-light.svg" width="430">
|
|
27
|
+
</picture>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
Ship Agent Plugins with Python packages.
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<a href="https://peter-gy.github.io/agent-plugins/"><strong>Documentation</strong></a> ·
|
|
36
|
+
<a href="https://pypi.org/project/agent-plugins/"><strong>PyPI</strong></a> ·
|
|
37
|
+
<a href="https://agent-plugins.org/"><strong>Agent Plugins format</strong></a>
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
<a href="https://pypi.org/project/agent-plugins/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/agent-plugins"></a>
|
|
42
|
+
<a href="https://pypi.org/project/agent-plugins/"><img alt="Supported Python versions" src="https://img.shields.io/pypi/pyversions/agent-plugins"></a>
|
|
43
|
+
<a href="https://github.com/peter-gy/agent-plugins/actions/workflows/ci.yml"><img alt="CI status" src="https://github.com/peter-gy/agent-plugins/actions/workflows/ci.yml/badge.svg"></a>
|
|
44
|
+
<a href="https://github.com/peter-gy/agent-plugins/blob/main/LICENSE"><img alt="Apache-2.0 license" src="https://img.shields.io/pypi/l/agent-plugins"></a>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
[Agent Plugins](https://agent-plugins.org/) gives reusable [Agent Skills](https://agentskills.io/specification) and [Model Context Protocol (MCP)](https://modelcontextprotocol.io/specification) servers one package structure that compatible clients can discover consistently. A `plugin.json` manifest identifies the format, fixed locations expose its portable components, and namespaced [client extensions](https://peter-gy.github.io/agent-plugins/integrations/client-extensions) preserve client-specific behavior. Authors maintain one plugin layout, and each client loads the parts it supports.
|
|
48
|
+
|
|
49
|
+
The specification defines that directory boundary. `agent-plugins` carries the complete plugin through Python packaging beside the library it extends. Regular Python [wheels](https://packaging.python.org/en/latest/specifications/binary-distribution-format/) and [source distributions](https://packaging.python.org/en/latest/specifications/source-distribution-format/) can contain the manifest, skills, MCP configuration, and extension files. Installing the distribution makes its matching Agent Plugin available through Python metadata. Editable installs point discovery at the authored directory.
|
|
50
|
+
|
|
51
|
+
The library and plugin share one release boundary. Teams can update library behavior, skills, MCP configuration, and client extensions together, evaluate the resulting integration against that build, then version, publish, install, and roll them back as one unit. Users and agents install one package, and compatible clients can discover the plugin for that installed library version immediately.
|
|
52
|
+
|
|
53
|
+
Use a build-backend adapter when `agent-plugins` owns the Python build path. When another tool already produced the wheel, attach the configured plugin as a separate artifact step. The command and Python API rewrite the input after the complete attached artifact succeeds. Pass `--output-dir` or `output_dir` to preserve it.
|
|
54
|
+
|
|
55
|
+
```console
|
|
56
|
+
agent-plugins attach-wheel dist/example-1.0.0-py3-none-any.whl --project .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
import agent_plugins as ap
|
|
61
|
+
|
|
62
|
+
result = ap.attach_wheel("dist/example-1.0.0-py3-none-any.whl")
|
|
63
|
+
print(result.output)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Both paths use the same build plan and wheel writer. See [Attach a prebuilt wheel](https://peter-gy.github.io/agent-plugins/guide/attach-wheel) for output copies, result fields, reruns, and signature handling.
|
|
67
|
+
|
|
68
|
+
## Quickstart
|
|
69
|
+
|
|
70
|
+
Keep the plugin directory beside its Python package:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
my-project/
|
|
74
|
+
├── plugin.json
|
|
75
|
+
├── skills/
|
|
76
|
+
│ └── use-my-project/
|
|
77
|
+
│ └── SKILL.md
|
|
78
|
+
└── packages/
|
|
79
|
+
└── python/
|
|
80
|
+
├── pyproject.toml
|
|
81
|
+
└── src/
|
|
82
|
+
└── my_project/
|
|
83
|
+
└── __init__.py
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Create `plugin.json`:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
91
|
+
"name": "my-project"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Create `skills/use-my-project/SKILL.md`:
|
|
96
|
+
|
|
97
|
+
```md
|
|
98
|
+
---
|
|
99
|
+
name: use-my-project
|
|
100
|
+
description: Use my-project to process project records.
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# Use my-project
|
|
104
|
+
|
|
105
|
+
Import `my_project` and call its public API.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Create an empty `packages/python/src/my_project/__init__.py`, then configure the Python project:
|
|
109
|
+
|
|
110
|
+
Wrap the [uv build backend](https://docs.astral.sh/uv/concepts/build-backend/) in `packages/python/pyproject.toml`:
|
|
111
|
+
|
|
112
|
+
```toml
|
|
113
|
+
[project]
|
|
114
|
+
name = "my-project"
|
|
115
|
+
version = "0.1.0"
|
|
116
|
+
requires-python = ">=3.10"
|
|
117
|
+
|
|
118
|
+
[build-system]
|
|
119
|
+
requires = ["agent-plugins", "uv_build"]
|
|
120
|
+
build-backend = "agent_plugins.build.uv_build"
|
|
121
|
+
|
|
122
|
+
[tool.agent-plugins]
|
|
123
|
+
root = "../.."
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
With the [uv package manager](https://docs.astral.sh/uv/) installed, preview the selected files, build the package, install the wheel in a temporary environment, and locate its Agent Plugin:
|
|
127
|
+
|
|
128
|
+
```console
|
|
129
|
+
uv run --with agent-plugins agent-plugins plan packages/python
|
|
130
|
+
uv build packages/python --out-dir dist
|
|
131
|
+
uv run \
|
|
132
|
+
--with agent-plugins \
|
|
133
|
+
--with dist/my_project-0.1.0-py3-none-any.whl \
|
|
134
|
+
agent-plugins locate my-project
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
/path/to/site-packages/my_project-0.1.0.agent-plugin
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The printed Agent Plugin directory and the importable library came from the same wheel and share its distribution version.
|
|
142
|
+
|
|
143
|
+
The [complete quickstart](https://peter-gy.github.io/agent-plugins/guide/getting-started) includes the Python package and Agent Skill files needed for a runnable project.
|
|
144
|
+
|
|
145
|
+
## Inspect a project or installation
|
|
146
|
+
|
|
147
|
+
Add `agent-plugins` to runtime dependencies when Python code calls the inspection API:
|
|
148
|
+
|
|
149
|
+
```toml
|
|
150
|
+
[project]
|
|
151
|
+
dependencies = ["agent-plugins"]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
import agent_plugins as ap
|
|
156
|
+
|
|
157
|
+
source = ap.Plugin.from_project("packages/python")
|
|
158
|
+
installed = ap.locate("my-project")
|
|
159
|
+
skill = source.skill("use-my-project")
|
|
160
|
+
|
|
161
|
+
print(source.manifest.name)
|
|
162
|
+
print(skill.source)
|
|
163
|
+
print(skill.file("SKILL.md"))
|
|
164
|
+
|
|
165
|
+
if installed.mcp is not None:
|
|
166
|
+
for name, server in installed.mcp.servers.items():
|
|
167
|
+
print(name, server)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`Plugin.from_project()` exposes exactly the files selected by `[tool.agent-plugins]`. After installing a build produced from that selection, `locate()` exposes the same plugin-relative inventory. `Plugin(path)` remains the directory-tree constructor for every current file below a plugin root.
|
|
171
|
+
|
|
172
|
+
`skill.source` returns the complete cached `SKILL.md` text. `skill.file()` checks that a resource belongs to the selected inventory before returning its path.
|
|
173
|
+
|
|
174
|
+
`locate()` accepts the Python distribution name used by `pip`. `installed.manifest.name` is a separate Agent Plugin identity.
|
|
175
|
+
|
|
176
|
+
Code-mode agents that can execute Python can use the installed distribution as their plugin source. Through the same API, they can inspect the manifest and MCP configuration, traverse `plugin.skills`, read skill instructions, and open client extension files through native `Path` operations. See [Inspect installed plugins](https://peter-gy.github.io/agent-plugins/guide/inspect-installed).
|
|
177
|
+
|
|
178
|
+
## Core model
|
|
179
|
+
|
|
180
|
+
<p align="center">
|
|
181
|
+
<picture>
|
|
182
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-core-model-dark.svg">
|
|
183
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-core-model-light.svg">
|
|
184
|
+
<img alt="Core model: an authored Python project builds into one wheel that installs the library beside its version-matched Agent Plugin, which locate() returns as a plugin handle" src="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-core-model-light.svg" width="300">
|
|
185
|
+
</picture>
|
|
186
|
+
</p>
|
|
187
|
+
|
|
188
|
+
The build plan selects the plugin files and checks their paths before a build-backend adapter or `attach_wheel()` packages them beside the library. Manifest, MCP, and skill-document content is read on first access through the inspection API and cached for that handle.
|
|
189
|
+
|
|
190
|
+
## Related work
|
|
191
|
+
|
|
192
|
+
[TanStack Intent](https://tanstack.com/intent/) versions Agent Skills with npm library releases and lets agents discover them from installed dependencies. `agent-plugins` applies that package-manager principle to Python and carries the broader Agent Plugins format: the manifest, optional skills and MCP configuration, and client extension files.
|
|
193
|
+
|
|
194
|
+
## Development
|
|
195
|
+
|
|
196
|
+
[`development_docs/`](https://github.com/peter-gy/agent-plugins/tree/main/development_docs) covers contributor setup, architecture, testing, packaging, documentation, and releases. Serve the docs through [Portless](https://portless.sh/):
|
|
197
|
+
|
|
198
|
+
```console
|
|
199
|
+
pnpm --dir docs dev
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The main checkout uses `https://docs.agent-plugins.localhost`. Linked worktrees receive a branch-prefixed subdomain.
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
Licensed under the [Apache License 2.0](https://github.com/peter-gy/agent-plugins/blob/main/LICENSE).
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-lockup-horizontal-dark.svg">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-lockup-horizontal-light.svg">
|
|
5
|
+
<img alt="agent-plugins" src="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-lockup-horizontal-light.svg" width="430">
|
|
6
|
+
</picture>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Ship Agent Plugins with Python packages.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://peter-gy.github.io/agent-plugins/"><strong>Documentation</strong></a> ·
|
|
15
|
+
<a href="https://pypi.org/project/agent-plugins/"><strong>PyPI</strong></a> ·
|
|
16
|
+
<a href="https://agent-plugins.org/"><strong>Agent Plugins format</strong></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="https://pypi.org/project/agent-plugins/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/agent-plugins"></a>
|
|
21
|
+
<a href="https://pypi.org/project/agent-plugins/"><img alt="Supported Python versions" src="https://img.shields.io/pypi/pyversions/agent-plugins"></a>
|
|
22
|
+
<a href="https://github.com/peter-gy/agent-plugins/actions/workflows/ci.yml"><img alt="CI status" src="https://github.com/peter-gy/agent-plugins/actions/workflows/ci.yml/badge.svg"></a>
|
|
23
|
+
<a href="https://github.com/peter-gy/agent-plugins/blob/main/LICENSE"><img alt="Apache-2.0 license" src="https://img.shields.io/pypi/l/agent-plugins"></a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
[Agent Plugins](https://agent-plugins.org/) gives reusable [Agent Skills](https://agentskills.io/specification) and [Model Context Protocol (MCP)](https://modelcontextprotocol.io/specification) servers one package structure that compatible clients can discover consistently. A `plugin.json` manifest identifies the format, fixed locations expose its portable components, and namespaced [client extensions](https://peter-gy.github.io/agent-plugins/integrations/client-extensions) preserve client-specific behavior. Authors maintain one plugin layout, and each client loads the parts it supports.
|
|
27
|
+
|
|
28
|
+
The specification defines that directory boundary. `agent-plugins` carries the complete plugin through Python packaging beside the library it extends. Regular Python [wheels](https://packaging.python.org/en/latest/specifications/binary-distribution-format/) and [source distributions](https://packaging.python.org/en/latest/specifications/source-distribution-format/) can contain the manifest, skills, MCP configuration, and extension files. Installing the distribution makes its matching Agent Plugin available through Python metadata. Editable installs point discovery at the authored directory.
|
|
29
|
+
|
|
30
|
+
The library and plugin share one release boundary. Teams can update library behavior, skills, MCP configuration, and client extensions together, evaluate the resulting integration against that build, then version, publish, install, and roll them back as one unit. Users and agents install one package, and compatible clients can discover the plugin for that installed library version immediately.
|
|
31
|
+
|
|
32
|
+
Use a build-backend adapter when `agent-plugins` owns the Python build path. When another tool already produced the wheel, attach the configured plugin as a separate artifact step. The command and Python API rewrite the input after the complete attached artifact succeeds. Pass `--output-dir` or `output_dir` to preserve it.
|
|
33
|
+
|
|
34
|
+
```console
|
|
35
|
+
agent-plugins attach-wheel dist/example-1.0.0-py3-none-any.whl --project .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import agent_plugins as ap
|
|
40
|
+
|
|
41
|
+
result = ap.attach_wheel("dist/example-1.0.0-py3-none-any.whl")
|
|
42
|
+
print(result.output)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Both paths use the same build plan and wheel writer. See [Attach a prebuilt wheel](https://peter-gy.github.io/agent-plugins/guide/attach-wheel) for output copies, result fields, reruns, and signature handling.
|
|
46
|
+
|
|
47
|
+
## Quickstart
|
|
48
|
+
|
|
49
|
+
Keep the plugin directory beside its Python package:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
my-project/
|
|
53
|
+
├── plugin.json
|
|
54
|
+
├── skills/
|
|
55
|
+
│ └── use-my-project/
|
|
56
|
+
│ └── SKILL.md
|
|
57
|
+
└── packages/
|
|
58
|
+
└── python/
|
|
59
|
+
├── pyproject.toml
|
|
60
|
+
└── src/
|
|
61
|
+
└── my_project/
|
|
62
|
+
└── __init__.py
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Create `plugin.json`:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
70
|
+
"name": "my-project"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Create `skills/use-my-project/SKILL.md`:
|
|
75
|
+
|
|
76
|
+
```md
|
|
77
|
+
---
|
|
78
|
+
name: use-my-project
|
|
79
|
+
description: Use my-project to process project records.
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
# Use my-project
|
|
83
|
+
|
|
84
|
+
Import `my_project` and call its public API.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Create an empty `packages/python/src/my_project/__init__.py`, then configure the Python project:
|
|
88
|
+
|
|
89
|
+
Wrap the [uv build backend](https://docs.astral.sh/uv/concepts/build-backend/) in `packages/python/pyproject.toml`:
|
|
90
|
+
|
|
91
|
+
```toml
|
|
92
|
+
[project]
|
|
93
|
+
name = "my-project"
|
|
94
|
+
version = "0.1.0"
|
|
95
|
+
requires-python = ">=3.10"
|
|
96
|
+
|
|
97
|
+
[build-system]
|
|
98
|
+
requires = ["agent-plugins", "uv_build"]
|
|
99
|
+
build-backend = "agent_plugins.build.uv_build"
|
|
100
|
+
|
|
101
|
+
[tool.agent-plugins]
|
|
102
|
+
root = "../.."
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
With the [uv package manager](https://docs.astral.sh/uv/) installed, preview the selected files, build the package, install the wheel in a temporary environment, and locate its Agent Plugin:
|
|
106
|
+
|
|
107
|
+
```console
|
|
108
|
+
uv run --with agent-plugins agent-plugins plan packages/python
|
|
109
|
+
uv build packages/python --out-dir dist
|
|
110
|
+
uv run \
|
|
111
|
+
--with agent-plugins \
|
|
112
|
+
--with dist/my_project-0.1.0-py3-none-any.whl \
|
|
113
|
+
agent-plugins locate my-project
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
/path/to/site-packages/my_project-0.1.0.agent-plugin
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The printed Agent Plugin directory and the importable library came from the same wheel and share its distribution version.
|
|
121
|
+
|
|
122
|
+
The [complete quickstart](https://peter-gy.github.io/agent-plugins/guide/getting-started) includes the Python package and Agent Skill files needed for a runnable project.
|
|
123
|
+
|
|
124
|
+
## Inspect a project or installation
|
|
125
|
+
|
|
126
|
+
Add `agent-plugins` to runtime dependencies when Python code calls the inspection API:
|
|
127
|
+
|
|
128
|
+
```toml
|
|
129
|
+
[project]
|
|
130
|
+
dependencies = ["agent-plugins"]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import agent_plugins as ap
|
|
135
|
+
|
|
136
|
+
source = ap.Plugin.from_project("packages/python")
|
|
137
|
+
installed = ap.locate("my-project")
|
|
138
|
+
skill = source.skill("use-my-project")
|
|
139
|
+
|
|
140
|
+
print(source.manifest.name)
|
|
141
|
+
print(skill.source)
|
|
142
|
+
print(skill.file("SKILL.md"))
|
|
143
|
+
|
|
144
|
+
if installed.mcp is not None:
|
|
145
|
+
for name, server in installed.mcp.servers.items():
|
|
146
|
+
print(name, server)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`Plugin.from_project()` exposes exactly the files selected by `[tool.agent-plugins]`. After installing a build produced from that selection, `locate()` exposes the same plugin-relative inventory. `Plugin(path)` remains the directory-tree constructor for every current file below a plugin root.
|
|
150
|
+
|
|
151
|
+
`skill.source` returns the complete cached `SKILL.md` text. `skill.file()` checks that a resource belongs to the selected inventory before returning its path.
|
|
152
|
+
|
|
153
|
+
`locate()` accepts the Python distribution name used by `pip`. `installed.manifest.name` is a separate Agent Plugin identity.
|
|
154
|
+
|
|
155
|
+
Code-mode agents that can execute Python can use the installed distribution as their plugin source. Through the same API, they can inspect the manifest and MCP configuration, traverse `plugin.skills`, read skill instructions, and open client extension files through native `Path` operations. See [Inspect installed plugins](https://peter-gy.github.io/agent-plugins/guide/inspect-installed).
|
|
156
|
+
|
|
157
|
+
## Core model
|
|
158
|
+
|
|
159
|
+
<p align="center">
|
|
160
|
+
<picture>
|
|
161
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-core-model-dark.svg">
|
|
162
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-core-model-light.svg">
|
|
163
|
+
<img alt="Core model: an authored Python project builds into one wheel that installs the library beside its version-matched Agent Plugin, which locate() returns as a plugin handle" src="https://raw.githubusercontent.com/peter-gy/agent-plugins/main/docs/public/brand/agent-plugins-core-model-light.svg" width="300">
|
|
164
|
+
</picture>
|
|
165
|
+
</p>
|
|
166
|
+
|
|
167
|
+
The build plan selects the plugin files and checks their paths before a build-backend adapter or `attach_wheel()` packages them beside the library. Manifest, MCP, and skill-document content is read on first access through the inspection API and cached for that handle.
|
|
168
|
+
|
|
169
|
+
## Related work
|
|
170
|
+
|
|
171
|
+
[TanStack Intent](https://tanstack.com/intent/) versions Agent Skills with npm library releases and lets agents discover them from installed dependencies. `agent-plugins` applies that package-manager principle to Python and carries the broader Agent Plugins format: the manifest, optional skills and MCP configuration, and client extension files.
|
|
172
|
+
|
|
173
|
+
## Development
|
|
174
|
+
|
|
175
|
+
[`development_docs/`](https://github.com/peter-gy/agent-plugins/tree/main/development_docs) covers contributor setup, architecture, testing, packaging, documentation, and releases. Serve the docs through [Portless](https://portless.sh/):
|
|
176
|
+
|
|
177
|
+
```console
|
|
178
|
+
pnpm --dir docs dev
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The main checkout uses `https://docs.agent-plugins.localhost`. Linked worktrees receive a branch-prefixed subdomain.
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
Licensed under the [Apache License 2.0](https://github.com/peter-gy/agent-plugins/blob/main/LICENSE).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agent-plugins"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "Ship Agent Plugins with Python packages and inspect their installed files"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -21,6 +21,8 @@ name = "Péter Ferenc Gyarmati"
|
|
|
21
21
|
email = "dev.petergy@gmail.com"
|
|
22
22
|
|
|
23
23
|
[project.urls]
|
|
24
|
+
Documentation = "https://peter-gy.github.io/agent-plugins/"
|
|
25
|
+
Issues = "https://github.com/peter-gy/agent-plugins/issues"
|
|
24
26
|
Source = "https://github.com/peter-gy/agent-plugins"
|
|
25
27
|
|
|
26
28
|
[project.scripts]
|