progressive-skills-mcp 0.2.0__py3-none-any.whl

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.
@@ -0,0 +1,5 @@
1
+ """Central definition of the Skillz package version."""
2
+
3
+ __all__ = ["__version__"]
4
+
5
+ __version__ = "0.2.0"
@@ -0,0 +1,164 @@
1
+ """Progressive disclosure implementation for skillz.
2
+
3
+ Add this code to _server.py to enable progressive disclosure.
4
+ """
5
+
6
+ from typing import Optional, Any
7
+ from fastmcp import Context
8
+ from fastmcp.exceptions import ToolError
9
+ import base64
10
+
11
+
12
+ class MetadataGenerator:
13
+ """Generate system prompt metadata for all skills."""
14
+
15
+ def __init__(self, registry):
16
+ self.registry = registry
17
+
18
+ def generate_system_prompt_metadata(self) -> str:
19
+ """Generate markdown-formatted skill metadata for system prompts."""
20
+ skills = sorted(self.registry.skills, key=lambda s: s.slug)
21
+
22
+ if not skills:
23
+ return "No skills available."
24
+
25
+ lines = [
26
+ "## Available Skills",
27
+ "",
28
+ "You have access to specialized skills. To use a skill, call the `load_skill` tool with the skill name.",
29
+ "",
30
+ ]
31
+
32
+ for skill in skills:
33
+ lines.append(f"- **{skill.slug}**: {skill.metadata.description}")
34
+
35
+ return "\n".join(lines)
36
+
37
+ def generate_json_metadata(self) -> str:
38
+ """Generate JSON metadata for programmatic use."""
39
+ import json
40
+ metadata = [
41
+ {
42
+ "name": skill.slug,
43
+ "description": skill.metadata.description,
44
+ "allowed_tools": list(skill.metadata.allowed_tools),
45
+ }
46
+ for skill in self.registry.skills
47
+ ]
48
+ return json.dumps(metadata, indent=2)
49
+
50
+
51
+ def register_progressive_disclosure_tools(mcp, registry) -> None:
52
+ """Register 3 universal tools for progressive disclosure."""
53
+
54
+ @mcp.tool(
55
+ name="load_skill",
56
+ description=(
57
+ "Load the complete instructions for a skill. "
58
+ "Use this when you've decided a skill is relevant based on "
59
+ "the skill metadata in your system prompt. "
60
+ "Returns the full SKILL.md content without frontmatter."
61
+ )
62
+ )
63
+ async def load_skill_tool(
64
+ skill_name: str,
65
+ ctx: Optional[Context] = None,
66
+ ) -> str:
67
+ """Load full skill instructions (Level 2 progressive disclosure)."""
68
+ try:
69
+ skill = registry.get(skill_name)
70
+ LOGGER.info("Loaded skill: %s", skill_name)
71
+ return skill.read_body()
72
+ except Exception as exc:
73
+ raise ToolError(
74
+ f"Skill '{skill_name}' not found. "
75
+ f"Available skills can be seen in your system prompt."
76
+ ) from exc
77
+
78
+ @mcp.tool(
79
+ name="read_skill_file",
80
+ description=(
81
+ "Read a specific file from a skill's directory. "
82
+ "Use this when skill instructions reference a file "
83
+ "(e.g., 'See references/api_reference.md'). "
84
+ "Provide the skill name and relative file path."
85
+ )
86
+ )
87
+ async def read_skill_file_tool(
88
+ skill_name: str,
89
+ file_path: str,
90
+ ctx: Optional[Context] = None,
91
+ ) -> str:
92
+ """Read a specific file from skill directory (Level 3 progressive disclosure)."""
93
+ try:
94
+ skill = registry.get(skill_name)
95
+
96
+ # Validate path doesn't traverse upward
97
+ if ".." in file_path or file_path.startswith("/"):
98
+ raise ToolError("Invalid path: path traversal not allowed")
99
+
100
+ if not skill.exists(file_path):
101
+ raise ToolError(
102
+ f"File '{file_path}' not found in skill '{skill_name}'"
103
+ )
104
+
105
+ # Read content
106
+ data = skill.open_bytes(file_path)
107
+
108
+ # Try to decode as UTF-8, fallback to base64 for binary
109
+ try:
110
+ content = data.decode("utf-8")
111
+ except UnicodeDecodeError:
112
+ content = f"[Binary file - base64 encoded]\n{base64.b64encode(data).decode('ascii')}"
113
+
114
+ LOGGER.info("Read file: %s/%s", skill_name, file_path)
115
+ return content
116
+
117
+ except Exception as exc:
118
+ raise ToolError(str(exc)) from exc
119
+
120
+ @mcp.tool(
121
+ name="list_skill_files",
122
+ description=(
123
+ "List files available in a skill's directory. "
124
+ "Use this to discover what reference files, scripts, or resources "
125
+ "a skill provides. Optionally specify a subdirectory like "
126
+ "'references' or 'scripts'."
127
+ )
128
+ )
129
+ async def list_skill_files_tool(
130
+ skill_name: str,
131
+ subdirectory: Optional[str] = None,
132
+ ctx: Optional[Context] = None,
133
+ ) -> str:
134
+ """List available files in a skill directory."""
135
+ try:
136
+ skill = registry.get(skill_name)
137
+
138
+ # Get all resource paths
139
+ all_paths = list(skill.iter_resource_paths())
140
+
141
+ # Filter by subdirectory if specified
142
+ if subdirectory:
143
+ # Normalize subdirectory path
144
+ subdir_prefix = subdirectory.rstrip("/") + "/"
145
+ filtered_paths = [
146
+ path for path in all_paths
147
+ if path.startswith(subdir_prefix)
148
+ ]
149
+ else:
150
+ filtered_paths = all_paths
151
+
152
+ if not filtered_paths:
153
+ subdir_msg = f" in subdirectory '{subdirectory}'" if subdirectory else ""
154
+ return f"No files found in skill '{skill_name}'{subdir_msg}"
155
+
156
+ # Format output
157
+ subdir_msg = f" in '{subdirectory}'" if subdirectory else ""
158
+ lines = [f"Files in skill '{skill_name}'{subdir_msg}:"]
159
+ lines.extend(f" - {path}" for path in sorted(filtered_paths))
160
+
161
+ return "\n".join(lines)
162
+
163
+ except Exception as exc:
164
+ raise ToolError(str(exc)) from exc
@@ -0,0 +1,228 @@
1
+ Metadata-Version: 2.3
2
+ Name: progressive-skills-mcp
3
+ Version: 0.2.0
4
+ Summary: MCP server that exposes Claude-style skills to any MCP client.
5
+ Keywords: mcp,skills,fastmcp,claude
6
+ Author: Eleanor Berger
7
+ Author-email: Eleanor Berger <eleanor@intellectronica.net>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2025 Eleanor Berger <eleanor@intellectronica.net>
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Programming Language :: Python
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.12
35
+ Requires-Dist: fastmcp>=2.2.5
36
+ Requires-Dist: pyyaml>=6.0
37
+ Requires-Python: >=3.12
38
+ Project-URL: Homepage, https://github.com/Flowtrica/skills-mcp
39
+ Project-URL: Issues, https://github.com/Flowtrica/skills-mcp/issues
40
+ Description-Content-Type: text/markdown
41
+
42
+ # Skills MCP
43
+
44
+ MCP server for SKILL.md files with **progressive disclosure** - achieving **13x token efficiency** over traditional approaches.
45
+
46
+ Based on [intellectronica/skillz](https://github.com/intellectronica/skillz) with progressive disclosure modifications inspired by Claude.ai's approach.
47
+
48
+ ## What's Different?
49
+
50
+ **Original skillz:**
51
+ - Creates 1 tool per skill
52
+ - 20 skills = 20 tools × ~100 tokens = **2000 tokens/request**
53
+
54
+ **Skills MCP (this fork):**
55
+ - Creates 3 universal tools (`load_skill`, `read_skill_file`, `list_skill_files`)
56
+ - 20 skills = 3 tools × ~50 tokens = **150 tokens/request**
57
+ - **13x improvement!** 🎉
58
+
59
+ ## Features
60
+
61
+ ✅ Progressive disclosure (3-level token efficiency)
62
+ ✅ Metadata generation for system prompts
63
+ ✅ Compatible with all SKILL.md format files
64
+ ✅ Supports .zip and .skill archives
65
+ ✅ Docker image available
66
+
67
+ ## Quick Start
68
+
69
+ ### Using Docker
70
+
71
+ ```bash
72
+ docker run -i --rm \
73
+ -v /path/to/skills:/skills \
74
+ flowtrica/skills-mcp:latest \
75
+ /skills
76
+ ```
77
+
78
+ ### Using uvx
79
+
80
+ ```bash
81
+ uvx skills-mcp@latest /path/to/skills
82
+ ```
83
+
84
+ ### With MCPHub
85
+
86
+ ```json
87
+ {
88
+ "mcpServers": {
89
+ "skills": {
90
+ "command": "docker",
91
+ "args": [
92
+ "run", "-i", "--rm",
93
+ "--entrypoint", "sh",
94
+ "flowtrica/skills-mcp:latest",
95
+ "-c",
96
+ "git clone https://github.com/YOUR_USERNAME/your-skills.git /tmp/skills && skills-mcp /tmp/skills"
97
+ ]
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Progressive Disclosure
104
+
105
+ ### Level 1: System Prompt (Once per conversation)
106
+ ```markdown
107
+ ## Available Skills
108
+ - **weather**: Get weather forecasts
109
+ - **pptx**: Create presentations
110
+ ```
111
+ **Cost:** ~200 tokens, sent ONCE
112
+
113
+ ### Level 2: On-Demand Instructions
114
+ ```python
115
+ load_skill("pptx") # Returns full SKILL.md
116
+ ```
117
+ **Cost:** 0 tokens until loaded
118
+
119
+ ### Level 3: Referenced Resources
120
+ ```python
121
+ read_skill_file("pptx", "references/api.md")
122
+ ```
123
+ **Cost:** 0 tokens until accessed
124
+
125
+ ## Generate Metadata
126
+
127
+ For Onyx or other MCP clients that support system prompts:
128
+
129
+ ```bash
130
+ skills-mcp --generate-metadata /path/to/skills
131
+ ```
132
+
133
+ Output:
134
+ ```markdown
135
+ ## Available Skills
136
+
137
+ You have access to specialized skills...
138
+
139
+ - **test-skill**: A simple test skill
140
+ - **weather**: Get weather forecasts
141
+ ```
142
+
143
+ ## Installation
144
+
145
+ ```bash
146
+ pip install skills-mcp
147
+ ```
148
+
149
+ Or use with `uv`:
150
+ ```bash
151
+ uv tool install skills-mcp
152
+ ```
153
+
154
+ ## Usage
155
+
156
+ ```bash
157
+ # Run MCP server
158
+ skills-mcp /path/to/skills
159
+
160
+ # Generate metadata
161
+ skills-mcp --generate-metadata /path/to/skills
162
+
163
+ # Generate JSON metadata
164
+ skills-mcp --generate-metadata --format json /path/to/skills
165
+
166
+ # List discovered skills
167
+ skills-mcp --list-skills /path/to/skills
168
+ ```
169
+
170
+ ## Skill Format
171
+
172
+ Skills can be:
173
+ - **Directories** with SKILL.md file
174
+ - **Zip archives** containing SKILL.md
175
+ - **.skill archives**
176
+
177
+ Example structure:
178
+ ```
179
+ skills/
180
+ ├── weather/
181
+ │ ├── SKILL.md
182
+ │ └── references/
183
+ │ └── api.md
184
+ └── pptx.zip
185
+ ```
186
+
187
+ SKILL.md format:
188
+ ```markdown
189
+ ---
190
+ name: skill-name
191
+ description: Brief description
192
+ ---
193
+
194
+ # Full Instructions
195
+
196
+ Detailed skill instructions here...
197
+ ```
198
+
199
+ ## Building Docker Image
200
+
201
+ ```bash
202
+ docker build -t flowtrica/skills-mcp:latest .
203
+ docker push flowtrica/skills-mcp:latest
204
+ ```
205
+
206
+ ## Token Efficiency Comparison
207
+
208
+ | Approach | Tools/Request | Tokens/Request | 20 Skills |
209
+ |----------|--------------|----------------|-----------|
210
+ | Original | 20 tools | ~100 each | 2000 tokens |
211
+ | **Skills MCP** | **3 tools** | **~50 each** | **150 tokens** |
212
+ | **Improvement** | | | **13x better!** 🎉 |
213
+
214
+ ## License
215
+
216
+ MIT (same as original skillz)
217
+
218
+ ## Credits
219
+
220
+ - Based on [skillz](https://github.com/intellectronica/skillz) by Eleanor Berger
221
+ - Progressive disclosure modifications by Flowtrica
222
+ - Inspired by Claude.ai's skills system
223
+
224
+ ## Links
225
+
226
+ - Original skillz: https://github.com/intellectronica/skillz
227
+ - Skills repo: https://github.com/Flowtrica/agent-skills
228
+ - Docker Hub: https://hub.docker.com/r/flowtrica/skills-mcp
@@ -0,0 +1,10 @@
1
+ progressive_skills_mcp/__init__.py,sha256=WFbujAfiFsm3g567Ea91ZXjhLesI78EVhc3Ao3oy1PM,522
2
+ progressive_skills_mcp/__main__.py,sha256=AFR1CXSuPL4Td1RPNWZzuUXntdaHqgJOp9DL5iPk8QM,215
3
+ progressive_skills_mcp/_server.py,sha256=jWuqHTTad8ECpawX-qd0PdNCodb0t2hcOPJo5qUnxVI,41991
4
+ progressive_skills_mcp/_version.py,sha256=q4q6xy8hoU3hhiPLlZPK9YPK0gwpSwNYBznw8EVjY6k,106
5
+ progressive_skills_mcp/progressive_disclosure.py,sha256=rSOGm0XodEXMoNlRTnkyPeDFiY3yug1i_pv3aUvHqPE,5855
6
+ progressive_skills_mcp/skills/context7-docs-lookup.zip,sha256=9jvk8QROayFq249BxCUCi2dhvaUdH2eOdEZunHjNSkg,2430
7
+ progressive_skills_mcp-0.2.0.dist-info/WHEEL,sha256=5DEXXimM34_d4Gx1AuF9ysMr1_maoEtGKjaILM3s4w4,80
8
+ progressive_skills_mcp-0.2.0.dist-info/entry_points.txt,sha256=v3yDRF-b-QfYLa8bfmOvTr40hHKTy9F0166K-DfoyGo,80
9
+ progressive_skills_mcp-0.2.0.dist-info/METADATA,sha256=yirmfD0v-RsW7xn-bIWfFB4ABcZt94TMX88AxxT26es,5964
10
+ progressive_skills_mcp-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.29
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ progressive-skills-mcp = progressive_skills_mcp.__main__:run
3
+