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.
@@ -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
+ [![PyPI](https://img.shields.io/pypi/v/agentskills-mcp-server)](https://pypi.org/project/agentskills-mcp-server/)
28
+ [![Python 3.12+](https://img.shields.io/pypi/pyversions/agentskills-mcp-server)](https://pypi.org/project/agentskills-mcp-server/)
29
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
+ [![PyPI](https://img.shields.io/pypi/v/agentskills-mcp-server)](https://pypi.org/project/agentskills-mcp-server/)
4
+ [![Python 3.12+](https://img.shields.io/pypi/pyversions/agentskills-mcp-server)](https://pypi.org/project/agentskills-mcp-server/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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)
@@ -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"