mcp-skill 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.
Files changed (48) hide show
  1. mcp_skill-0.2.0/.github/workflows/release.yml +71 -0
  2. mcp_skill-0.2.0/.release-please-manifest.json +3 -0
  3. mcp_skill-0.2.0/CHANGELOG.md +30 -0
  4. mcp_skill-0.2.0/LICENSE +21 -0
  5. mcp_skill-0.2.0/PKG-INFO +198 -0
  6. mcp_skill-0.2.0/README.md +169 -0
  7. mcp_skill-0.2.0/pyproject.toml +43 -0
  8. mcp_skill-0.2.0/release-please-config.json +12 -0
  9. mcp_skill-0.2.0/skills/airtable/SKILL.md +308 -0
  10. mcp_skill-0.2.0/skills/airtable/__init__.py +0 -0
  11. mcp_skill-0.2.0/skills/airtable/app.py +371 -0
  12. mcp_skill-0.2.0/skills/canva/SKILL.md +500 -0
  13. mcp_skill-0.2.0/skills/canva/__init__.py +0 -0
  14. mcp_skill-0.2.0/skills/canva/app.py +1004 -0
  15. mcp_skill-0.2.0/skills/clickup/SKILL.md +500 -0
  16. mcp_skill-0.2.0/skills/clickup/__init__.py +0 -0
  17. mcp_skill-0.2.0/skills/clickup/app.py +1304 -0
  18. mcp_skill-0.2.0/skills/context7/SKILL.md +152 -0
  19. mcp_skill-0.2.0/skills/context7/__init__.py +0 -0
  20. mcp_skill-0.2.0/skills/context7/app.py +120 -0
  21. mcp_skill-0.2.0/skills/linear/SKILL.md +500 -0
  22. mcp_skill-0.2.0/skills/linear/__init__.py +0 -0
  23. mcp_skill-0.2.0/skills/linear/app.py +1243 -0
  24. mcp_skill-0.2.0/skills/notion/SKILL.md +500 -0
  25. mcp_skill-0.2.0/skills/notion/__init__.py +0 -0
  26. mcp_skill-0.2.0/skills/notion/app.py +794 -0
  27. mcp_skill-0.2.0/skills/parallel_search/SKILL.md +135 -0
  28. mcp_skill-0.2.0/skills/parallel_search/__init__.py +0 -0
  29. mcp_skill-0.2.0/skills/parallel_search/app.py +93 -0
  30. mcp_skill-0.2.0/skills/pubmed/SKILL.md +409 -0
  31. mcp_skill-0.2.0/skills/pubmed/__init__.py +0 -0
  32. mcp_skill-0.2.0/skills/pubmed/app.py +463 -0
  33. mcp_skill-0.2.0/skills/sentry/SKILL.md +500 -0
  34. mcp_skill-0.2.0/skills/sentry/__init__.py +0 -0
  35. mcp_skill-0.2.0/skills/sentry/app.py +785 -0
  36. mcp_skill-0.2.0/src/mcp_skill/__init__.py +3 -0
  37. mcp_skill-0.2.0/src/mcp_skill/auth/__init__.py +16 -0
  38. mcp_skill-0.2.0/src/mcp_skill/auth/api_key.py +45 -0
  39. mcp_skill-0.2.0/src/mcp_skill/auth/bearer.py +39 -0
  40. mcp_skill-0.2.0/src/mcp_skill/auth/client_credentials.py +16 -0
  41. mcp_skill-0.2.0/src/mcp_skill/cli.py +160 -0
  42. mcp_skill-0.2.0/src/mcp_skill/generator.py +184 -0
  43. mcp_skill-0.2.0/src/mcp_skill/introspector.py +69 -0
  44. mcp_skill-0.2.0/src/mcp_skill/templates/app.py.j2 +98 -0
  45. mcp_skill-0.2.0/src/mcp_skill/templates/skill.md.j2 +166 -0
  46. mcp_skill-0.2.0/src/mcp_skill/type_mapper.py +210 -0
  47. mcp_skill-0.2.0/src/mcp_skill/validator.py +91 -0
  48. mcp_skill-0.2.0/uv.lock +1676 -0
@@ -0,0 +1,71 @@
1
+ # .github/workflows/release.yml
2
+ #
3
+ # Release workflow: automated changelog + PyPI publishing
4
+ #
5
+ # How it works:
6
+ # 1. On every push to main, release-please checks for conventional commits
7
+ # and maintains a "Release PR" with updated CHANGELOG.md and version bump.
8
+ # 2. When the Release PR is merged, release-please creates a GitHub release.
9
+ # 3. The publish job then builds and publishes to PyPI using trusted publishing.
10
+ #
11
+ # Setup required (one-time, manual):
12
+ # - On PyPI: Settings → Publishing → Add trusted publisher
13
+ # Publisher: GitHub Actions
14
+ # Repository: manojbajaj95/mcp-skill
15
+ # Workflow: release.yml
16
+ # Environment: pypi
17
+ # - On GitHub: Settings → Environments → Create "pypi" environment
18
+ #
19
+ # Conventional commits required for release-please:
20
+ # feat: → minor version bump (0.1.0 → 0.2.0)
21
+ # fix: → patch version bump (0.1.0 → 0.1.1)
22
+ # feat!: → major version bump (0.1.0 → 1.0.0)
23
+
24
+ name: release
25
+
26
+ on:
27
+ push:
28
+ branches:
29
+ - main
30
+ workflow_dispatch:
31
+
32
+ jobs:
33
+ release-please:
34
+ runs-on: ubuntu-latest
35
+ permissions:
36
+ contents: write
37
+ pull-requests: write
38
+ outputs:
39
+ release_created: ${{ steps.release.outputs.release_created }}
40
+ tag_name: ${{ steps.release.outputs.tag_name }}
41
+ steps:
42
+ - uses: googleapis/release-please-action@v4
43
+ id: release
44
+ with:
45
+ token: ${{ secrets.GITHUB_TOKEN }}
46
+ config-file: release-please-config.json
47
+ manifest-file: .release-please-manifest.json
48
+
49
+ publish:
50
+ name: Publish to PyPI
51
+ runs-on: ubuntu-latest
52
+ needs: release-please
53
+ if: ${{ needs.release-please.outputs.release_created }}
54
+ environment:
55
+ name: pypi
56
+ url: https://pypi.org/project/mcp-skill/
57
+ permissions:
58
+ id-token: write # Required for PyPI trusted publishing (OIDC)
59
+ steps:
60
+ - uses: actions/checkout@v4
61
+
62
+ - name: Install uv
63
+ uses: astral-sh/setup-uv@v7
64
+ with:
65
+ enable-cache: true
66
+
67
+ - name: Build package
68
+ run: uv build
69
+
70
+ - name: Publish to PyPI
71
+ run: uv publish --trusted-publishing always
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.0"
3
+ }
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0](https://github.com/manojbajaj95/mcp-skill/compare/v0.1.0...v0.2.0) (2026-03-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add generated skills ([c9c81b9](https://github.com/manojbajaj95/mcp-skill/commit/c9c81b93344c1e45ce152e8a58ef264835f89f8d))
9
+ * add persistent disk-backed token storage for all auth types ([531e402](https://github.com/manojbajaj95/mcp-skill/commit/531e40278268fb2997be012ef39e4b3ee0774078))
10
+ * **auth:** add ClientCredentialsAuth stub (NotImplementedError placeholder) ([133ebcc](https://github.com/manojbajaj95/mcp-skill/commit/133ebcc50aad4b04d3c60ff5dfe064daca4abc87))
11
+ * **auth:** extract auth classes into importable mcp_skill.auth module ([e0d0873](https://github.com/manojbajaj95/mcp-skill/commit/e0d0873d208100b05d40705108e78ecb47b48f0d))
12
+ * **cli:** add interactive wizard and non-interactive CLI mode ([2e7e30c](https://github.com/manojbajaj95/mcp-skill/commit/2e7e30c8d38d654368ab23b36dd06249b1c4770e))
13
+ * **core:** add introspector, app.py generator, and SKILL.md generator ([5256855](https://github.com/manojbajaj95/mcp-skill/commit/52568551306122451ef5cafcbe63103d22138b1a))
14
+ * fix skill output, add deps/usage to SKILL.md, add post-gen validation ([516218b](https://github.com/manojbajaj95/mcp-skill/commit/516218bc74c4153b7b569bf9f7668cd04a9ec86a))
15
+ * **scaffold:** initialize mcp-skill project with UV and pyproject.toml ([afcecd9](https://github.com/manojbajaj95/mcp-skill/commit/afcecd9f045a08c17a48bfd3973ac5b2d18a9ff3))
16
+ * **templates:** unify __init__ signature to use auth=None across all auth types ([99bd4ef](https://github.com/manojbajaj95/mcp-skill/commit/99bd4ef5ff54cd1c681d3b44a9887ff4eef22058))
17
+ * **types:** add JSON Schema to Python type mapper and name sanitizer ([6234fa1](https://github.com/manojbajaj95/mcp-skill/commit/6234fa1781963897c7b4407c923a1eb1b6d5d15f))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * Fix parallel search name ([c5afbf6](https://github.com/manojbajaj95/mcp-skill/commit/c5afbf62d9c51346709c8fd7f87e0945138c35b5))
23
+ * **generate:** use per-method client pattern and user-provided app name ([c65bb3e](https://github.com/manojbajaj95/mcp-skill/commit/c65bb3e2412f740706f155b4a243389003ea2f6f))
24
+ * **generate:** use result.content for CallToolResult and filter None optional args ([48e4b56](https://github.com/manojbajaj95/mcp-skill/commit/48e4b566e3d2a88e0daaaaa6955c269ce944e764))
25
+ * sanitize skill name to valid Python identifier for folder and imports ([afba3b6](https://github.com/manojbajaj95/mcp-skill/commit/afba3b683860c294ec28d7716eab5a553e1ff099))
26
+
27
+
28
+ ### Documentation
29
+
30
+ * rewrite README with before/after, diagram, generated output, and audience section ([e341453](https://github.com/manojbajaj95/mcp-skill/commit/e341453e690ff8fa46422b270a70f8bf271426d8))
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mcp-skill contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-skill
3
+ Version: 0.2.0
4
+ Summary: Convert any MCP server into an Agent Skill
5
+ Project-URL: Homepage, https://github.com/manojbajaj95/mcp-skill
6
+ Project-URL: Repository, https://github.com/manojbajaj95/mcp-skill
7
+ Project-URL: Issues, https://github.com/manojbajaj95/mcp-skill/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: agent,code-generation,fastmcp,llm,mcp,skill
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Topic :: Software Development :: Code Generators
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: click>=8.0
23
+ Requires-Dist: fastmcp>=2.0
24
+ Requires-Dist: jinja2>=3.1
25
+ Requires-Dist: py-key-value-aio[disk]
26
+ Requires-Dist: ruff>=0.15.4
27
+ Requires-Dist: ty>=0.0.20
28
+ Description-Content-Type: text/markdown
29
+
30
+ # mcp-skill
31
+
32
+ Turn any MCP server into a typed Python SDK.
33
+
34
+ > **Compile MCP tools into code.**
35
+
36
+ `mcp-skill` introspects an MCP server and generates a Python class where each tool becomes a typed async method.
37
+
38
+ ## Before and After
39
+
40
+ ### Before
41
+
42
+ Agents call MCP tools through the model loop — one round-trip per tool call:
43
+
44
+ ```
45
+ llm.call_tool("web_search_preview", {"query": "..."})
46
+ # → model decides next step → calls another tool → model decides again → ...
47
+ ```
48
+
49
+ ### After
50
+
51
+ Agents call tools directly in code:
52
+
53
+ ```python
54
+ result = await app.web_search_preview(
55
+ objective="find latest news",
56
+ search_queries=["topic X 2026"]
57
+ )
58
+ # Agent processes result in code — no round-trip back to model
59
+ ```
60
+
61
+ ## How It Works
62
+
63
+ ```
64
+ ┌─────────────┐ ┌───────────────┐ ┌────────────────────┐
65
+ │ MCP Server │─────▶│ mcp-skill │─────▶│ Generated Skill │
66
+ │ (any URL) │ │ CLI │ │ │
67
+ │ │ │ │ │ app.py │
68
+ │ Tools: │ │ 1. Connect │ │ ├─ Typed class │
69
+ │ - search │ │ 2. Introspec │ │ ├─ Async methods │
70
+ │ - fetch │ │ 3. Map types │ │ ├─ Auth + storage │
71
+ │ - ... │ │ 4. Generate │ │ └─ JSON parsing │
72
+ │ │ │ 5. Validate │ │ │
73
+ └─────────────┘ └───────────────┘ │ SKILL.md │
74
+ │ └─ Agent docs │
75
+ └────────────────────┘
76
+ ```
77
+
78
+ 1. Connects to the MCP server using [fastmcp](https://github.com/jlowin/fastmcp)
79
+ 2. Introspects all available tools via `list_tools()`
80
+ 3. Converts each tool's JSON Schema into Python type annotations
81
+ 4. Generates a typed `App` class where each MCP tool becomes an `async` method
82
+ 5. Validates the output with `ast.parse` → `ruff` → `ty`
83
+ 6. Generates `SKILL.md` with tool documentation and usage examples for agents
84
+
85
+ ## Motivation
86
+
87
+ MCP servers give agents access to tools, but every tool call round-trips through the model — request tool, execute, full result back into context, decide next step. For large payloads or sequential calls, this burns tokens and adds latency.
88
+
89
+ [Programmatic Tool Calling](https://platform.claude.com/cookbook/tool-use-programmatic-tool-calling-ptc) fixes this: the agent writes code that calls tools directly, without model round-trips per invocation. Fetch, filter, aggregate — all in one code block.
90
+
91
+ **mcp-skill** makes this possible by compiling any MCP server into a plain Python class. Each tool becomes a typed async method. The agent just writes Python.
92
+
93
+ ```python
94
+ from parallel_search.app import ParallelApp
95
+
96
+ app = ParallelApp(auth="sk-...")
97
+ result = await app.web_search_preview(
98
+ objective="find latest news on topic X",
99
+ search_queries=["topic X 2026"]
100
+ )
101
+ ```
102
+
103
+ ## Setup
104
+
105
+ ```bash
106
+ # Install with uv
107
+ uv pip install -e .
108
+
109
+ # Or use directly
110
+ uv run mcp-skill create --url https://your-mcp-server.com/mcp --auth api-key
111
+ ```
112
+
113
+ Requires [uv](https://github.com/astral-sh/uv) and Python 3.10+.
114
+
115
+ ## Usage
116
+
117
+ ```bash
118
+ # Interactive mode — prompts for URL, auth type, etc.
119
+ mcp-skill create
120
+
121
+ # Non-interactive mode
122
+ mcp-skill create \
123
+ --url https://search-mcp.parallel.ai/mcp \
124
+ --auth api-key \
125
+ --api-key YOUR_KEY \
126
+ --name parallel-search \
127
+ --non-interactive
128
+ ```
129
+
130
+ ### Generated Output
131
+
132
+ The skill lands in `.agents/skills/<name>/` as a Python package:
133
+
134
+ ```
135
+ .agents/skills/parallel_search/
136
+ ├── __init__.py
137
+ ├── app.py # Typed Python class wrapping the MCP server
138
+ └── SKILL.md # Agent-facing docs, dependencies, and usage
139
+ ```
140
+
141
+ Here's what the generated `app.py` looks like:
142
+
143
+ ```python
144
+ class ParallelApp:
145
+
146
+ def __init__(self, url: str = "https://...", auth=None) -> None:
147
+ ...
148
+
149
+ async def web_search_preview(
150
+ self,
151
+ objective: str,
152
+ search_queries: list[str],
153
+ ) -> dict[str, Any]:
154
+ """Search the web with multiple queries in parallel."""
155
+ ...
156
+
157
+ async def fetch_url(
158
+ self,
159
+ url: str,
160
+ max_length: int = None,
161
+ ) -> dict[str, Any]:
162
+ """Fetch and extract content from a URL."""
163
+ ...
164
+
165
+ def list_tools(self):
166
+ return [self.web_search_preview, self.fetch_url]
167
+ ```
168
+
169
+ Each method connects to the MCP server, calls the underlying tool, and returns parsed JSON. Auth credentials are persisted to disk (`~/.mcp-skill/<name>/`) after first use — provide once, reuse automatically.
170
+
171
+ ## Who Is This For?
172
+
173
+ Developers building:
174
+
175
+ - **MCP-based agents** that need direct tool access without model round-trips
176
+ - **Automation systems** using MCP tools as programmatic building blocks
177
+ - **Code-execution agents** using [Programmatic Tool Calling](https://platform.claude.com/cookbook/tool-use-programmatic-tool-calling-ptc)
178
+
179
+ ## Current Limitations
180
+
181
+ - **Auth**: Supports API key (Bearer or custom header), OAuth, and none — no mTLS or complex auth flows
182
+ - **Runtime dependency**: Generated code depends on [fastmcp](https://github.com/jlowin/fastmcp) for MCP client connections
183
+ - **Connection per call**: Each method creates a new MCP client connection (no pooling)
184
+ - **Tools only**: MCP resources and prompts not yet supported
185
+
186
+ ## Task List
187
+
188
+ Tracked improvements based on real-world usage:
189
+
190
+ - [x] **Fix output directory path** — Changed from `.agents/skill/<name>` to `.agents/skills/<name>`
191
+ - [x] **Add dependency info to SKILL.md** — Dependencies listed with `uv` and `pip` install commands
192
+ - [x] **Generate `__init__.py`** — Skill directory is a proper Python package
193
+ - [x] **Post-generation validation** — `ast.parse` → `ruff check` → `ty check` with `uvx` fallback
194
+ - [x] **Package-style imports** — Moved `app.py` to skill root; import via `from <skill>.app import <Class>`
195
+ - [x] **Persistent token storage** — Disk-backed credential storage at `~/.mcp-skill/<name>/`
196
+ - [x] **Unified auth signature** — All auth types use `auth=None` in `__init__`
197
+ - [x] **Sanitize skill names** — Hyphens/dots converted to underscores for valid Python identifiers
198
+ - [ ] **Support MCP resources and prompts** — Currently only tools are introspected and generated
@@ -0,0 +1,169 @@
1
+ # mcp-skill
2
+
3
+ Turn any MCP server into a typed Python SDK.
4
+
5
+ > **Compile MCP tools into code.**
6
+
7
+ `mcp-skill` introspects an MCP server and generates a Python class where each tool becomes a typed async method.
8
+
9
+ ## Before and After
10
+
11
+ ### Before
12
+
13
+ Agents call MCP tools through the model loop — one round-trip per tool call:
14
+
15
+ ```
16
+ llm.call_tool("web_search_preview", {"query": "..."})
17
+ # → model decides next step → calls another tool → model decides again → ...
18
+ ```
19
+
20
+ ### After
21
+
22
+ Agents call tools directly in code:
23
+
24
+ ```python
25
+ result = await app.web_search_preview(
26
+ objective="find latest news",
27
+ search_queries=["topic X 2026"]
28
+ )
29
+ # Agent processes result in code — no round-trip back to model
30
+ ```
31
+
32
+ ## How It Works
33
+
34
+ ```
35
+ ┌─────────────┐ ┌───────────────┐ ┌────────────────────┐
36
+ │ MCP Server │─────▶│ mcp-skill │─────▶│ Generated Skill │
37
+ │ (any URL) │ │ CLI │ │ │
38
+ │ │ │ │ │ app.py │
39
+ │ Tools: │ │ 1. Connect │ │ ├─ Typed class │
40
+ │ - search │ │ 2. Introspec │ │ ├─ Async methods │
41
+ │ - fetch │ │ 3. Map types │ │ ├─ Auth + storage │
42
+ │ - ... │ │ 4. Generate │ │ └─ JSON parsing │
43
+ │ │ │ 5. Validate │ │ │
44
+ └─────────────┘ └───────────────┘ │ SKILL.md │
45
+ │ └─ Agent docs │
46
+ └────────────────────┘
47
+ ```
48
+
49
+ 1. Connects to the MCP server using [fastmcp](https://github.com/jlowin/fastmcp)
50
+ 2. Introspects all available tools via `list_tools()`
51
+ 3. Converts each tool's JSON Schema into Python type annotations
52
+ 4. Generates a typed `App` class where each MCP tool becomes an `async` method
53
+ 5. Validates the output with `ast.parse` → `ruff` → `ty`
54
+ 6. Generates `SKILL.md` with tool documentation and usage examples for agents
55
+
56
+ ## Motivation
57
+
58
+ MCP servers give agents access to tools, but every tool call round-trips through the model — request tool, execute, full result back into context, decide next step. For large payloads or sequential calls, this burns tokens and adds latency.
59
+
60
+ [Programmatic Tool Calling](https://platform.claude.com/cookbook/tool-use-programmatic-tool-calling-ptc) fixes this: the agent writes code that calls tools directly, without model round-trips per invocation. Fetch, filter, aggregate — all in one code block.
61
+
62
+ **mcp-skill** makes this possible by compiling any MCP server into a plain Python class. Each tool becomes a typed async method. The agent just writes Python.
63
+
64
+ ```python
65
+ from parallel_search.app import ParallelApp
66
+
67
+ app = ParallelApp(auth="sk-...")
68
+ result = await app.web_search_preview(
69
+ objective="find latest news on topic X",
70
+ search_queries=["topic X 2026"]
71
+ )
72
+ ```
73
+
74
+ ## Setup
75
+
76
+ ```bash
77
+ # Install with uv
78
+ uv pip install -e .
79
+
80
+ # Or use directly
81
+ uv run mcp-skill create --url https://your-mcp-server.com/mcp --auth api-key
82
+ ```
83
+
84
+ Requires [uv](https://github.com/astral-sh/uv) and Python 3.10+.
85
+
86
+ ## Usage
87
+
88
+ ```bash
89
+ # Interactive mode — prompts for URL, auth type, etc.
90
+ mcp-skill create
91
+
92
+ # Non-interactive mode
93
+ mcp-skill create \
94
+ --url https://search-mcp.parallel.ai/mcp \
95
+ --auth api-key \
96
+ --api-key YOUR_KEY \
97
+ --name parallel-search \
98
+ --non-interactive
99
+ ```
100
+
101
+ ### Generated Output
102
+
103
+ The skill lands in `.agents/skills/<name>/` as a Python package:
104
+
105
+ ```
106
+ .agents/skills/parallel_search/
107
+ ├── __init__.py
108
+ ├── app.py # Typed Python class wrapping the MCP server
109
+ └── SKILL.md # Agent-facing docs, dependencies, and usage
110
+ ```
111
+
112
+ Here's what the generated `app.py` looks like:
113
+
114
+ ```python
115
+ class ParallelApp:
116
+
117
+ def __init__(self, url: str = "https://...", auth=None) -> None:
118
+ ...
119
+
120
+ async def web_search_preview(
121
+ self,
122
+ objective: str,
123
+ search_queries: list[str],
124
+ ) -> dict[str, Any]:
125
+ """Search the web with multiple queries in parallel."""
126
+ ...
127
+
128
+ async def fetch_url(
129
+ self,
130
+ url: str,
131
+ max_length: int = None,
132
+ ) -> dict[str, Any]:
133
+ """Fetch and extract content from a URL."""
134
+ ...
135
+
136
+ def list_tools(self):
137
+ return [self.web_search_preview, self.fetch_url]
138
+ ```
139
+
140
+ Each method connects to the MCP server, calls the underlying tool, and returns parsed JSON. Auth credentials are persisted to disk (`~/.mcp-skill/<name>/`) after first use — provide once, reuse automatically.
141
+
142
+ ## Who Is This For?
143
+
144
+ Developers building:
145
+
146
+ - **MCP-based agents** that need direct tool access without model round-trips
147
+ - **Automation systems** using MCP tools as programmatic building blocks
148
+ - **Code-execution agents** using [Programmatic Tool Calling](https://platform.claude.com/cookbook/tool-use-programmatic-tool-calling-ptc)
149
+
150
+ ## Current Limitations
151
+
152
+ - **Auth**: Supports API key (Bearer or custom header), OAuth, and none — no mTLS or complex auth flows
153
+ - **Runtime dependency**: Generated code depends on [fastmcp](https://github.com/jlowin/fastmcp) for MCP client connections
154
+ - **Connection per call**: Each method creates a new MCP client connection (no pooling)
155
+ - **Tools only**: MCP resources and prompts not yet supported
156
+
157
+ ## Task List
158
+
159
+ Tracked improvements based on real-world usage:
160
+
161
+ - [x] **Fix output directory path** — Changed from `.agents/skill/<name>` to `.agents/skills/<name>`
162
+ - [x] **Add dependency info to SKILL.md** — Dependencies listed with `uv` and `pip` install commands
163
+ - [x] **Generate `__init__.py`** — Skill directory is a proper Python package
164
+ - [x] **Post-generation validation** — `ast.parse` → `ruff check` → `ty check` with `uvx` fallback
165
+ - [x] **Package-style imports** — Moved `app.py` to skill root; import via `from <skill>.app import <Class>`
166
+ - [x] **Persistent token storage** — Disk-backed credential storage at `~/.mcp-skill/<name>/`
167
+ - [x] **Unified auth signature** — All auth types use `auth=None` in `__init__`
168
+ - [x] **Sanitize skill names** — Hyphens/dots converted to underscores for valid Python identifiers
169
+ - [ ] **Support MCP resources and prompts** — Currently only tools are introspected and generated
@@ -0,0 +1,43 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mcp-skill"
7
+ version = "0.2.0"
8
+ description = "Convert any MCP server into an Agent Skill"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ keywords = ["mcp", "agent", "skill", "code-generation", "fastmcp", "llm"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Software Development :: Code Generators",
23
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ ]
25
+ dependencies = [
26
+ "fastmcp>=2.0",
27
+ "click>=8.0",
28
+ "jinja2>=3.1",
29
+ "ruff>=0.15.4",
30
+ "ty>=0.0.20",
31
+ "py-key-value-aio[disk]",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/manojbajaj95/mcp-skill"
36
+ Repository = "https://github.com/manojbajaj95/mcp-skill"
37
+ Issues = "https://github.com/manojbajaj95/mcp-skill/issues"
38
+
39
+ [project.scripts]
40
+ mcp-skill = "mcp_skill.cli:main"
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["src/mcp_skill"]
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3
+ "packages": {
4
+ ".": {
5
+ "release-type": "python",
6
+ "package-name": "mcp-skill",
7
+ "bump-minor-pre-major": true,
8
+ "changelog-path": "CHANGELOG.md",
9
+ "include-component-in-tag": false
10
+ }
11
+ }
12
+ }