@contractspec/app.alpic-mcp 0.0.0-canary-20260204161232
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.
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/assets/app.js +40 -0
- package/assets/index.html +102 -0
- package/assets/style.css +315 -0
- package/dist/assets/app.js +40 -0
- package/dist/assets/index.html +102 -0
- package/dist/assets/style.css +315 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +3 -0
- package/dist/server.d.mts +35 -0
- package/dist/server.mjs +42 -0
- package/package.json +43 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @contractspec/app.alpic-mcp
|
|
2
|
+
|
|
3
|
+
## 0.0.0-canary-20260204161232
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1363bca: Add Alpic MCP starter and asset hosting helpers.
|
|
8
|
+
- Updated dependencies [1363bca]
|
|
9
|
+
- @contractspec/bundle.alpic@0.0.0-canary-20260204161232
|
|
10
|
+
|
|
11
|
+
## 1.56.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Initial release for Alpic MCP hosting app.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Chaman Ventures, SASU
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @contractspec/app.alpic-mcp
|
|
2
|
+
|
|
3
|
+
Minimal MCP server and ChatGPT App asset host for Alpic.
|
|
4
|
+
|
|
5
|
+
## Alpic settings
|
|
6
|
+
|
|
7
|
+
- Build command: `npm run build`
|
|
8
|
+
- Output directory: `dist`
|
|
9
|
+
- MCP endpoints: `/` (SSE + Streamable HTTP) and `/mcp` (Streamable HTTP)
|
|
10
|
+
- Assets: `/assets`
|
|
11
|
+
|
|
12
|
+
## Notes
|
|
13
|
+
|
|
14
|
+
- Place static UI files in `assets/` at the project root.
|
|
15
|
+
- Alpic merges `assets/` and `dist/assets/` on deploy.
|
|
16
|
+
- If assets are cached in ChatGPT, use the in-app refresh option.
|
package/assets/app.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const origin = window.location.origin;
|
|
2
|
+
|
|
3
|
+
const config = {
|
|
4
|
+
mcpServers: {
|
|
5
|
+
'alpic-app': {
|
|
6
|
+
url: origin,
|
|
7
|
+
transport: 'http',
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const originTargets = document.querySelectorAll('[data-origin]');
|
|
13
|
+
originTargets.forEach((node) => {
|
|
14
|
+
node.textContent = origin;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const configNode = document.getElementById('config-json');
|
|
18
|
+
if (configNode) {
|
|
19
|
+
configNode.textContent = JSON.stringify(config, null, 2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const copyButton = document.getElementById('copy-config');
|
|
23
|
+
if (copyButton) {
|
|
24
|
+
copyButton.addEventListener('click', async () => {
|
|
25
|
+
try {
|
|
26
|
+
await navigator.clipboard.writeText(JSON.stringify(config, null, 2));
|
|
27
|
+
copyButton.textContent = 'Copied';
|
|
28
|
+
copyButton.classList.add('is-copied');
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
copyButton.textContent = 'Copy MCP config';
|
|
31
|
+
copyButton.classList.remove('is-copied');
|
|
32
|
+
}, 1600);
|
|
33
|
+
} catch {
|
|
34
|
+
copyButton.textContent = 'Copy failed';
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
copyButton.textContent = 'Copy MCP config';
|
|
37
|
+
}, 1600);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>ContractSpec Alpic MCP</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link
|
|
10
|
+
href="https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,600&family=Space+Grotesk:wght@400;500;600;700&display=swap"
|
|
11
|
+
rel="stylesheet"
|
|
12
|
+
/>
|
|
13
|
+
<link rel="stylesheet" href="/assets/style.css" />
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<main class="page">
|
|
17
|
+
<header class="hero">
|
|
18
|
+
<span class="hero__badge">Alpic MCP + ChatGPT App</span>
|
|
19
|
+
<h1>Ship MCP tools with a polished UI on Alpic.</h1>
|
|
20
|
+
<p>
|
|
21
|
+
This starter ships a minimal MCP surface and a static UI bundle.
|
|
22
|
+
Deploy it on Alpic and you get MCP endpoints at <span>/</span> and
|
|
23
|
+
<span>/mcp</span>, plus static assets served from
|
|
24
|
+
<span>/assets</span>.
|
|
25
|
+
</p>
|
|
26
|
+
<div class="hero__actions">
|
|
27
|
+
<button class="primary" id="copy-config">Copy MCP config</button>
|
|
28
|
+
<a class="ghost" href="#assets">See assets</a>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="hero__meta">
|
|
31
|
+
<div class="meta-card">
|
|
32
|
+
<span>Base URL</span>
|
|
33
|
+
<code data-origin>https://your-app.alpic.live</code>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="meta-card">
|
|
36
|
+
<span>Assets</span>
|
|
37
|
+
<code>/assets</code>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</header>
|
|
41
|
+
|
|
42
|
+
<section class="grid">
|
|
43
|
+
<article class="card">
|
|
44
|
+
<h2>MCP endpoints</h2>
|
|
45
|
+
<ul>
|
|
46
|
+
<li><strong>/</strong> - SSE + Streamable HTTP</li>
|
|
47
|
+
<li><strong>/mcp</strong> - Streamable HTTP</li>
|
|
48
|
+
</ul>
|
|
49
|
+
</article>
|
|
50
|
+
<article class="card">
|
|
51
|
+
<h2>UI resource</h2>
|
|
52
|
+
<p>
|
|
53
|
+
The MCP resource <strong>app://ui</strong> points to the UI entry at
|
|
54
|
+
<strong>/assets/index.html</strong>.
|
|
55
|
+
</p>
|
|
56
|
+
</article>
|
|
57
|
+
<article class="card">
|
|
58
|
+
<h2>Copy-ready config</h2>
|
|
59
|
+
<pre id="config-json" class="code"></pre>
|
|
60
|
+
</article>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section id="assets" class="assets">
|
|
64
|
+
<div class="assets__header">
|
|
65
|
+
<h2>Assets bundle</h2>
|
|
66
|
+
<p>Drop any static files in <code>assets/</code> before deploying.</p>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="assets__list">
|
|
69
|
+
<div class="asset-item">
|
|
70
|
+
<span>index.html</span>
|
|
71
|
+
<small>UI shell</small>
|
|
72
|
+
</div>
|
|
73
|
+
<div class="asset-item">
|
|
74
|
+
<span>style.css</span>
|
|
75
|
+
<small>Design system</small>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="asset-item">
|
|
78
|
+
<span>app.js</span>
|
|
79
|
+
<small>Client boot</small>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</section>
|
|
83
|
+
|
|
84
|
+
<footer class="footer">
|
|
85
|
+
<div><strong>ContractSpec</strong> + Alpic MCP starter</div>
|
|
86
|
+
<div class="footer__links">
|
|
87
|
+
<a href="https://docs.alpic.ai" target="_blank" rel="noreferrer">
|
|
88
|
+
Alpic docs
|
|
89
|
+
</a>
|
|
90
|
+
<a
|
|
91
|
+
href="https://docs.alpic.ai/guides/hosting-chatgpt-app-assets"
|
|
92
|
+
target="_blank"
|
|
93
|
+
rel="noreferrer"
|
|
94
|
+
>
|
|
95
|
+
Hosting assets
|
|
96
|
+
</a>
|
|
97
|
+
</div>
|
|
98
|
+
</footer>
|
|
99
|
+
</main>
|
|
100
|
+
<script type="module" src="/assets/app.js"></script>
|
|
101
|
+
</body>
|
|
102
|
+
</html>
|
package/assets/style.css
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #f7f2ea;
|
|
3
|
+
--bg-alt: #e9f3f1;
|
|
4
|
+
--ink: #1f1b16;
|
|
5
|
+
--muted: #6b6258;
|
|
6
|
+
--card: #ffffff;
|
|
7
|
+
--accent: #1b7f6b;
|
|
8
|
+
--accent-strong: #156554;
|
|
9
|
+
--accent-warm: #d97941;
|
|
10
|
+
--border: rgba(31, 27, 22, 0.12);
|
|
11
|
+
--shadow: 0 18px 40px rgba(31, 27, 22, 0.12);
|
|
12
|
+
--radius: 24px;
|
|
13
|
+
--radius-small: 14px;
|
|
14
|
+
--space: 24px;
|
|
15
|
+
--mono: 'Space Grotesk', 'Avenir Next', sans-serif;
|
|
16
|
+
--serif: 'Newsreader', 'Georgia', serif;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
* {
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
body {
|
|
24
|
+
margin: 0;
|
|
25
|
+
font-family: var(--mono);
|
|
26
|
+
color: var(--ink);
|
|
27
|
+
background:
|
|
28
|
+
radial-gradient(circle at top left, #fff4e6, transparent 55%),
|
|
29
|
+
linear-gradient(135deg, var(--bg), var(--bg-alt));
|
|
30
|
+
min-height: 100vh;
|
|
31
|
+
display: flex;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
body::before,
|
|
36
|
+
body::after {
|
|
37
|
+
content: '';
|
|
38
|
+
position: fixed;
|
|
39
|
+
z-index: -1;
|
|
40
|
+
width: 340px;
|
|
41
|
+
height: 340px;
|
|
42
|
+
border-radius: 50%;
|
|
43
|
+
filter: blur(10px);
|
|
44
|
+
opacity: 0.35;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
body::before {
|
|
48
|
+
top: -120px;
|
|
49
|
+
right: -80px;
|
|
50
|
+
background: radial-gradient(circle, #b6e2d3, transparent 70%);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
body::after {
|
|
54
|
+
bottom: -140px;
|
|
55
|
+
left: -120px;
|
|
56
|
+
background: radial-gradient(circle, #f2c4a0, transparent 70%);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.page {
|
|
60
|
+
width: min(1100px, 92vw);
|
|
61
|
+
padding: 48px 0 64px;
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
gap: 48px;
|
|
65
|
+
animation: fade-in 0.6s ease-out;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@keyframes fade-in {
|
|
69
|
+
from {
|
|
70
|
+
opacity: 0;
|
|
71
|
+
transform: translateY(14px);
|
|
72
|
+
}
|
|
73
|
+
to {
|
|
74
|
+
opacity: 1;
|
|
75
|
+
transform: translateY(0);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.hero {
|
|
80
|
+
background: var(--card);
|
|
81
|
+
padding: clamp(28px, 4vw, 48px);
|
|
82
|
+
border-radius: var(--radius);
|
|
83
|
+
box-shadow: var(--shadow);
|
|
84
|
+
border: 1px solid var(--border);
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: column;
|
|
87
|
+
gap: 16px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.hero__badge {
|
|
91
|
+
align-self: flex-start;
|
|
92
|
+
padding: 8px 14px;
|
|
93
|
+
border-radius: 999px;
|
|
94
|
+
background: rgba(27, 127, 107, 0.12);
|
|
95
|
+
color: var(--accent-strong);
|
|
96
|
+
font-weight: 600;
|
|
97
|
+
letter-spacing: 0.03em;
|
|
98
|
+
text-transform: uppercase;
|
|
99
|
+
font-size: 12px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.hero h1 {
|
|
103
|
+
font-size: clamp(32px, 4vw, 48px);
|
|
104
|
+
margin: 0;
|
|
105
|
+
line-height: 1.05;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.hero p {
|
|
109
|
+
margin: 0;
|
|
110
|
+
font-size: 17px;
|
|
111
|
+
color: var(--muted);
|
|
112
|
+
font-family: var(--serif);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.hero p span {
|
|
116
|
+
font-weight: 600;
|
|
117
|
+
color: var(--ink);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.hero__actions {
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-wrap: wrap;
|
|
123
|
+
gap: 14px;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.hero__actions .primary,
|
|
127
|
+
.hero__actions .ghost {
|
|
128
|
+
border-radius: 999px;
|
|
129
|
+
padding: 12px 20px;
|
|
130
|
+
font-size: 15px;
|
|
131
|
+
border: none;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
text-decoration: none;
|
|
134
|
+
transition:
|
|
135
|
+
transform 0.2s ease,
|
|
136
|
+
box-shadow 0.2s ease;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.hero__actions .primary {
|
|
140
|
+
background: var(--accent);
|
|
141
|
+
color: #fff;
|
|
142
|
+
box-shadow: 0 14px 24px rgba(27, 127, 107, 0.25);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.hero__actions .primary:hover {
|
|
146
|
+
transform: translateY(-1px);
|
|
147
|
+
box-shadow: 0 18px 28px rgba(27, 127, 107, 0.3);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.hero__actions .primary.is-copied {
|
|
151
|
+
background: var(--accent-strong);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.hero__actions .ghost {
|
|
155
|
+
border: 1px solid var(--border);
|
|
156
|
+
color: var(--ink);
|
|
157
|
+
background: transparent;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.hero__meta {
|
|
161
|
+
display: grid;
|
|
162
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
163
|
+
gap: 12px;
|
|
164
|
+
margin-top: 10px;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.meta-card {
|
|
168
|
+
border-radius: var(--radius-small);
|
|
169
|
+
padding: 14px 16px;
|
|
170
|
+
background: rgba(27, 127, 107, 0.08);
|
|
171
|
+
display: grid;
|
|
172
|
+
gap: 6px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.meta-card span {
|
|
176
|
+
font-size: 12px;
|
|
177
|
+
text-transform: uppercase;
|
|
178
|
+
letter-spacing: 0.04em;
|
|
179
|
+
color: var(--muted);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.meta-card code {
|
|
183
|
+
font-family: var(--mono);
|
|
184
|
+
font-weight: 600;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.grid {
|
|
188
|
+
display: grid;
|
|
189
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
190
|
+
gap: 18px;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.card {
|
|
194
|
+
background: var(--card);
|
|
195
|
+
border: 1px solid var(--border);
|
|
196
|
+
border-radius: var(--radius-small);
|
|
197
|
+
padding: 20px;
|
|
198
|
+
display: flex;
|
|
199
|
+
flex-direction: column;
|
|
200
|
+
gap: 12px;
|
|
201
|
+
box-shadow: 0 14px 26px rgba(31, 27, 22, 0.08);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.card h2 {
|
|
205
|
+
margin: 0;
|
|
206
|
+
font-size: 20px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.card p {
|
|
210
|
+
margin: 0;
|
|
211
|
+
color: var(--muted);
|
|
212
|
+
font-family: var(--serif);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.card ul {
|
|
216
|
+
margin: 0;
|
|
217
|
+
padding-left: 18px;
|
|
218
|
+
color: var(--muted);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.card strong {
|
|
222
|
+
color: var(--ink);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.code {
|
|
226
|
+
background: #0f172a;
|
|
227
|
+
color: #dbeafe;
|
|
228
|
+
padding: 16px;
|
|
229
|
+
border-radius: 12px;
|
|
230
|
+
font-size: 12px;
|
|
231
|
+
line-height: 1.5;
|
|
232
|
+
overflow-x: auto;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.assets {
|
|
236
|
+
background: var(--card);
|
|
237
|
+
padding: 24px;
|
|
238
|
+
border-radius: var(--radius);
|
|
239
|
+
border: 1px solid var(--border);
|
|
240
|
+
display: grid;
|
|
241
|
+
gap: 20px;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.assets__header h2 {
|
|
245
|
+
margin: 0 0 6px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.assets__header p {
|
|
249
|
+
margin: 0;
|
|
250
|
+
color: var(--muted);
|
|
251
|
+
font-family: var(--serif);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.assets__list {
|
|
255
|
+
display: grid;
|
|
256
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
257
|
+
gap: 14px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.asset-item {
|
|
261
|
+
padding: 16px;
|
|
262
|
+
border-radius: 14px;
|
|
263
|
+
border: 1px solid var(--border);
|
|
264
|
+
background: rgba(217, 121, 65, 0.08);
|
|
265
|
+
display: grid;
|
|
266
|
+
gap: 6px;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.asset-item span {
|
|
270
|
+
font-weight: 600;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.asset-item small {
|
|
274
|
+
color: var(--muted);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.footer {
|
|
278
|
+
display: flex;
|
|
279
|
+
flex-wrap: wrap;
|
|
280
|
+
justify-content: space-between;
|
|
281
|
+
gap: 12px;
|
|
282
|
+
color: var(--muted);
|
|
283
|
+
font-size: 14px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.footer__links {
|
|
287
|
+
display: flex;
|
|
288
|
+
gap: 16px;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.footer a {
|
|
292
|
+
color: var(--accent-strong);
|
|
293
|
+
text-decoration: none;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.footer a:hover {
|
|
297
|
+
text-decoration: underline;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
@media (max-width: 720px) {
|
|
301
|
+
.page {
|
|
302
|
+
padding-top: 32px;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.hero__actions {
|
|
306
|
+
flex-direction: column;
|
|
307
|
+
align-items: stretch;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.hero__actions .primary,
|
|
311
|
+
.hero__actions .ghost {
|
|
312
|
+
width: 100%;
|
|
313
|
+
text-align: center;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const origin = window.location.origin;
|
|
2
|
+
|
|
3
|
+
const config = {
|
|
4
|
+
mcpServers: {
|
|
5
|
+
'alpic-app': {
|
|
6
|
+
url: origin,
|
|
7
|
+
transport: 'http',
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const originTargets = document.querySelectorAll('[data-origin]');
|
|
13
|
+
originTargets.forEach((node) => {
|
|
14
|
+
node.textContent = origin;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const configNode = document.getElementById('config-json');
|
|
18
|
+
if (configNode) {
|
|
19
|
+
configNode.textContent = JSON.stringify(config, null, 2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const copyButton = document.getElementById('copy-config');
|
|
23
|
+
if (copyButton) {
|
|
24
|
+
copyButton.addEventListener('click', async () => {
|
|
25
|
+
try {
|
|
26
|
+
await navigator.clipboard.writeText(JSON.stringify(config, null, 2));
|
|
27
|
+
copyButton.textContent = 'Copied';
|
|
28
|
+
copyButton.classList.add('is-copied');
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
copyButton.textContent = 'Copy MCP config';
|
|
31
|
+
copyButton.classList.remove('is-copied');
|
|
32
|
+
}, 1600);
|
|
33
|
+
} catch {
|
|
34
|
+
copyButton.textContent = 'Copy failed';
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
copyButton.textContent = 'Copy MCP config';
|
|
37
|
+
}, 1600);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>ContractSpec Alpic MCP</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link
|
|
10
|
+
href="https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,600&family=Space+Grotesk:wght@400;500;600;700&display=swap"
|
|
11
|
+
rel="stylesheet"
|
|
12
|
+
/>
|
|
13
|
+
<link rel="stylesheet" href="/assets/style.css" />
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<main class="page">
|
|
17
|
+
<header class="hero">
|
|
18
|
+
<span class="hero__badge">Alpic MCP + ChatGPT App</span>
|
|
19
|
+
<h1>Ship MCP tools with a polished UI on Alpic.</h1>
|
|
20
|
+
<p>
|
|
21
|
+
This starter ships a minimal MCP surface and a static UI bundle.
|
|
22
|
+
Deploy it on Alpic and you get MCP endpoints at <span>/</span> and
|
|
23
|
+
<span>/mcp</span>, plus static assets served from
|
|
24
|
+
<span>/assets</span>.
|
|
25
|
+
</p>
|
|
26
|
+
<div class="hero__actions">
|
|
27
|
+
<button class="primary" id="copy-config">Copy MCP config</button>
|
|
28
|
+
<a class="ghost" href="#assets">See assets</a>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="hero__meta">
|
|
31
|
+
<div class="meta-card">
|
|
32
|
+
<span>Base URL</span>
|
|
33
|
+
<code data-origin>https://your-app.alpic.live</code>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="meta-card">
|
|
36
|
+
<span>Assets</span>
|
|
37
|
+
<code>/assets</code>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</header>
|
|
41
|
+
|
|
42
|
+
<section class="grid">
|
|
43
|
+
<article class="card">
|
|
44
|
+
<h2>MCP endpoints</h2>
|
|
45
|
+
<ul>
|
|
46
|
+
<li><strong>/</strong> - SSE + Streamable HTTP</li>
|
|
47
|
+
<li><strong>/mcp</strong> - Streamable HTTP</li>
|
|
48
|
+
</ul>
|
|
49
|
+
</article>
|
|
50
|
+
<article class="card">
|
|
51
|
+
<h2>UI resource</h2>
|
|
52
|
+
<p>
|
|
53
|
+
The MCP resource <strong>app://ui</strong> points to the UI entry at
|
|
54
|
+
<strong>/assets/index.html</strong>.
|
|
55
|
+
</p>
|
|
56
|
+
</article>
|
|
57
|
+
<article class="card">
|
|
58
|
+
<h2>Copy-ready config</h2>
|
|
59
|
+
<pre id="config-json" class="code"></pre>
|
|
60
|
+
</article>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section id="assets" class="assets">
|
|
64
|
+
<div class="assets__header">
|
|
65
|
+
<h2>Assets bundle</h2>
|
|
66
|
+
<p>Drop any static files in <code>assets/</code> before deploying.</p>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="assets__list">
|
|
69
|
+
<div class="asset-item">
|
|
70
|
+
<span>index.html</span>
|
|
71
|
+
<small>UI shell</small>
|
|
72
|
+
</div>
|
|
73
|
+
<div class="asset-item">
|
|
74
|
+
<span>style.css</span>
|
|
75
|
+
<small>Design system</small>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="asset-item">
|
|
78
|
+
<span>app.js</span>
|
|
79
|
+
<small>Client boot</small>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</section>
|
|
83
|
+
|
|
84
|
+
<footer class="footer">
|
|
85
|
+
<div><strong>ContractSpec</strong> + Alpic MCP starter</div>
|
|
86
|
+
<div class="footer__links">
|
|
87
|
+
<a href="https://docs.alpic.ai" target="_blank" rel="noreferrer">
|
|
88
|
+
Alpic docs
|
|
89
|
+
</a>
|
|
90
|
+
<a
|
|
91
|
+
href="https://docs.alpic.ai/guides/hosting-chatgpt-app-assets"
|
|
92
|
+
target="_blank"
|
|
93
|
+
rel="noreferrer"
|
|
94
|
+
>
|
|
95
|
+
Hosting assets
|
|
96
|
+
</a>
|
|
97
|
+
</div>
|
|
98
|
+
</footer>
|
|
99
|
+
</main>
|
|
100
|
+
<script type="module" src="/assets/app.js"></script>
|
|
101
|
+
</body>
|
|
102
|
+
</html>
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #f7f2ea;
|
|
3
|
+
--bg-alt: #e9f3f1;
|
|
4
|
+
--ink: #1f1b16;
|
|
5
|
+
--muted: #6b6258;
|
|
6
|
+
--card: #ffffff;
|
|
7
|
+
--accent: #1b7f6b;
|
|
8
|
+
--accent-strong: #156554;
|
|
9
|
+
--accent-warm: #d97941;
|
|
10
|
+
--border: rgba(31, 27, 22, 0.12);
|
|
11
|
+
--shadow: 0 18px 40px rgba(31, 27, 22, 0.12);
|
|
12
|
+
--radius: 24px;
|
|
13
|
+
--radius-small: 14px;
|
|
14
|
+
--space: 24px;
|
|
15
|
+
--mono: 'Space Grotesk', 'Avenir Next', sans-serif;
|
|
16
|
+
--serif: 'Newsreader', 'Georgia', serif;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
* {
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
body {
|
|
24
|
+
margin: 0;
|
|
25
|
+
font-family: var(--mono);
|
|
26
|
+
color: var(--ink);
|
|
27
|
+
background:
|
|
28
|
+
radial-gradient(circle at top left, #fff4e6, transparent 55%),
|
|
29
|
+
linear-gradient(135deg, var(--bg), var(--bg-alt));
|
|
30
|
+
min-height: 100vh;
|
|
31
|
+
display: flex;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
body::before,
|
|
36
|
+
body::after {
|
|
37
|
+
content: '';
|
|
38
|
+
position: fixed;
|
|
39
|
+
z-index: -1;
|
|
40
|
+
width: 340px;
|
|
41
|
+
height: 340px;
|
|
42
|
+
border-radius: 50%;
|
|
43
|
+
filter: blur(10px);
|
|
44
|
+
opacity: 0.35;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
body::before {
|
|
48
|
+
top: -120px;
|
|
49
|
+
right: -80px;
|
|
50
|
+
background: radial-gradient(circle, #b6e2d3, transparent 70%);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
body::after {
|
|
54
|
+
bottom: -140px;
|
|
55
|
+
left: -120px;
|
|
56
|
+
background: radial-gradient(circle, #f2c4a0, transparent 70%);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.page {
|
|
60
|
+
width: min(1100px, 92vw);
|
|
61
|
+
padding: 48px 0 64px;
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
gap: 48px;
|
|
65
|
+
animation: fade-in 0.6s ease-out;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@keyframes fade-in {
|
|
69
|
+
from {
|
|
70
|
+
opacity: 0;
|
|
71
|
+
transform: translateY(14px);
|
|
72
|
+
}
|
|
73
|
+
to {
|
|
74
|
+
opacity: 1;
|
|
75
|
+
transform: translateY(0);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.hero {
|
|
80
|
+
background: var(--card);
|
|
81
|
+
padding: clamp(28px, 4vw, 48px);
|
|
82
|
+
border-radius: var(--radius);
|
|
83
|
+
box-shadow: var(--shadow);
|
|
84
|
+
border: 1px solid var(--border);
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: column;
|
|
87
|
+
gap: 16px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.hero__badge {
|
|
91
|
+
align-self: flex-start;
|
|
92
|
+
padding: 8px 14px;
|
|
93
|
+
border-radius: 999px;
|
|
94
|
+
background: rgba(27, 127, 107, 0.12);
|
|
95
|
+
color: var(--accent-strong);
|
|
96
|
+
font-weight: 600;
|
|
97
|
+
letter-spacing: 0.03em;
|
|
98
|
+
text-transform: uppercase;
|
|
99
|
+
font-size: 12px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.hero h1 {
|
|
103
|
+
font-size: clamp(32px, 4vw, 48px);
|
|
104
|
+
margin: 0;
|
|
105
|
+
line-height: 1.05;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.hero p {
|
|
109
|
+
margin: 0;
|
|
110
|
+
font-size: 17px;
|
|
111
|
+
color: var(--muted);
|
|
112
|
+
font-family: var(--serif);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.hero p span {
|
|
116
|
+
font-weight: 600;
|
|
117
|
+
color: var(--ink);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.hero__actions {
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-wrap: wrap;
|
|
123
|
+
gap: 14px;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.hero__actions .primary,
|
|
127
|
+
.hero__actions .ghost {
|
|
128
|
+
border-radius: 999px;
|
|
129
|
+
padding: 12px 20px;
|
|
130
|
+
font-size: 15px;
|
|
131
|
+
border: none;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
text-decoration: none;
|
|
134
|
+
transition:
|
|
135
|
+
transform 0.2s ease,
|
|
136
|
+
box-shadow 0.2s ease;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.hero__actions .primary {
|
|
140
|
+
background: var(--accent);
|
|
141
|
+
color: #fff;
|
|
142
|
+
box-shadow: 0 14px 24px rgba(27, 127, 107, 0.25);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.hero__actions .primary:hover {
|
|
146
|
+
transform: translateY(-1px);
|
|
147
|
+
box-shadow: 0 18px 28px rgba(27, 127, 107, 0.3);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.hero__actions .primary.is-copied {
|
|
151
|
+
background: var(--accent-strong);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.hero__actions .ghost {
|
|
155
|
+
border: 1px solid var(--border);
|
|
156
|
+
color: var(--ink);
|
|
157
|
+
background: transparent;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.hero__meta {
|
|
161
|
+
display: grid;
|
|
162
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
163
|
+
gap: 12px;
|
|
164
|
+
margin-top: 10px;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.meta-card {
|
|
168
|
+
border-radius: var(--radius-small);
|
|
169
|
+
padding: 14px 16px;
|
|
170
|
+
background: rgba(27, 127, 107, 0.08);
|
|
171
|
+
display: grid;
|
|
172
|
+
gap: 6px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.meta-card span {
|
|
176
|
+
font-size: 12px;
|
|
177
|
+
text-transform: uppercase;
|
|
178
|
+
letter-spacing: 0.04em;
|
|
179
|
+
color: var(--muted);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.meta-card code {
|
|
183
|
+
font-family: var(--mono);
|
|
184
|
+
font-weight: 600;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.grid {
|
|
188
|
+
display: grid;
|
|
189
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
190
|
+
gap: 18px;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.card {
|
|
194
|
+
background: var(--card);
|
|
195
|
+
border: 1px solid var(--border);
|
|
196
|
+
border-radius: var(--radius-small);
|
|
197
|
+
padding: 20px;
|
|
198
|
+
display: flex;
|
|
199
|
+
flex-direction: column;
|
|
200
|
+
gap: 12px;
|
|
201
|
+
box-shadow: 0 14px 26px rgba(31, 27, 22, 0.08);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.card h2 {
|
|
205
|
+
margin: 0;
|
|
206
|
+
font-size: 20px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.card p {
|
|
210
|
+
margin: 0;
|
|
211
|
+
color: var(--muted);
|
|
212
|
+
font-family: var(--serif);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.card ul {
|
|
216
|
+
margin: 0;
|
|
217
|
+
padding-left: 18px;
|
|
218
|
+
color: var(--muted);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.card strong {
|
|
222
|
+
color: var(--ink);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.code {
|
|
226
|
+
background: #0f172a;
|
|
227
|
+
color: #dbeafe;
|
|
228
|
+
padding: 16px;
|
|
229
|
+
border-radius: 12px;
|
|
230
|
+
font-size: 12px;
|
|
231
|
+
line-height: 1.5;
|
|
232
|
+
overflow-x: auto;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.assets {
|
|
236
|
+
background: var(--card);
|
|
237
|
+
padding: 24px;
|
|
238
|
+
border-radius: var(--radius);
|
|
239
|
+
border: 1px solid var(--border);
|
|
240
|
+
display: grid;
|
|
241
|
+
gap: 20px;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.assets__header h2 {
|
|
245
|
+
margin: 0 0 6px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.assets__header p {
|
|
249
|
+
margin: 0;
|
|
250
|
+
color: var(--muted);
|
|
251
|
+
font-family: var(--serif);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.assets__list {
|
|
255
|
+
display: grid;
|
|
256
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
257
|
+
gap: 14px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.asset-item {
|
|
261
|
+
padding: 16px;
|
|
262
|
+
border-radius: 14px;
|
|
263
|
+
border: 1px solid var(--border);
|
|
264
|
+
background: rgba(217, 121, 65, 0.08);
|
|
265
|
+
display: grid;
|
|
266
|
+
gap: 6px;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.asset-item span {
|
|
270
|
+
font-weight: 600;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.asset-item small {
|
|
274
|
+
color: var(--muted);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.footer {
|
|
278
|
+
display: flex;
|
|
279
|
+
flex-wrap: wrap;
|
|
280
|
+
justify-content: space-between;
|
|
281
|
+
gap: 12px;
|
|
282
|
+
color: var(--muted);
|
|
283
|
+
font-size: 14px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.footer__links {
|
|
287
|
+
display: flex;
|
|
288
|
+
gap: 16px;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.footer a {
|
|
292
|
+
color: var(--accent-strong);
|
|
293
|
+
text-decoration: none;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.footer a:hover {
|
|
297
|
+
text-decoration: underline;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
@media (max-width: 720px) {
|
|
301
|
+
.page {
|
|
302
|
+
padding-top: 32px;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.hero__actions {
|
|
306
|
+
flex-direction: column;
|
|
307
|
+
align-items: stretch;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.hero__actions .primary,
|
|
311
|
+
.hero__actions .ghost {
|
|
312
|
+
width: 100%;
|
|
313
|
+
text-align: center;
|
|
314
|
+
}
|
|
315
|
+
}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as elysia0 from "elysia";
|
|
2
|
+
|
|
3
|
+
//#region src/server.d.ts
|
|
4
|
+
declare const app: elysia0.default<"", {
|
|
5
|
+
decorator: {};
|
|
6
|
+
store: {};
|
|
7
|
+
derive: {};
|
|
8
|
+
resolve: {};
|
|
9
|
+
}, {
|
|
10
|
+
typebox: {};
|
|
11
|
+
error: {};
|
|
12
|
+
}, {
|
|
13
|
+
schema: {};
|
|
14
|
+
standaloneSchema: {};
|
|
15
|
+
macro: {};
|
|
16
|
+
macroFn: {};
|
|
17
|
+
parser: {};
|
|
18
|
+
response: {};
|
|
19
|
+
}, {}, {
|
|
20
|
+
derive: {};
|
|
21
|
+
resolve: {};
|
|
22
|
+
schema: {};
|
|
23
|
+
standaloneSchema: {};
|
|
24
|
+
response: {};
|
|
25
|
+
}, {
|
|
26
|
+
derive: {};
|
|
27
|
+
resolve: {};
|
|
28
|
+
schema: {};
|
|
29
|
+
standaloneSchema: {};
|
|
30
|
+
response: {};
|
|
31
|
+
}>;
|
|
32
|
+
type App = typeof app;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { App, app };
|
|
35
|
+
//# sourceMappingURL=server.d.mts.map
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { createAlpicMcpApp } from "@contractspec/bundle.alpic";
|
|
2
|
+
import { LogLevel, Logger } from "@contractspec/lib.logger";
|
|
3
|
+
|
|
4
|
+
//#region src/server.ts
|
|
5
|
+
const PORT = Number(process.env.PORT ?? 8080);
|
|
6
|
+
const logger = new Logger({
|
|
7
|
+
level: process.env.NODE_ENV === "production" ? LogLevel.INFO : LogLevel.DEBUG,
|
|
8
|
+
environment: process.env.NODE_ENV || "development",
|
|
9
|
+
enableTracing: false,
|
|
10
|
+
enableTiming: false,
|
|
11
|
+
enableContext: false,
|
|
12
|
+
enableColors: process.env.NODE_ENV !== "production"
|
|
13
|
+
});
|
|
14
|
+
const app = createAlpicMcpApp({
|
|
15
|
+
logger,
|
|
16
|
+
serverName: process.env.ALPIC_MCP_NAME ?? "contractspec-alpic-mcp",
|
|
17
|
+
serverVersion: process.env.ALPIC_MCP_VERSION ?? "1.0.0"
|
|
18
|
+
});
|
|
19
|
+
app.listen(PORT);
|
|
20
|
+
logger.info("alpic-mcp.started", {
|
|
21
|
+
port: PORT,
|
|
22
|
+
endpoints: {
|
|
23
|
+
root: "/",
|
|
24
|
+
mcp: "/mcp",
|
|
25
|
+
assets: "/assets"
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const shutdown = async (signal) => {
|
|
29
|
+
logger.info("alpic-mcp.shutdown", { signal });
|
|
30
|
+
await logger.flush();
|
|
31
|
+
process.exit(0);
|
|
32
|
+
};
|
|
33
|
+
process.on("SIGTERM", () => {
|
|
34
|
+
shutdown("SIGTERM");
|
|
35
|
+
});
|
|
36
|
+
process.on("SIGINT", () => {
|
|
37
|
+
shutdown("SIGINT");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
export { app };
|
|
42
|
+
//# sourceMappingURL=server.mjs.map
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contractspec/app.alpic-mcp",
|
|
3
|
+
"version": "0.0.0-canary-20260204161232",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
|
|
7
|
+
"publish:pkg:canary": "bun publish:pkg --tag canary",
|
|
8
|
+
"clean": "rm -rf dist",
|
|
9
|
+
"lint": "bun run lint:fix",
|
|
10
|
+
"lint:fix": "eslint src --fix",
|
|
11
|
+
"lint:check": "eslint src",
|
|
12
|
+
"build": "tsdown && mkdir -p dist && cp -R assets dist/assets",
|
|
13
|
+
"dev": "tsdown --watch",
|
|
14
|
+
"start": "node dist/server.js"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@contractspec/bundle.alpic": "0.0.0-canary-20260204161232",
|
|
18
|
+
"@contractspec/lib.logger": "1.56.1"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@contractspec/tool.tsdown": "1.56.1",
|
|
22
|
+
"@contractspec/tool.typescript": "1.56.1",
|
|
23
|
+
"@types/node": "^24.4.0",
|
|
24
|
+
"tsdown": "^0.20.1",
|
|
25
|
+
"typescript": "^5.9.3"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/lssm-tech/contractspec.git",
|
|
31
|
+
"directory": "packages/apps/alpic-mcp"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"registry": "https://registry.npmjs.org/",
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://contractspec.io",
|
|
38
|
+
"exports": {
|
|
39
|
+
".": "./dist/index.mjs",
|
|
40
|
+
"./server": "./dist/server.mjs",
|
|
41
|
+
"./*": "./*"
|
|
42
|
+
}
|
|
43
|
+
}
|