agentskills-mcp-server 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.
- agentskills_mcp_server-0.2.0/PKG-INFO +179 -0
- agentskills_mcp_server-0.2.0/README.md +154 -0
- agentskills_mcp_server-0.2.0/agentskills_mcp_server/__init__.py +35 -0
- agentskills_mcp_server-0.2.0/agentskills_mcp_server/__main__.py +124 -0
- agentskills_mcp_server-0.2.0/agentskills_mcp_server/config.py +50 -0
- agentskills_mcp_server-0.2.0/agentskills_mcp_server/py.typed +0 -0
- agentskills_mcp_server-0.2.0/agentskills_mcp_server/server.py +248 -0
- agentskills_mcp_server-0.2.0/pyproject.toml +34 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentskills-mcp-server
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: MCP server integration for the Agent Skills format — expose skills as MCP tools and resources (https://agentskills.io)
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Pratik Panda
|
|
7
|
+
Requires-Python: >=3.12,<4.0
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Provides-Extra: fs
|
|
17
|
+
Provides-Extra: http
|
|
18
|
+
Requires-Dist: agentskills-core (>=0.1.0)
|
|
19
|
+
Requires-Dist: mcp (>=1.0)
|
|
20
|
+
Requires-Dist: pydantic (>=2.0)
|
|
21
|
+
Project-URL: Homepage, https://agentskills.io
|
|
22
|
+
Project-URL: Repository, https://github.com/pratikxpanda/agentskills-sdk
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# agentskills-mcp-server
|
|
26
|
+
|
|
27
|
+
[](https://pypi.org/project/agentskills-mcp-server/)
|
|
28
|
+
[](https://pypi.org/project/agentskills-mcp-server/)
|
|
29
|
+
[](https://github.com/pratikxpanda/agentskills-sdk/blob/main/LICENSE)
|
|
30
|
+
|
|
31
|
+
> MCP server integration for the [Agent Skills SDK](../../README.md) — expose a skill registry as an MCP server.
|
|
32
|
+
|
|
33
|
+
Creates a [Model Context Protocol](https://modelcontextprotocol.io/) server from a `SkillRegistry`, exposing skills as MCP tools and resources. Works with any MCP-compatible client (Claude Desktop, VS Code, custom clients, etc.).
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install agentskills-mcp-server
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
With provider extras:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install agentskills-mcp-server[fs] # filesystem provider
|
|
45
|
+
pip install agentskills-mcp-server[http] # HTTP provider
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Requires Python 3.12+. Installs `agentskills-core`, `mcp`, and `pydantic` as dependencies.
|
|
49
|
+
|
|
50
|
+
## Quick Start (CLI)
|
|
51
|
+
|
|
52
|
+
Create a `server.json` config file:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"name": "My Skills Server",
|
|
57
|
+
"skills": [
|
|
58
|
+
{
|
|
59
|
+
"id": "incident-response",
|
|
60
|
+
"provider": "fs",
|
|
61
|
+
"options": {"root": "./skills"}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Start the server:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python -m agentskills_mcp_server --config server.json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
With Streamable HTTP transport:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python -m agentskills_mcp_server --config server.json --transport streamable-http
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The server listens on `http://127.0.0.1:8000/mcp`.
|
|
80
|
+
|
|
81
|
+
### MCP Client Integration
|
|
82
|
+
|
|
83
|
+
Any MCP-compatible client (Claude Desktop, VS Code, etc.) can connect to the server.
|
|
84
|
+
|
|
85
|
+
Stdio (local):
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"command": "python",
|
|
90
|
+
"args": ["-m", "agentskills_mcp_server", "--config", "server.json"]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Streamable HTTP (remote):
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"url": "http://127.0.0.1:8000/mcp"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Config Reference
|
|
103
|
+
|
|
104
|
+
The `server.json` file supports the following structure:
|
|
105
|
+
|
|
106
|
+
| Field | Type | Required | Description |
|
|
107
|
+
| --- | --- | --- | --- |
|
|
108
|
+
| `name` | `str` | Yes | Display name shown to MCP clients |
|
|
109
|
+
| `instructions` | `str` | No | Server-level instructions sent during handshake |
|
|
110
|
+
| `skills` | `list` | Yes | One or more skill definitions (see below) |
|
|
111
|
+
|
|
112
|
+
Each skill entry:
|
|
113
|
+
|
|
114
|
+
| Field | Type | Required | Description |
|
|
115
|
+
| --- | --- | --- | --- |
|
|
116
|
+
| `id` | `str` | Yes | Skill identifier |
|
|
117
|
+
| `provider` | `str` | Yes | Provider type: `"fs"` or `"http"` |
|
|
118
|
+
| `options` | `dict` | No | Provider-specific options |
|
|
119
|
+
|
|
120
|
+
**Provider options:**
|
|
121
|
+
|
|
122
|
+
- **`fs`**: `root` (path to skills directory, default `"."`)
|
|
123
|
+
- **`http`**: `base_url` (required), `headers` (optional), `params` (optional query string parameters)
|
|
124
|
+
|
|
125
|
+
## Programmatic Usage
|
|
126
|
+
|
|
127
|
+
For custom providers or advanced setups, use the Python API directly:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from agentskills_core import SkillRegistry
|
|
131
|
+
from agentskills_mcp_server import create_mcp_server
|
|
132
|
+
|
|
133
|
+
registry = SkillRegistry()
|
|
134
|
+
await registry.register("incident-response", my_custom_provider)
|
|
135
|
+
|
|
136
|
+
server = create_mcp_server(registry, name="My Skills Server")
|
|
137
|
+
server.run() # stdio by default
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Tools
|
|
141
|
+
|
|
142
|
+
The server exposes tools that let the LLM agent access skill content:
|
|
143
|
+
|
|
144
|
+
| Tool | Parameters | Description |
|
|
145
|
+
| --- | --- | --- |
|
|
146
|
+
| `get_skill_metadata` | `skill_id` | Read frontmatter (name, description, etc.) |
|
|
147
|
+
| `get_skill_body` | `skill_id` | Load full skill instructions |
|
|
148
|
+
| `get_skill_reference` | `skill_id`, `name` | Read a reference document |
|
|
149
|
+
| `get_skill_script` | `skill_id`, `name` | Read a script |
|
|
150
|
+
| `get_skill_asset` | `skill_id`, `name` | Read an asset |
|
|
151
|
+
|
|
152
|
+
## Resources
|
|
153
|
+
|
|
154
|
+
The server provides resources for system-prompt context:
|
|
155
|
+
|
|
156
|
+
| URI | Description |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| `skills://catalog/xml` | XML catalog of all registered skills |
|
|
159
|
+
| `skills://catalog/markdown` | Markdown catalog of all registered skills |
|
|
160
|
+
| `skills://tools-usage-instructions` | Workflow instructions for using the tools |
|
|
161
|
+
|
|
162
|
+
The MCP client reads these resources and injects them into the system prompt, giving the agent both *what* skills exist and *how* to interact with them.
|
|
163
|
+
|
|
164
|
+
## API
|
|
165
|
+
|
|
166
|
+
### `create_mcp_server(registry, *, name, instructions=None) -> FastMCP`
|
|
167
|
+
|
|
168
|
+
| Parameter | Type | Description |
|
|
169
|
+
| --- | --- | --- |
|
|
170
|
+
| `registry` | `SkillRegistry` | The registry whose skills are exposed |
|
|
171
|
+
| `name` | `str` | Display name for the MCP server (required) |
|
|
172
|
+
| `instructions` | `str \| None` | Optional server-level instructions sent to clients |
|
|
173
|
+
|
|
174
|
+
Returns a configured `FastMCP` instance ready for `server.run()`.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT
|
|
179
|
+
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# agentskills-mcp-server
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/agentskills-mcp-server/)
|
|
4
|
+
[](https://pypi.org/project/agentskills-mcp-server/)
|
|
5
|
+
[](https://github.com/pratikxpanda/agentskills-sdk/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
> MCP server integration for the [Agent Skills SDK](../../README.md) — expose a skill registry as an MCP server.
|
|
8
|
+
|
|
9
|
+
Creates a [Model Context Protocol](https://modelcontextprotocol.io/) server from a `SkillRegistry`, exposing skills as MCP tools and resources. Works with any MCP-compatible client (Claude Desktop, VS Code, custom clients, etc.).
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install agentskills-mcp-server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
With provider extras:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install agentskills-mcp-server[fs] # filesystem provider
|
|
21
|
+
pip install agentskills-mcp-server[http] # HTTP provider
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Requires Python 3.12+. Installs `agentskills-core`, `mcp`, and `pydantic` as dependencies.
|
|
25
|
+
|
|
26
|
+
## Quick Start (CLI)
|
|
27
|
+
|
|
28
|
+
Create a `server.json` config file:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"name": "My Skills Server",
|
|
33
|
+
"skills": [
|
|
34
|
+
{
|
|
35
|
+
"id": "incident-response",
|
|
36
|
+
"provider": "fs",
|
|
37
|
+
"options": {"root": "./skills"}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Start the server:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
python -m agentskills_mcp_server --config server.json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
With Streamable HTTP transport:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python -m agentskills_mcp_server --config server.json --transport streamable-http
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The server listens on `http://127.0.0.1:8000/mcp`.
|
|
56
|
+
|
|
57
|
+
### MCP Client Integration
|
|
58
|
+
|
|
59
|
+
Any MCP-compatible client (Claude Desktop, VS Code, etc.) can connect to the server.
|
|
60
|
+
|
|
61
|
+
Stdio (local):
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"command": "python",
|
|
66
|
+
"args": ["-m", "agentskills_mcp_server", "--config", "server.json"]
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Streamable HTTP (remote):
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"url": "http://127.0.0.1:8000/mcp"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Config Reference
|
|
79
|
+
|
|
80
|
+
The `server.json` file supports the following structure:
|
|
81
|
+
|
|
82
|
+
| Field | Type | Required | Description |
|
|
83
|
+
| --- | --- | --- | --- |
|
|
84
|
+
| `name` | `str` | Yes | Display name shown to MCP clients |
|
|
85
|
+
| `instructions` | `str` | No | Server-level instructions sent during handshake |
|
|
86
|
+
| `skills` | `list` | Yes | One or more skill definitions (see below) |
|
|
87
|
+
|
|
88
|
+
Each skill entry:
|
|
89
|
+
|
|
90
|
+
| Field | Type | Required | Description |
|
|
91
|
+
| --- | --- | --- | --- |
|
|
92
|
+
| `id` | `str` | Yes | Skill identifier |
|
|
93
|
+
| `provider` | `str` | Yes | Provider type: `"fs"` or `"http"` |
|
|
94
|
+
| `options` | `dict` | No | Provider-specific options |
|
|
95
|
+
|
|
96
|
+
**Provider options:**
|
|
97
|
+
|
|
98
|
+
- **`fs`**: `root` (path to skills directory, default `"."`)
|
|
99
|
+
- **`http`**: `base_url` (required), `headers` (optional), `params` (optional query string parameters)
|
|
100
|
+
|
|
101
|
+
## Programmatic Usage
|
|
102
|
+
|
|
103
|
+
For custom providers or advanced setups, use the Python API directly:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from agentskills_core import SkillRegistry
|
|
107
|
+
from agentskills_mcp_server import create_mcp_server
|
|
108
|
+
|
|
109
|
+
registry = SkillRegistry()
|
|
110
|
+
await registry.register("incident-response", my_custom_provider)
|
|
111
|
+
|
|
112
|
+
server = create_mcp_server(registry, name="My Skills Server")
|
|
113
|
+
server.run() # stdio by default
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Tools
|
|
117
|
+
|
|
118
|
+
The server exposes tools that let the LLM agent access skill content:
|
|
119
|
+
|
|
120
|
+
| Tool | Parameters | Description |
|
|
121
|
+
| --- | --- | --- |
|
|
122
|
+
| `get_skill_metadata` | `skill_id` | Read frontmatter (name, description, etc.) |
|
|
123
|
+
| `get_skill_body` | `skill_id` | Load full skill instructions |
|
|
124
|
+
| `get_skill_reference` | `skill_id`, `name` | Read a reference document |
|
|
125
|
+
| `get_skill_script` | `skill_id`, `name` | Read a script |
|
|
126
|
+
| `get_skill_asset` | `skill_id`, `name` | Read an asset |
|
|
127
|
+
|
|
128
|
+
## Resources
|
|
129
|
+
|
|
130
|
+
The server provides resources for system-prompt context:
|
|
131
|
+
|
|
132
|
+
| URI | Description |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| `skills://catalog/xml` | XML catalog of all registered skills |
|
|
135
|
+
| `skills://catalog/markdown` | Markdown catalog of all registered skills |
|
|
136
|
+
| `skills://tools-usage-instructions` | Workflow instructions for using the tools |
|
|
137
|
+
|
|
138
|
+
The MCP client reads these resources and injects them into the system prompt, giving the agent both *what* skills exist and *how* to interact with them.
|
|
139
|
+
|
|
140
|
+
## API
|
|
141
|
+
|
|
142
|
+
### `create_mcp_server(registry, *, name, instructions=None) -> FastMCP`
|
|
143
|
+
|
|
144
|
+
| Parameter | Type | Description |
|
|
145
|
+
| --- | --- | --- |
|
|
146
|
+
| `registry` | `SkillRegistry` | The registry whose skills are exposed |
|
|
147
|
+
| `name` | `str` | Display name for the MCP server (required) |
|
|
148
|
+
| `instructions` | `str \| None` | Optional server-level instructions sent to clients |
|
|
149
|
+
|
|
150
|
+
Returns a configured `FastMCP` instance ready for `server.run()`.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""MCP server integration for Agent Skills.
|
|
2
|
+
|
|
3
|
+
This package bridges :mod:`agentskills_core` and the `Model Context
|
|
4
|
+
Protocol <https://modelcontextprotocol.io>`_, providing:
|
|
5
|
+
|
|
6
|
+
* :func:`create_mcp_server` -- builds a FastMCP server from a
|
|
7
|
+
:class:`~agentskills_core.SkillRegistry`. Useful when you have
|
|
8
|
+
custom providers or need full control over registration.
|
|
9
|
+
* CLI entry-point (``python -m agentskills_mcp_server --config server.json``)
|
|
10
|
+
for zero-code server startup.
|
|
11
|
+
|
|
12
|
+
Quick start (programmatic)::
|
|
13
|
+
|
|
14
|
+
from agentskills_core import SkillRegistry
|
|
15
|
+
from agentskills_mcp_server import create_mcp_server
|
|
16
|
+
|
|
17
|
+
registry = SkillRegistry()
|
|
18
|
+
await registry.register("incident-response", my_custom_provider)
|
|
19
|
+
server = create_mcp_server(registry, name="My Agent")
|
|
20
|
+
server.run() # stdio by default
|
|
21
|
+
|
|
22
|
+
CLI::
|
|
23
|
+
|
|
24
|
+
python -m agentskills_mcp_server --config server.json
|
|
25
|
+
|
|
26
|
+
Install::
|
|
27
|
+
|
|
28
|
+
pip install agentskills-mcp-server
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from agentskills_mcp_server.server import create_mcp_server
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"create_mcp_server",
|
|
35
|
+
]
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""Run an Agent Skills MCP server from a config file.
|
|
2
|
+
|
|
3
|
+
Usage::
|
|
4
|
+
|
|
5
|
+
python -m agentskills_mcp_server --config server.json
|
|
6
|
+
python -m agentskills_mcp_server --config server.yaml
|
|
7
|
+
python -m agentskills_mcp_server --config server.json --transport streamable-http
|
|
8
|
+
|
|
9
|
+
The config file is a JSON or YAML document conforming to
|
|
10
|
+
:class:`~agentskills_mcp_server.config.ServerConfig`.
|
|
11
|
+
|
|
12
|
+
Example ``server.json``::
|
|
13
|
+
|
|
14
|
+
{
|
|
15
|
+
"name": "My Skills Server",
|
|
16
|
+
"skills": [
|
|
17
|
+
{
|
|
18
|
+
"id": "incident-response",
|
|
19
|
+
"provider": "fs",
|
|
20
|
+
"options": {"root": "./skills"}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "cloud-runbooks",
|
|
24
|
+
"provider": "http",
|
|
25
|
+
"options": {
|
|
26
|
+
"base_url": "https://cdn.example.com/skills",
|
|
27
|
+
"headers": {"Authorization": "Bearer <token>"},
|
|
28
|
+
"params": {"sv": "2020-08-04", "sig": "<sas-token>"}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
MCP client integration (stdio transport)::
|
|
35
|
+
|
|
36
|
+
{
|
|
37
|
+
"command": "python",
|
|
38
|
+
"args": ["-m", "agentskills_mcp_server", "--config", "server.json"]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
MCP client integration (streamable-http transport)::
|
|
42
|
+
|
|
43
|
+
{
|
|
44
|
+
"url": "http://127.0.0.1:8000/mcp"
|
|
45
|
+
}
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
from __future__ import annotations
|
|
49
|
+
|
|
50
|
+
import argparse
|
|
51
|
+
import asyncio
|
|
52
|
+
import json
|
|
53
|
+
import sys
|
|
54
|
+
from pathlib import Path
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def main() -> None:
|
|
58
|
+
"""Parse CLI arguments, load config, and start the MCP server."""
|
|
59
|
+
parser = argparse.ArgumentParser(
|
|
60
|
+
prog="agentskills_mcp_server",
|
|
61
|
+
description="Start an Agent Skills MCP server from a config file.",
|
|
62
|
+
)
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"--config",
|
|
65
|
+
required=True,
|
|
66
|
+
type=Path,
|
|
67
|
+
help="Path to a JSON or YAML configuration file.",
|
|
68
|
+
)
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"--transport",
|
|
71
|
+
default="stdio",
|
|
72
|
+
choices=["stdio", "streamable-http"],
|
|
73
|
+
help="MCP transport type (default: stdio).",
|
|
74
|
+
)
|
|
75
|
+
args = parser.parse_args()
|
|
76
|
+
|
|
77
|
+
# ------------------------------------------------------------------
|
|
78
|
+
# Load config file
|
|
79
|
+
# ------------------------------------------------------------------
|
|
80
|
+
config_path: Path = args.config
|
|
81
|
+
if not config_path.exists():
|
|
82
|
+
print(
|
|
83
|
+
f"Error: config file not found: {config_path}",
|
|
84
|
+
file=sys.stderr,
|
|
85
|
+
)
|
|
86
|
+
sys.exit(1)
|
|
87
|
+
|
|
88
|
+
raw = config_path.read_text(encoding="utf-8")
|
|
89
|
+
|
|
90
|
+
if config_path.suffix in (".yaml", ".yml"):
|
|
91
|
+
try:
|
|
92
|
+
import yaml # type: ignore[import-untyped]
|
|
93
|
+
except ImportError:
|
|
94
|
+
print(
|
|
95
|
+
"Error: YAML config files require pyyaml. Install with: pip install pyyaml",
|
|
96
|
+
file=sys.stderr,
|
|
97
|
+
)
|
|
98
|
+
sys.exit(1)
|
|
99
|
+
data = yaml.safe_load(raw)
|
|
100
|
+
else:
|
|
101
|
+
data = json.loads(raw)
|
|
102
|
+
|
|
103
|
+
# ------------------------------------------------------------------
|
|
104
|
+
# Build and run
|
|
105
|
+
# ------------------------------------------------------------------
|
|
106
|
+
from agentskills_core import SkillRegistry
|
|
107
|
+
from agentskills_mcp_server.config import ServerConfig
|
|
108
|
+
from agentskills_mcp_server.server import _resolve_provider, create_mcp_server
|
|
109
|
+
|
|
110
|
+
config = ServerConfig(**data)
|
|
111
|
+
|
|
112
|
+
async def _build() -> object:
|
|
113
|
+
registry = SkillRegistry()
|
|
114
|
+
for skill_cfg in config.skills:
|
|
115
|
+
provider = _resolve_provider(skill_cfg.provider, skill_cfg.options)
|
|
116
|
+
await registry.register(skill_cfg.id, provider)
|
|
117
|
+
return create_mcp_server(registry, name=config.name, instructions=config.instructions)
|
|
118
|
+
|
|
119
|
+
server = asyncio.run(_build())
|
|
120
|
+
server.run(transport=args.transport)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
main()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Pydantic configuration models for Agent Skills MCP servers.
|
|
2
|
+
|
|
3
|
+
This module defines the declarative configuration schema used by
|
|
4
|
+
the CLI (``python -m agentskills_mcp_server --config server.json``).
|
|
5
|
+
|
|
6
|
+
Example config (JSON)::
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
"name": "My Skills Server",
|
|
10
|
+
"skills": [
|
|
11
|
+
{
|
|
12
|
+
"id": "incident-response",
|
|
13
|
+
"provider": "fs",
|
|
14
|
+
"options": {"root": "./skills"}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from pydantic import BaseModel, Field
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SkillConfig(BaseModel):
|
|
28
|
+
"""Configuration for a single skill."""
|
|
29
|
+
|
|
30
|
+
id: str = Field(..., description="Skill identifier")
|
|
31
|
+
provider: str = Field(..., description="Provider type (e.g., 'fs', 'http')")
|
|
32
|
+
options: dict[str, Any] = Field(
|
|
33
|
+
default_factory=dict,
|
|
34
|
+
description="Provider-specific options passed to the provider constructor",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ServerConfig(BaseModel):
|
|
39
|
+
"""Top-level configuration for an Agent Skills MCP server.
|
|
40
|
+
|
|
41
|
+
Attributes:
|
|
42
|
+
name: Display name shown to MCP clients during initialization.
|
|
43
|
+
instructions: Optional server-level instructions sent to the
|
|
44
|
+
client during the MCP handshake.
|
|
45
|
+
skills: One or more skill definitions to register.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
name: str = Field(..., description="Display name for the MCP server")
|
|
49
|
+
instructions: str | None = Field(None, description="Optional server-level instructions")
|
|
50
|
+
skills: list[SkillConfig] = Field(..., description="Skills to register", min_length=1)
|
|
File without changes
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""MCP server builder for Agent Skills.
|
|
2
|
+
|
|
3
|
+
This module creates a `FastMCP <https://pypi.org/project/mcp/>`_ server
|
|
4
|
+
that exposes a :class:`~agentskills_core.SkillRegistry` as a set of MCP
|
|
5
|
+
tools and resources.
|
|
6
|
+
|
|
7
|
+
Tools
|
|
8
|
+
-----
|
|
9
|
+
Tools give the LLM agent access to skill content:
|
|
10
|
+
|
|
11
|
+
============================== =============================================
|
|
12
|
+
Tool name Description
|
|
13
|
+
============================== =============================================
|
|
14
|
+
``get_skill_metadata`` Read frontmatter (name, description, ...).
|
|
15
|
+
``get_skill_body`` Load full skill instructions.
|
|
16
|
+
``get_skill_reference`` Read a single reference document.
|
|
17
|
+
``get_skill_script`` Read a single script.
|
|
18
|
+
``get_skill_asset`` Read a single asset.
|
|
19
|
+
============================== =============================================
|
|
20
|
+
|
|
21
|
+
Resources
|
|
22
|
+
---------
|
|
23
|
+
Resources provide context for the system prompt:
|
|
24
|
+
|
|
25
|
+
========================================== ==============================================
|
|
26
|
+
URI Description
|
|
27
|
+
========================================== ==============================================
|
|
28
|
+
``skills://catalog/xml`` XML catalog of all registered skills.
|
|
29
|
+
``skills://catalog/markdown`` Markdown catalog of all registered skills.
|
|
30
|
+
``skills://tools-usage-instructions`` Workflow instructions for using the tools.
|
|
31
|
+
========================================== ==============================================
|
|
32
|
+
|
|
33
|
+
The developer reads these resources and injects them into the system
|
|
34
|
+
prompt, giving the LLM agent both *what* skills exist and *how* to
|
|
35
|
+
interact with them.
|
|
36
|
+
|
|
37
|
+
Example::
|
|
38
|
+
|
|
39
|
+
from agentskills_mcp_server import create_mcp_server
|
|
40
|
+
|
|
41
|
+
server = create_mcp_server(registry, name="My Agent")
|
|
42
|
+
server.run() # stdio by default
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
import json
|
|
48
|
+
from pathlib import Path
|
|
49
|
+
from typing import Any
|
|
50
|
+
|
|
51
|
+
from mcp.server.fastmcp import FastMCP
|
|
52
|
+
|
|
53
|
+
from agentskills_core import SkillProvider, SkillRegistry
|
|
54
|
+
|
|
55
|
+
# ------------------------------------------------------------------
|
|
56
|
+
# Provider resolution
|
|
57
|
+
# ------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
#: Provider types that are recognized by :func:`_resolve_provider`.
|
|
60
|
+
SUPPORTED_PROVIDERS: frozenset[str] = frozenset({"fs", "http"})
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _resolve_provider(provider_type: str, options: dict[str, Any]) -> SkillProvider:
|
|
64
|
+
"""Map a provider type string and options to a concrete provider.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
provider_type: One of the :data:`SUPPORTED_PROVIDERS` keys.
|
|
68
|
+
options: Keyword arguments forwarded to the provider
|
|
69
|
+
constructor. Unknown keys are silently ignored for
|
|
70
|
+
safety (e.g. a ``client`` key cannot be serialized
|
|
71
|
+
to JSON and must not be passed).
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
A ready-to-use :class:`~agentskills_core.SkillProvider`.
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
ImportError: If the required provider package is not installed.
|
|
78
|
+
ValueError: If *provider_type* is not recognized.
|
|
79
|
+
"""
|
|
80
|
+
if provider_type == "fs":
|
|
81
|
+
try:
|
|
82
|
+
from agentskills_fs import LocalFileSystemSkillProvider
|
|
83
|
+
except ImportError as exc:
|
|
84
|
+
raise ImportError(
|
|
85
|
+
"Provider 'fs' requires the agentskills-fs package. "
|
|
86
|
+
"Install it with: pip install agentskills-fs"
|
|
87
|
+
) from exc
|
|
88
|
+
root = Path(options.get("root", "."))
|
|
89
|
+
return LocalFileSystemSkillProvider(root=root)
|
|
90
|
+
|
|
91
|
+
if provider_type == "http":
|
|
92
|
+
try:
|
|
93
|
+
from agentskills_http import HTTPStaticFileSkillProvider
|
|
94
|
+
except ImportError as exc:
|
|
95
|
+
raise ImportError(
|
|
96
|
+
"Provider 'http' requires the agentskills-http package. "
|
|
97
|
+
"Install it with: pip install agentskills-http"
|
|
98
|
+
) from exc
|
|
99
|
+
# Only pass constructor-safe keys; runtime objects like
|
|
100
|
+
# ``client`` cannot be serialized to a config file.
|
|
101
|
+
safe_http_keys = {"base_url", "headers", "params"}
|
|
102
|
+
filtered = {k: v for k, v in options.items() if k in safe_http_keys}
|
|
103
|
+
return HTTPStaticFileSkillProvider(**filtered)
|
|
104
|
+
|
|
105
|
+
raise ValueError(
|
|
106
|
+
f"Unknown provider type: {provider_type!r}. "
|
|
107
|
+
f"Supported types: {', '.join(sorted(SUPPORTED_PROVIDERS))}"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# ------------------------------------------------------------------
|
|
112
|
+
# Server builder
|
|
113
|
+
# ------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def create_mcp_server(
|
|
117
|
+
registry: SkillRegistry,
|
|
118
|
+
*,
|
|
119
|
+
name: str,
|
|
120
|
+
instructions: str | None = None,
|
|
121
|
+
) -> FastMCP:
|
|
122
|
+
"""Build an MCP server that exposes an Agent Skills registry.
|
|
123
|
+
|
|
124
|
+
The returned :class:`~mcp.server.fastmcp.FastMCP` server is
|
|
125
|
+
transport-agnostic. Call ``server.run()`` to start with the
|
|
126
|
+
default stdio transport, or ``server.run(transport="streamable-http")``
|
|
127
|
+
for HTTP.
|
|
128
|
+
|
|
129
|
+
**Tools** let the LLM agent read skill content (metadata,
|
|
130
|
+
body, references, scripts, assets). **Resources** provide
|
|
131
|
+
the skill catalog and usage instructions for system-prompt
|
|
132
|
+
injection.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
registry: The :class:`~agentskills_core.SkillRegistry` whose
|
|
136
|
+
skills should be exposed via MCP.
|
|
137
|
+
name: Display name for the MCP server. Clients see this
|
|
138
|
+
during the MCP initialization handshake. Required.
|
|
139
|
+
instructions: Optional server-level instructions sent to the
|
|
140
|
+
MCP client during initialization. Use this to describe
|
|
141
|
+
the server's purpose or capabilities.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
A configured :class:`~mcp.server.fastmcp.FastMCP` server
|
|
145
|
+
instance, ready for ``server.run()``.
|
|
146
|
+
"""
|
|
147
|
+
mcp = FastMCP(name, instructions=instructions)
|
|
148
|
+
|
|
149
|
+
# ------------------------------------------------------------------
|
|
150
|
+
# Tools
|
|
151
|
+
# ------------------------------------------------------------------
|
|
152
|
+
|
|
153
|
+
@mcp.tool()
|
|
154
|
+
async def get_skill_metadata(skill_id: str) -> str:
|
|
155
|
+
"""Get structured metadata (name, description, and optional fields like license, compatibility, metadata) for a specific skill.""" # noqa: E501
|
|
156
|
+
skill = registry.get_skill(skill_id)
|
|
157
|
+
return json.dumps(await skill.get_metadata())
|
|
158
|
+
|
|
159
|
+
@mcp.tool()
|
|
160
|
+
async def get_skill_body(skill_id: str) -> str:
|
|
161
|
+
"""Get the full instructions and guidance (markdown body) for a specific skill."""
|
|
162
|
+
skill = registry.get_skill(skill_id)
|
|
163
|
+
return await skill.get_body()
|
|
164
|
+
|
|
165
|
+
@mcp.tool()
|
|
166
|
+
async def get_skill_reference(skill_id: str, name: str) -> str:
|
|
167
|
+
"""Get the full content of a specific reference document from a skill.
|
|
168
|
+
|
|
169
|
+
Provide both skill_id and the reference name. Binary content is
|
|
170
|
+
decoded as UTF-8 with replacement characters for non-decodable bytes.
|
|
171
|
+
"""
|
|
172
|
+
skill = registry.get_skill(skill_id)
|
|
173
|
+
return (await skill.get_reference(name)).decode("utf-8", errors="replace")
|
|
174
|
+
|
|
175
|
+
@mcp.tool()
|
|
176
|
+
async def get_skill_asset(skill_id: str, name: str) -> str:
|
|
177
|
+
"""Get the content of a specific asset from a skill.
|
|
178
|
+
|
|
179
|
+
Provide both skill_id and the asset name. Binary content is
|
|
180
|
+
decoded as UTF-8 with replacement characters for non-decodable bytes.
|
|
181
|
+
"""
|
|
182
|
+
skill = registry.get_skill(skill_id)
|
|
183
|
+
return (await skill.get_asset(name)).decode("utf-8", errors="replace")
|
|
184
|
+
|
|
185
|
+
@mcp.tool()
|
|
186
|
+
async def get_skill_script(skill_id: str, name: str) -> str:
|
|
187
|
+
"""Get the content of a specific script from a skill.
|
|
188
|
+
|
|
189
|
+
Provide both skill_id and the script name. Binary content is
|
|
190
|
+
decoded as UTF-8 with replacement characters for non-decodable bytes.
|
|
191
|
+
"""
|
|
192
|
+
skill = registry.get_skill(skill_id)
|
|
193
|
+
return (await skill.get_script(name)).decode("utf-8", errors="replace")
|
|
194
|
+
|
|
195
|
+
# ------------------------------------------------------------------
|
|
196
|
+
# Resources
|
|
197
|
+
# ------------------------------------------------------------------
|
|
198
|
+
|
|
199
|
+
@mcp.resource("skills://catalog/xml")
|
|
200
|
+
async def skills_catalog_xml() -> str:
|
|
201
|
+
"""XML catalog of all registered skills for system-prompt injection."""
|
|
202
|
+
return await registry.get_skills_catalog(format="xml")
|
|
203
|
+
|
|
204
|
+
@mcp.resource("skills://catalog/markdown")
|
|
205
|
+
async def skills_catalog_markdown() -> str:
|
|
206
|
+
"""Markdown catalog of all registered skills for system-prompt injection."""
|
|
207
|
+
return await registry.get_skills_catalog(format="markdown")
|
|
208
|
+
|
|
209
|
+
@mcp.resource("skills://tools-usage-instructions")
|
|
210
|
+
def skills_tools_usage_instructions() -> str:
|
|
211
|
+
"""Workflow instructions explaining how to use the Agent Skills tools."""
|
|
212
|
+
return _TOOLS_USAGE_INSTRUCTIONS
|
|
213
|
+
|
|
214
|
+
return mcp
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
_TOOLS_USAGE_INSTRUCTIONS = """\
|
|
218
|
+
## How to Use Agent Skills
|
|
219
|
+
|
|
220
|
+
You have access to a set of **Agent Skills** — curated knowledge \
|
|
221
|
+
bundles that contain step-by-step instructions, reference documents, \
|
|
222
|
+
scripts, and assets. The available skills are listed in the catalog.
|
|
223
|
+
|
|
224
|
+
### Workflow
|
|
225
|
+
|
|
226
|
+
1. **Pick a skill** — Choose the most relevant skill from the catalog \
|
|
227
|
+
based on the user's request.
|
|
228
|
+
2. **Read metadata** — Call `get_skill_metadata(skill_id)` to get \
|
|
229
|
+
structured information (name, description, and optional fields).
|
|
230
|
+
3. **Read the body** — Call `get_skill_body(skill_id)` to load the \
|
|
231
|
+
full instructions. Follow these instructions carefully.
|
|
232
|
+
4. **Fetch resources on demand** — The skill body will reference \
|
|
233
|
+
specific resources by name. Use the appropriate tool to retrieve them:
|
|
234
|
+
- `get_skill_reference(skill_id, name)` — reference documents \
|
|
235
|
+
(policies, templates, runbooks)
|
|
236
|
+
- `get_skill_script(skill_id, name)` — executable scripts
|
|
237
|
+
- `get_skill_asset(skill_id, name)` — diagrams, data files, or \
|
|
238
|
+
other assets
|
|
239
|
+
|
|
240
|
+
### Important guidelines
|
|
241
|
+
|
|
242
|
+
- **Do not guess resource names.** Only fetch resources that are \
|
|
243
|
+
explicitly mentioned in the skill body.
|
|
244
|
+
- **Follow progressive disclosure.** Read the skill body first, then \
|
|
245
|
+
fetch only the resources you need for the current step.
|
|
246
|
+
- **One skill at a time.** Focus on the most relevant skill for the \
|
|
247
|
+
user's request. If multiple skills apply, address them sequentially.\
|
|
248
|
+
"""
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "agentskills-mcp-server"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "MCP server integration for the Agent Skills format — expose skills as MCP tools and resources (https://agentskills.io)"
|
|
5
|
+
license = "MIT"
|
|
6
|
+
authors = ["Pratik Panda"]
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
homepage = "https://agentskills.io"
|
|
9
|
+
repository = "https://github.com/pratikxpanda/agentskills-sdk"
|
|
10
|
+
packages = [{include = "agentskills_mcp_server"}]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Topic :: Software Development :: Libraries",
|
|
15
|
+
"Programming Language :: Python :: 3.12",
|
|
16
|
+
"Programming Language :: Python :: 3.13",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.poetry.dependencies]
|
|
20
|
+
python = ">=3.12,<4.0"
|
|
21
|
+
agentskills-core = ">=0.1.0"
|
|
22
|
+
mcp = ">=1.0"
|
|
23
|
+
pydantic = ">=2.0"
|
|
24
|
+
|
|
25
|
+
[tool.poetry.extras]
|
|
26
|
+
fs = ["agentskills-fs"]
|
|
27
|
+
http = ["agentskills-http"]
|
|
28
|
+
|
|
29
|
+
[tool.poetry.scripts]
|
|
30
|
+
agentskills-mcp-server = "agentskills_mcp_server.__main__:main"
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["poetry-core"]
|
|
34
|
+
build-backend = "poetry.core.masonry.api"
|