aimarket-mcp-packager 2.0.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.
- aimarket_mcp_packager-2.0.0/LICENSE +21 -0
- aimarket_mcp_packager-2.0.0/PKG-INFO +182 -0
- aimarket_mcp_packager-2.0.0/README.md +167 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager/__init__.py +1 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager/mcp_packager.py +3 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager/packager_core.py +139 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager/plugin.py +38 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager.egg-info/PKG-INFO +182 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager.egg-info/SOURCES.txt +13 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager.egg-info/dependency_links.txt +1 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager.egg-info/entry_points.txt +5 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager.egg-info/requires.txt +7 -0
- aimarket_mcp_packager-2.0.0/aimarket_mcp_packager.egg-info/top_level.txt +1 -0
- aimarket_mcp_packager-2.0.0/pyproject.toml +25 -0
- aimarket_mcp_packager-2.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AI-Factory Project 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,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aimarket-mcp-packager
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Package products as ready-to-run MCP servers for Claude Desktop
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: aimarket-hub>=3.0.0
|
|
10
|
+
Provides-Extra: mcp
|
|
11
|
+
Requires-Dist: mcp<4,>=1.6; extra == "mcp"
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# aimarket-mcp-packager — MCP server
|
|
17
|
+
|
|
18
|
+
<!-- aicom-readme-badges -->
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="https://github.com/alexar76/aimarket-plugins/actions/workflows/ci.yml"><img src="https://github.com/alexar76/aimarket-plugins/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
21
|
+
<a href="https://glama.ai/mcp/servers/alexar76/aimarket-plugins"><img src="https://glama.ai/mcp/servers/alexar76/aimarket-plugins/badges/score.svg" alt="aimarket-plugins MCP server" /></a>
|
|
22
|
+
<a href="#testing--coverage"><img src="docs/badges/coverage.svg" alt="Test coverage" /></a>
|
|
23
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache--2.0-blue.svg" alt="License: Apache-2.0" /></a>
|
|
24
|
+
</p>
|
|
25
|
+
<!-- /aicom-readme-badges -->
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
**This repository ships a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server** that packages AIMarket capabilities into self-hosted MCP server products (Docker image metadata, MCP manifest, Claude Desktop config).
|
|
32
|
+
|
|
33
|
+
Transport: **stdio** (`mcp_stdio_server.py`). Built with the official **[MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)** (`mcp` package, `FastMCP`).
|
|
34
|
+
|
|
35
|
+
Compatible hosts: Claude Desktop, Cursor, Glama, and any MCP client that supports stdio servers.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## MCP server in this repo
|
|
40
|
+
|
|
41
|
+
| Item | Location |
|
|
42
|
+
|------|----------|
|
|
43
|
+
| MCP entrypoint | [`mcp_stdio_server.py`](mcp_stdio_server.py) |
|
|
44
|
+
| MCP SDK dependency | [`requirements-mcp.txt`](requirements-mcp.txt) — `mcp>=1.6,<4` |
|
|
45
|
+
| Glama / Docker run | [`Dockerfile`](Dockerfile), [`glama.json`](glama.json) |
|
|
46
|
+
| Tool implementation | [`aimarket_mcp_packager/packager_core.py`](aimarket_mcp_packager/packager_core.py) |
|
|
47
|
+
|
|
48
|
+
Run locally:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install -r requirements-mcp.txt
|
|
52
|
+
pip install -e .
|
|
53
|
+
python mcp_stdio_server.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or with Docker (stdio MCP server):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
docker build -t aimarket-mcp-packager .
|
|
60
|
+
docker run --rm -i aimarket-mcp-packager
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## MCP tools
|
|
66
|
+
|
|
67
|
+
The server exposes **3 tools** (no MCP resources or prompts):
|
|
68
|
+
|
|
69
|
+
| Tool | Description |
|
|
70
|
+
|------|-------------|
|
|
71
|
+
| `package_capability` | Build an MCP server package: Docker image name, `mcp_manifest`, subscription tiers, connection string |
|
|
72
|
+
| `generate_dockerfile` | Generate a Dockerfile template for the packaged MCP server |
|
|
73
|
+
| `generate_claude_desktop_config` | Generate a `claude_desktop_config.json` snippet (`mcpServers`) for docker-run MCP |
|
|
74
|
+
|
|
75
|
+
Example tool call (conceptual):
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"name": "package_capability",
|
|
80
|
+
"arguments": {
|
|
81
|
+
"capability_id": "translate.multi@v2",
|
|
82
|
+
"product_id": "prod-001",
|
|
83
|
+
"name": "Lyra",
|
|
84
|
+
"description": "Multilingual translator",
|
|
85
|
+
"input_schema": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"] }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
> `input_schema` takes a JSON Schema **object** (a JSON string is also tolerated for backward compatibility). Every tool parameter is documented in the server's tool schema for MCP clients.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## MCP resources
|
|
95
|
+
|
|
96
|
+
This server does **not** register MCP resources or prompts — only the tools above. Output is JSON text returned from each tool call.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Client configuration
|
|
101
|
+
|
|
102
|
+
### Claude Desktop
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"mcpServers": {
|
|
107
|
+
"aimarket-mcp-packager": {
|
|
108
|
+
"command": "python",
|
|
109
|
+
"args": ["/path/to/aimarket-mcp-packager/mcp_stdio_server.py"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Docker variant (see `generate_claude_desktop_config` tool output):
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"aimarket-mcp-packager": {
|
|
121
|
+
"command": "docker",
|
|
122
|
+
"args": ["run", "--rm", "-i", "aimarket-mcp-packager:latest"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Cursor
|
|
129
|
+
|
|
130
|
+
Add the same stdio server under **Settings → MCP** (command + args pointing at `mcp_stdio_server.py` or the Docker image above).
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Python library (optional)
|
|
135
|
+
|
|
136
|
+
The same packaging logic is available as a library and as an AIMarket Hub plugin (PyPI package coming soon — for now `pip install -e .` from this directory, or use the AIMarket Hub Docker image). Hub HTTP routes are optional; **the MCP server runs standalone** via `mcp_stdio_server.py`.
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from aimarket_mcp_packager.mcp_packager import MCPPackager
|
|
140
|
+
|
|
141
|
+
packager = MCPPackager()
|
|
142
|
+
pkg = packager.package(
|
|
143
|
+
capability_id="translate.multi@v2",
|
|
144
|
+
product_id="prod-001",
|
|
145
|
+
name="Lyra",
|
|
146
|
+
description="Multilingual translator",
|
|
147
|
+
input_schema={"type": "object", "properties": {"text": {"type": "string"}}},
|
|
148
|
+
price_per_call_usd=0.40,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
print(pkg.docker_image)
|
|
152
|
+
print(pkg.mcp_manifest)
|
|
153
|
+
print(packager.generate_claude_desktop_config(pkg))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## When to use
|
|
159
|
+
|
|
160
|
+
- Distribute AI capabilities as self-hosted MCP servers (Docker + manifest)
|
|
161
|
+
- Generate Claude Desktop / Cursor MCP client configs
|
|
162
|
+
- Enterprise on-prem deployment with subscription tiers
|
|
163
|
+
|
|
164
|
+
## Subscription tiers (packaged products)
|
|
165
|
+
|
|
166
|
+
| Tier | Calls/month | Price |
|
|
167
|
+
|------|------------|-------|
|
|
168
|
+
| Starter | 100 | $9.99 |
|
|
169
|
+
| Pro | 1,000 | $49.99 |
|
|
170
|
+
| Enterprise | 10,000 | $299.99 |
|
|
171
|
+
|
|
172
|
+
## Documentation
|
|
173
|
+
|
|
174
|
+
| Document | Description |
|
|
175
|
+
|----------|-------------|
|
|
176
|
+
| [User guide](docs/user-guide.md) | Install, Hub plugin, verify loaded |
|
|
177
|
+
| [User cases](docs/user-cases.md) | Personas and cross-plugin workflows |
|
|
178
|
+
| [SDK integration](docs/sdk-integration.md) | Code examples and hook behavior |
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT · Maintained by AI-Factory
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# aimarket-mcp-packager — MCP server
|
|
2
|
+
|
|
3
|
+
<!-- aicom-readme-badges -->
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://github.com/alexar76/aimarket-plugins/actions/workflows/ci.yml"><img src="https://github.com/alexar76/aimarket-plugins/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
6
|
+
<a href="https://glama.ai/mcp/servers/alexar76/aimarket-plugins"><img src="https://glama.ai/mcp/servers/alexar76/aimarket-plugins/badges/score.svg" alt="aimarket-plugins MCP server" /></a>
|
|
7
|
+
<a href="#testing--coverage"><img src="docs/badges/coverage.svg" alt="Test coverage" /></a>
|
|
8
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache--2.0-blue.svg" alt="License: Apache-2.0" /></a>
|
|
9
|
+
</p>
|
|
10
|
+
<!-- /aicom-readme-badges -->
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
**This repository ships a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server** that packages AIMarket capabilities into self-hosted MCP server products (Docker image metadata, MCP manifest, Claude Desktop config).
|
|
17
|
+
|
|
18
|
+
Transport: **stdio** (`mcp_stdio_server.py`). Built with the official **[MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)** (`mcp` package, `FastMCP`).
|
|
19
|
+
|
|
20
|
+
Compatible hosts: Claude Desktop, Cursor, Glama, and any MCP client that supports stdio servers.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## MCP server in this repo
|
|
25
|
+
|
|
26
|
+
| Item | Location |
|
|
27
|
+
|------|----------|
|
|
28
|
+
| MCP entrypoint | [`mcp_stdio_server.py`](mcp_stdio_server.py) |
|
|
29
|
+
| MCP SDK dependency | [`requirements-mcp.txt`](requirements-mcp.txt) — `mcp>=1.6,<4` |
|
|
30
|
+
| Glama / Docker run | [`Dockerfile`](Dockerfile), [`glama.json`](glama.json) |
|
|
31
|
+
| Tool implementation | [`aimarket_mcp_packager/packager_core.py`](aimarket_mcp_packager/packager_core.py) |
|
|
32
|
+
|
|
33
|
+
Run locally:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install -r requirements-mcp.txt
|
|
37
|
+
pip install -e .
|
|
38
|
+
python mcp_stdio_server.py
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or with Docker (stdio MCP server):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
docker build -t aimarket-mcp-packager .
|
|
45
|
+
docker run --rm -i aimarket-mcp-packager
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## MCP tools
|
|
51
|
+
|
|
52
|
+
The server exposes **3 tools** (no MCP resources or prompts):
|
|
53
|
+
|
|
54
|
+
| Tool | Description |
|
|
55
|
+
|------|-------------|
|
|
56
|
+
| `package_capability` | Build an MCP server package: Docker image name, `mcp_manifest`, subscription tiers, connection string |
|
|
57
|
+
| `generate_dockerfile` | Generate a Dockerfile template for the packaged MCP server |
|
|
58
|
+
| `generate_claude_desktop_config` | Generate a `claude_desktop_config.json` snippet (`mcpServers`) for docker-run MCP |
|
|
59
|
+
|
|
60
|
+
Example tool call (conceptual):
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"name": "package_capability",
|
|
65
|
+
"arguments": {
|
|
66
|
+
"capability_id": "translate.multi@v2",
|
|
67
|
+
"product_id": "prod-001",
|
|
68
|
+
"name": "Lyra",
|
|
69
|
+
"description": "Multilingual translator",
|
|
70
|
+
"input_schema": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"] }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
> `input_schema` takes a JSON Schema **object** (a JSON string is also tolerated for backward compatibility). Every tool parameter is documented in the server's tool schema for MCP clients.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## MCP resources
|
|
80
|
+
|
|
81
|
+
This server does **not** register MCP resources or prompts — only the tools above. Output is JSON text returned from each tool call.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Client configuration
|
|
86
|
+
|
|
87
|
+
### Claude Desktop
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"mcpServers": {
|
|
92
|
+
"aimarket-mcp-packager": {
|
|
93
|
+
"command": "python",
|
|
94
|
+
"args": ["/path/to/aimarket-mcp-packager/mcp_stdio_server.py"]
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Docker variant (see `generate_claude_desktop_config` tool output):
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"mcpServers": {
|
|
105
|
+
"aimarket-mcp-packager": {
|
|
106
|
+
"command": "docker",
|
|
107
|
+
"args": ["run", "--rm", "-i", "aimarket-mcp-packager:latest"]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Cursor
|
|
114
|
+
|
|
115
|
+
Add the same stdio server under **Settings → MCP** (command + args pointing at `mcp_stdio_server.py` or the Docker image above).
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Python library (optional)
|
|
120
|
+
|
|
121
|
+
The same packaging logic is available as a library and as an AIMarket Hub plugin (PyPI package coming soon — for now `pip install -e .` from this directory, or use the AIMarket Hub Docker image). Hub HTTP routes are optional; **the MCP server runs standalone** via `mcp_stdio_server.py`.
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from aimarket_mcp_packager.mcp_packager import MCPPackager
|
|
125
|
+
|
|
126
|
+
packager = MCPPackager()
|
|
127
|
+
pkg = packager.package(
|
|
128
|
+
capability_id="translate.multi@v2",
|
|
129
|
+
product_id="prod-001",
|
|
130
|
+
name="Lyra",
|
|
131
|
+
description="Multilingual translator",
|
|
132
|
+
input_schema={"type": "object", "properties": {"text": {"type": "string"}}},
|
|
133
|
+
price_per_call_usd=0.40,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
print(pkg.docker_image)
|
|
137
|
+
print(pkg.mcp_manifest)
|
|
138
|
+
print(packager.generate_claude_desktop_config(pkg))
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## When to use
|
|
144
|
+
|
|
145
|
+
- Distribute AI capabilities as self-hosted MCP servers (Docker + manifest)
|
|
146
|
+
- Generate Claude Desktop / Cursor MCP client configs
|
|
147
|
+
- Enterprise on-prem deployment with subscription tiers
|
|
148
|
+
|
|
149
|
+
## Subscription tiers (packaged products)
|
|
150
|
+
|
|
151
|
+
| Tier | Calls/month | Price |
|
|
152
|
+
|------|------------|-------|
|
|
153
|
+
| Starter | 100 | $9.99 |
|
|
154
|
+
| Pro | 1,000 | $49.99 |
|
|
155
|
+
| Enterprise | 10,000 | $299.99 |
|
|
156
|
+
|
|
157
|
+
## Documentation
|
|
158
|
+
|
|
159
|
+
| Document | Description |
|
|
160
|
+
|----------|-------------|
|
|
161
|
+
| [User guide](docs/user-guide.md) | Install, Hub plugin, verify loaded |
|
|
162
|
+
| [User cases](docs/user-cases.md) | Personas and cross-plugin workflows |
|
|
163
|
+
| [SDK integration](docs/sdk-integration.md) | Code examples and hook behavior |
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT · Maintained by AI-Factory
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# aimarket-mcp-packager plugin
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Canonical MCP packager logic (stdlib-only). Used by stdio MCP server and hub shim."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
_SLUG_RE = re.compile(r"[^a-z0-9._-]+")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _slug(value: str, fallback: str = "mcp") -> str:
|
|
14
|
+
"""Constrain free-text to a docker/compose-safe token.
|
|
15
|
+
|
|
16
|
+
``name`` and ``registry`` flow into image tags and the docker-compose /
|
|
17
|
+
Dockerfile text templates. Without this, a value containing newlines or
|
|
18
|
+
YAML metacharacters could inject extra compose keys (e.g. ``privileged``).
|
|
19
|
+
"""
|
|
20
|
+
slug = _SLUG_RE.sub("-", (value or "").strip().lower()).strip("-._")
|
|
21
|
+
return slug or fallback
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class MCPServerPackage:
|
|
26
|
+
name: str
|
|
27
|
+
version: str
|
|
28
|
+
capability_id: str
|
|
29
|
+
product_id: str
|
|
30
|
+
docker_image: str
|
|
31
|
+
docker_compose_snippet: str
|
|
32
|
+
mcp_manifest: dict[str, Any]
|
|
33
|
+
connection_string: str
|
|
34
|
+
env_template: dict[str, str] = field(default_factory=dict)
|
|
35
|
+
subscription_tiers: list[dict[str, Any]] = field(default_factory=list)
|
|
36
|
+
license_required: bool = True
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class MCPPackager:
|
|
40
|
+
"""Package capabilities as self-hosted MCP servers."""
|
|
41
|
+
|
|
42
|
+
def package(
|
|
43
|
+
self,
|
|
44
|
+
capability_id: str,
|
|
45
|
+
product_id: str,
|
|
46
|
+
name: str,
|
|
47
|
+
description: str,
|
|
48
|
+
input_schema: dict[str, Any],
|
|
49
|
+
price_per_call_usd: float = 0.40,
|
|
50
|
+
registry: str = "aifactory",
|
|
51
|
+
) -> MCPServerPackage:
|
|
52
|
+
del price_per_call_usd
|
|
53
|
+
safe_name = _slug(name)
|
|
54
|
+
safe_registry = _slug(registry, "aifactory")
|
|
55
|
+
image_name = f"{safe_registry}/{safe_name}"
|
|
56
|
+
image_tag = f"{image_name}:2.0.0"
|
|
57
|
+
mcp_manifest = {
|
|
58
|
+
"protocol": "mcp",
|
|
59
|
+
"version": "1.0",
|
|
60
|
+
"server": {
|
|
61
|
+
"name": f"{name} MCP Server",
|
|
62
|
+
"description": description,
|
|
63
|
+
"vendor": registry,
|
|
64
|
+
},
|
|
65
|
+
"tools": [
|
|
66
|
+
{
|
|
67
|
+
"name": capability_id,
|
|
68
|
+
"description": description,
|
|
69
|
+
"inputSchema": input_schema,
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"pricing": {
|
|
73
|
+
"model": "subscription",
|
|
74
|
+
"tiers": [
|
|
75
|
+
{"name": "Starter", "calls_per_month": 100, "price_usd_month": 9.99},
|
|
76
|
+
{"name": "Pro", "calls_per_month": 1000, "price_usd_month": 49.99},
|
|
77
|
+
{"name": "Enterprise", "calls_per_month": 10000, "price_usd_month": 299.99},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
docker_compose = (
|
|
82
|
+
f"{safe_name}:\n"
|
|
83
|
+
f" image: {image_tag}\n"
|
|
84
|
+
f" ports:\n"
|
|
85
|
+
f" - '3100:3100'\n"
|
|
86
|
+
f" environment:\n"
|
|
87
|
+
f" - MCP_SERVER_NAME={safe_name}\n"
|
|
88
|
+
f" - AIFACTORY_LICENSE_KEY=${{AIFACTORY_LICENSE_KEY}}\n"
|
|
89
|
+
f" restart: unless-stopped"
|
|
90
|
+
)
|
|
91
|
+
connection_string = json.dumps(
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
safe_name: {
|
|
95
|
+
"command": "docker",
|
|
96
|
+
"args": ["run", "-d", "-p", "3100:3100", image_tag],
|
|
97
|
+
"env": {"AIFACTORY_LICENSE_KEY": "${AIFACTORY_LICENSE_KEY}"},
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
indent=2,
|
|
102
|
+
)
|
|
103
|
+
return MCPServerPackage(
|
|
104
|
+
name=image_name,
|
|
105
|
+
version="2.0.0",
|
|
106
|
+
capability_id=capability_id,
|
|
107
|
+
product_id=product_id,
|
|
108
|
+
docker_image=image_tag,
|
|
109
|
+
docker_compose_snippet=docker_compose,
|
|
110
|
+
mcp_manifest=mcp_manifest,
|
|
111
|
+
connection_string=connection_string,
|
|
112
|
+
env_template={"AIFACTORY_LICENSE_KEY": "your_license_key_here"},
|
|
113
|
+
subscription_tiers=mcp_manifest["pricing"]["tiers"],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def generate_dockerfile(self, package: MCPServerPackage) -> str:
|
|
117
|
+
short = package.name.split("/")[-1]
|
|
118
|
+
return f"""# MCP Server: {package.name}
|
|
119
|
+
FROM python:3.12-slim
|
|
120
|
+
WORKDIR /app
|
|
121
|
+
ENV MCP_SERVER_NAME={short}
|
|
122
|
+
ENV MCP_SERVER_PORT=3100
|
|
123
|
+
EXPOSE 3100
|
|
124
|
+
ENTRYPOINT ["python", "-m", "mcp_server"]
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
def generate_claude_desktop_config(self, package: MCPServerPackage) -> str:
|
|
128
|
+
return json.dumps(
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
package.name.split("/")[-1]: {
|
|
132
|
+
"command": "docker",
|
|
133
|
+
"args": ["run", "--rm", "-i", package.docker_image],
|
|
134
|
+
"description": package.mcp_manifest["server"]["description"],
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
indent=2,
|
|
139
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""aimarket-mcp-packager plugin — Package capabilities as ready-to-run MCP servers for Claude Desktop."""
|
|
2
|
+
|
|
3
|
+
from aimarket_hub.plugin import HubPlugin
|
|
4
|
+
from aimarket_mcp_packager.mcp_packager import MCPPackager
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MCPPlugin(HubPlugin):
|
|
8
|
+
name = "aimarket-mcp-packager"
|
|
9
|
+
version = "2.0.0"
|
|
10
|
+
description = "Package capabilities as ready-to-run MCP servers for Claude Desktop"
|
|
11
|
+
homepage = "https://github.com/ai-factory/aimarket-mcp-packager"
|
|
12
|
+
category = "tooling"
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
super().__init__()
|
|
16
|
+
self._packager = MCPPackager()
|
|
17
|
+
|
|
18
|
+
def register_routes(self, router):
|
|
19
|
+
|
|
20
|
+
from pydantic import BaseModel, Field
|
|
21
|
+
from fastapi.responses import JSONResponse
|
|
22
|
+
|
|
23
|
+
class PackageRequest(BaseModel):
|
|
24
|
+
capability_id: str = Field(..., min_length=2)
|
|
25
|
+
product_id: str = Field(..., min_length=2)
|
|
26
|
+
name: str = Field(..., min_length=1)
|
|
27
|
+
description: str = Field("")
|
|
28
|
+
input_schema: dict = Field(default_factory=dict)
|
|
29
|
+
|
|
30
|
+
@router.post("/mcp/package")
|
|
31
|
+
async def package_capability(body: PackageRequest):
|
|
32
|
+
pkg = self._packager.package(body.capability_id, body.product_id,
|
|
33
|
+
body.name, body.description, body.input_schema)
|
|
34
|
+
return {"docker_image": pkg.docker_image, "subscription_tiers": pkg.subscription_tiers,
|
|
35
|
+
"mcp_manifest": pkg.mcp_manifest}
|
|
36
|
+
|
|
37
|
+
def get_manifest_extension(self):
|
|
38
|
+
return {"mcp": {"enabled": True, "registry": "aifactory"}}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aimarket-mcp-packager
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Package products as ready-to-run MCP servers for Claude Desktop
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: aimarket-hub>=3.0.0
|
|
10
|
+
Provides-Extra: mcp
|
|
11
|
+
Requires-Dist: mcp<4,>=1.6; extra == "mcp"
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# aimarket-mcp-packager — MCP server
|
|
17
|
+
|
|
18
|
+
<!-- aicom-readme-badges -->
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="https://github.com/alexar76/aimarket-plugins/actions/workflows/ci.yml"><img src="https://github.com/alexar76/aimarket-plugins/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
21
|
+
<a href="https://glama.ai/mcp/servers/alexar76/aimarket-plugins"><img src="https://glama.ai/mcp/servers/alexar76/aimarket-plugins/badges/score.svg" alt="aimarket-plugins MCP server" /></a>
|
|
22
|
+
<a href="#testing--coverage"><img src="docs/badges/coverage.svg" alt="Test coverage" /></a>
|
|
23
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache--2.0-blue.svg" alt="License: Apache-2.0" /></a>
|
|
24
|
+
</p>
|
|
25
|
+
<!-- /aicom-readme-badges -->
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
**This repository ships a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server** that packages AIMarket capabilities into self-hosted MCP server products (Docker image metadata, MCP manifest, Claude Desktop config).
|
|
32
|
+
|
|
33
|
+
Transport: **stdio** (`mcp_stdio_server.py`). Built with the official **[MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)** (`mcp` package, `FastMCP`).
|
|
34
|
+
|
|
35
|
+
Compatible hosts: Claude Desktop, Cursor, Glama, and any MCP client that supports stdio servers.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## MCP server in this repo
|
|
40
|
+
|
|
41
|
+
| Item | Location |
|
|
42
|
+
|------|----------|
|
|
43
|
+
| MCP entrypoint | [`mcp_stdio_server.py`](mcp_stdio_server.py) |
|
|
44
|
+
| MCP SDK dependency | [`requirements-mcp.txt`](requirements-mcp.txt) — `mcp>=1.6,<4` |
|
|
45
|
+
| Glama / Docker run | [`Dockerfile`](Dockerfile), [`glama.json`](glama.json) |
|
|
46
|
+
| Tool implementation | [`aimarket_mcp_packager/packager_core.py`](aimarket_mcp_packager/packager_core.py) |
|
|
47
|
+
|
|
48
|
+
Run locally:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install -r requirements-mcp.txt
|
|
52
|
+
pip install -e .
|
|
53
|
+
python mcp_stdio_server.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or with Docker (stdio MCP server):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
docker build -t aimarket-mcp-packager .
|
|
60
|
+
docker run --rm -i aimarket-mcp-packager
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## MCP tools
|
|
66
|
+
|
|
67
|
+
The server exposes **3 tools** (no MCP resources or prompts):
|
|
68
|
+
|
|
69
|
+
| Tool | Description |
|
|
70
|
+
|------|-------------|
|
|
71
|
+
| `package_capability` | Build an MCP server package: Docker image name, `mcp_manifest`, subscription tiers, connection string |
|
|
72
|
+
| `generate_dockerfile` | Generate a Dockerfile template for the packaged MCP server |
|
|
73
|
+
| `generate_claude_desktop_config` | Generate a `claude_desktop_config.json` snippet (`mcpServers`) for docker-run MCP |
|
|
74
|
+
|
|
75
|
+
Example tool call (conceptual):
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"name": "package_capability",
|
|
80
|
+
"arguments": {
|
|
81
|
+
"capability_id": "translate.multi@v2",
|
|
82
|
+
"product_id": "prod-001",
|
|
83
|
+
"name": "Lyra",
|
|
84
|
+
"description": "Multilingual translator",
|
|
85
|
+
"input_schema": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"] }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
> `input_schema` takes a JSON Schema **object** (a JSON string is also tolerated for backward compatibility). Every tool parameter is documented in the server's tool schema for MCP clients.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## MCP resources
|
|
95
|
+
|
|
96
|
+
This server does **not** register MCP resources or prompts — only the tools above. Output is JSON text returned from each tool call.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Client configuration
|
|
101
|
+
|
|
102
|
+
### Claude Desktop
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"mcpServers": {
|
|
107
|
+
"aimarket-mcp-packager": {
|
|
108
|
+
"command": "python",
|
|
109
|
+
"args": ["/path/to/aimarket-mcp-packager/mcp_stdio_server.py"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Docker variant (see `generate_claude_desktop_config` tool output):
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"aimarket-mcp-packager": {
|
|
121
|
+
"command": "docker",
|
|
122
|
+
"args": ["run", "--rm", "-i", "aimarket-mcp-packager:latest"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Cursor
|
|
129
|
+
|
|
130
|
+
Add the same stdio server under **Settings → MCP** (command + args pointing at `mcp_stdio_server.py` or the Docker image above).
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Python library (optional)
|
|
135
|
+
|
|
136
|
+
The same packaging logic is available as a library and as an AIMarket Hub plugin (PyPI package coming soon — for now `pip install -e .` from this directory, or use the AIMarket Hub Docker image). Hub HTTP routes are optional; **the MCP server runs standalone** via `mcp_stdio_server.py`.
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from aimarket_mcp_packager.mcp_packager import MCPPackager
|
|
140
|
+
|
|
141
|
+
packager = MCPPackager()
|
|
142
|
+
pkg = packager.package(
|
|
143
|
+
capability_id="translate.multi@v2",
|
|
144
|
+
product_id="prod-001",
|
|
145
|
+
name="Lyra",
|
|
146
|
+
description="Multilingual translator",
|
|
147
|
+
input_schema={"type": "object", "properties": {"text": {"type": "string"}}},
|
|
148
|
+
price_per_call_usd=0.40,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
print(pkg.docker_image)
|
|
152
|
+
print(pkg.mcp_manifest)
|
|
153
|
+
print(packager.generate_claude_desktop_config(pkg))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## When to use
|
|
159
|
+
|
|
160
|
+
- Distribute AI capabilities as self-hosted MCP servers (Docker + manifest)
|
|
161
|
+
- Generate Claude Desktop / Cursor MCP client configs
|
|
162
|
+
- Enterprise on-prem deployment with subscription tiers
|
|
163
|
+
|
|
164
|
+
## Subscription tiers (packaged products)
|
|
165
|
+
|
|
166
|
+
| Tier | Calls/month | Price |
|
|
167
|
+
|------|------------|-------|
|
|
168
|
+
| Starter | 100 | $9.99 |
|
|
169
|
+
| Pro | 1,000 | $49.99 |
|
|
170
|
+
| Enterprise | 10,000 | $299.99 |
|
|
171
|
+
|
|
172
|
+
## Documentation
|
|
173
|
+
|
|
174
|
+
| Document | Description |
|
|
175
|
+
|----------|-------------|
|
|
176
|
+
| [User guide](docs/user-guide.md) | Install, Hub plugin, verify loaded |
|
|
177
|
+
| [User cases](docs/user-cases.md) | Personas and cross-plugin workflows |
|
|
178
|
+
| [SDK integration](docs/sdk-integration.md) | Code examples and hook behavior |
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT · Maintained by AI-Factory
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
aimarket_mcp_packager/__init__.py
|
|
5
|
+
aimarket_mcp_packager/mcp_packager.py
|
|
6
|
+
aimarket_mcp_packager/packager_core.py
|
|
7
|
+
aimarket_mcp_packager/plugin.py
|
|
8
|
+
aimarket_mcp_packager.egg-info/PKG-INFO
|
|
9
|
+
aimarket_mcp_packager.egg-info/SOURCES.txt
|
|
10
|
+
aimarket_mcp_packager.egg-info/dependency_links.txt
|
|
11
|
+
aimarket_mcp_packager.egg-info/entry_points.txt
|
|
12
|
+
aimarket_mcp_packager.egg-info/requires.txt
|
|
13
|
+
aimarket_mcp_packager.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aimarket_mcp_packager
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=75", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "aimarket-mcp-packager"
|
|
7
|
+
version = "2.0.0"
|
|
8
|
+
description = "Package products as ready-to-run MCP servers for Claude Desktop"
|
|
9
|
+
license = {text = "MIT"}
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
dependencies = ["aimarket-hub>=3.0.0"]
|
|
13
|
+
|
|
14
|
+
[project.optional-dependencies]
|
|
15
|
+
mcp = ["mcp>=1.6,<4"]
|
|
16
|
+
dev = ["pytest>=8"]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
aimarket-mcp-packager-mcp = "mcp_stdio_server:main"
|
|
20
|
+
|
|
21
|
+
[project.entry-points."aimarket.plugins"]
|
|
22
|
+
mcp-packager = "aimarket_mcp_packager.plugin:MCPPlugin"
|
|
23
|
+
|
|
24
|
+
[tool.setuptools.packages.find]
|
|
25
|
+
include = ["aimarket_mcp_packager*"]
|