yorck-mcp 0.1.3 → 0.1.4
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/package.json +1 -1
- package/src/index.ts +12 -1
- package/src/landing.ts +2 -2
- package/src/skill-content.ts +36 -0
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { reserveUnlimited, cancelOrder, getOrder } from "./yorck/booking.ts";
|
|
|
7
7
|
import { whoAmI } from "./yorck/auth.ts";
|
|
8
8
|
import { showtimeToIcs } from "./lib/ics.ts";
|
|
9
9
|
import { PublicYorckMcp, YorckMcp } from "./mcp.ts";
|
|
10
|
-
import { installScript, YORCK_MOVIE_AGENT_SKILL } from "./skill-content.ts";
|
|
10
|
+
import { installScript, skillZip, YORCK_MOVIE_AGENT_SKILL } from "./skill-content.ts";
|
|
11
11
|
import { landingPage } from "./landing.ts";
|
|
12
12
|
|
|
13
13
|
export { PublicYorckMcp, YorckMcp };
|
|
@@ -42,6 +42,17 @@ app.get("/skill/SKILL.md", (c) => c.text(YORCK_MOVIE_AGENT_SKILL, 200, { "Conten
|
|
|
42
42
|
|
|
43
43
|
app.get("/install.sh", (c) => c.text(installScript("https://yorck-mcp.isiklimahir.workers.dev"), 200, { "Content-Type": "text/x-shellscript; charset=utf-8" }));
|
|
44
44
|
|
|
45
|
+
app.get("/skill.zip", () => {
|
|
46
|
+
const zip = skillZip();
|
|
47
|
+
const body = zip.buffer.slice(zip.byteOffset, zip.byteOffset + zip.byteLength) as ArrayBuffer;
|
|
48
|
+
return new Response(body, {
|
|
49
|
+
headers: {
|
|
50
|
+
"Content-Type": "application/zip",
|
|
51
|
+
"Content-Disposition": "attachment; filename=yorck-movie-agent-skill.zip",
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
45
56
|
// REST endpoints (also handy for quick curl tests)
|
|
46
57
|
app.get("/v1/films", async (c) => {
|
|
47
58
|
const q = c.req.query();
|
package/src/landing.ts
CHANGED
|
@@ -14,7 +14,7 @@ export function landingPage(): string {
|
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
|
16
16
|
<main>
|
|
17
|
-
<nav class="nav"><div class="brand">yorck-mcp</div><div class="links"><a class="pill" href="/public/mcp">public MCP</a><a class="pill" href="/skill/SKILL.md">SKILL.md</a><a class="pill" href="/install.sh">install.sh</a><a class="pill" href="https://www.npmjs.com/package/yorck-mcp">npm</a></div></nav>
|
|
17
|
+
<nav class="nav"><div class="brand">yorck-mcp</div><div class="links"><a class="pill" href="/public/mcp">public MCP</a><a class="pill" href="/skill/SKILL.md">SKILL.md</a><a class="pill" href="/skill.zip">skill.zip</a><a class="pill" href="/install.sh">install.sh</a><a class="pill" href="https://www.npmjs.com/package/yorck-mcp">npm</a></div></nav>
|
|
18
18
|
<section class="hero">
|
|
19
19
|
<div>
|
|
20
20
|
<div class="eyebrow">Berlin cinema for agents</div>
|
|
@@ -55,7 +55,7 @@ export function landingPage(): string {
|
|
|
55
55
|
--env YORCK_PASSWORD=your-password \\
|
|
56
56
|
--env YORCK_UNLIMITED_CARD=your-card-number \\
|
|
57
57
|
yorck -- npx -y yorck-mcp mcp-stdio</pre></div>
|
|
58
|
-
<div class="panel" id="skill"><h3>Install the skill file</h3><pre class="screen"><button class="copy">copy</button>curl -fsSL https://yorck-mcp.isiklimahir.workers.dev/install.sh | bash</pre><p>Or from npm:</p><pre class="screen"><button class="copy">copy</button>npx -y yorck-mcp install-skill --target claude</pre></div>
|
|
58
|
+
<div class="panel" id="skill"><h3>Install the skill file</h3><p>Claude Web skills can upload the ZIP. Claude Code can install the filesystem skill.</p><pre class="screen"><button class="copy">copy</button>https://yorck-mcp.isiklimahir.workers.dev/skill.zip</pre><pre class="screen"><button class="copy">copy</button>curl -fsSL https://yorck-mcp.isiklimahir.workers.dev/install.sh | bash</pre><p>Or from npm:</p><pre class="screen"><button class="copy">copy</button>npx -y yorck-mcp install-skill --target claude</pre></div>
|
|
59
59
|
<div class="panel" id="cli"><h3>Use it directly</h3><pre class="screen"><button class="copy">copy</button>npx -y yorck-mcp whats-on --when tonight --after 18:00
|
|
60
60
|
npx -y yorck-mcp plan --q "devil wears prada" --when tonight
|
|
61
61
|
npx -y yorck-mcp seat-map 1007-30456 --out seat-map.svg</pre></div>
|
package/src/skill-content.ts
CHANGED
|
@@ -118,6 +118,42 @@ Private/local mode can book with credentials. It currently supports Yorck Unlimi
|
|
|
118
118
|
- "book the best option if my Unlimited card makes it free"
|
|
119
119
|
`;
|
|
120
120
|
|
|
121
|
+
function crc32(bytes: Uint8Array): number {
|
|
122
|
+
let crc = 0xffffffff;
|
|
123
|
+
for (const byte of bytes) {
|
|
124
|
+
crc ^= byte;
|
|
125
|
+
for (let i = 0; i < 8; i++) crc = (crc >>> 1) ^ (0xedb88320 & -(crc & 1));
|
|
126
|
+
}
|
|
127
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function u16(n: number) { return [n & 255, (n >>> 8) & 255]; }
|
|
131
|
+
function u32(n: number) { return [n & 255, (n >>> 8) & 255, (n >>> 16) & 255, (n >>> 24) & 255]; }
|
|
132
|
+
|
|
133
|
+
export function skillZip(): Uint8Array {
|
|
134
|
+
const encoder = new TextEncoder();
|
|
135
|
+
const filename = encoder.encode("yorck-movie-agent/SKILL.md");
|
|
136
|
+
const content = encoder.encode(YORCK_MOVIE_AGENT_SKILL);
|
|
137
|
+
const crc = crc32(content);
|
|
138
|
+
const localHeader = new Uint8Array([
|
|
139
|
+
...u32(0x04034b50), ...u16(20), ...u16(0), ...u16(0), ...u16(0), ...u16(0),
|
|
140
|
+
...u32(crc), ...u32(content.length), ...u32(content.length), ...u16(filename.length), ...u16(0),
|
|
141
|
+
]);
|
|
142
|
+
const centralOffset = localHeader.length + filename.length + content.length;
|
|
143
|
+
const centralHeader = new Uint8Array([
|
|
144
|
+
...u32(0x02014b50), ...u16(20), ...u16(20), ...u16(0), ...u16(0), ...u16(0), ...u16(0),
|
|
145
|
+
...u32(crc), ...u32(content.length), ...u32(content.length), ...u16(filename.length), ...u16(0), ...u16(0), ...u16(0), ...u16(0), ...u32(0), ...u32(0),
|
|
146
|
+
]);
|
|
147
|
+
const centralSize = centralHeader.length + filename.length;
|
|
148
|
+
const end = new Uint8Array([
|
|
149
|
+
...u32(0x06054b50), ...u16(0), ...u16(0), ...u16(1), ...u16(1), ...u32(centralSize), ...u32(centralOffset), ...u16(0),
|
|
150
|
+
]);
|
|
151
|
+
const out = new Uint8Array(localHeader.length + filename.length + content.length + centralHeader.length + filename.length + end.length);
|
|
152
|
+
let o = 0;
|
|
153
|
+
for (const part of [localHeader, filename, content, centralHeader, filename, end]) { out.set(part, o); o += part.length; }
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
|
|
121
157
|
export function installScript(baseUrl = "https://yorck-mcp.isiklimahir.workers.dev") {
|
|
122
158
|
return `#!/usr/bin/env bash
|
|
123
159
|
set -euo pipefail
|