@hidechae/eztab-mcp 0.5.1 → 0.5.2
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/README.md +3 -1
- package/dist/server.js +24 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ Run standalone for testing: `task mcp` (or `npx tsx mcp/server.ts`).
|
|
|
113
113
|
- コードは track 0 のもの(`set_chords` は track 0 の列で指定)。`write_measures(track > 0)` ではコード指定と、
|
|
114
114
|
既存小節の拍子を変える `time` を拒否する
|
|
115
115
|
- `get_tab` は全パートを小節ごとに並べて表示する(`track` で1パートに絞れる)
|
|
116
|
-
- `send_to_eztab` は対応する最新の形式リビジョンをヘッダーに付けて送る(0.5.
|
|
116
|
+
- `send_to_eztab` は対応する最新の形式リビジョンをヘッダーに付けて送る(0.5.2では `6`)。
|
|
117
117
|
対応上限を超える形式のタブは閲覧のみで、編集・送信できない。
|
|
118
118
|
0.2.0以前のMCPは複数パートのタブを送り返せない(サーバが409で拒否する)。
|
|
119
119
|
|
|
@@ -146,3 +146,5 @@ Claude Desktop では入力欄の「+」→ eztab → `import_tab_from_image`
|
|
|
146
146
|
EZTab のモデルに無い記譜(スライド・ハンマリング・プリング → タイ/スラー、
|
|
147
147
|
ハーモニクス・ビブラート・装飾音 → 主音のみ等)の寄せ方は手順書
|
|
148
148
|
([prompts.ts](prompts.ts))に書いてあり、書き起こし後に簡略化した箇所を報告させる。
|
|
149
|
+
|
|
150
|
+
0.5.2以降は曲全体のMarkdownメモ(形式リビジョン6)を既存の編集・送信操作で保持します。曲メモの入力・表示はwebアプリで行います。
|
package/dist/server.js
CHANGED
|
@@ -7,7 +7,8 @@ import { z } from "zod";
|
|
|
7
7
|
|
|
8
8
|
// ../src/types/tab.ts
|
|
9
9
|
var TAB_FILE_VERSION = 1;
|
|
10
|
-
var SUPPORTED_FORMAT_REVISION =
|
|
10
|
+
var SUPPORTED_FORMAT_REVISION = 6;
|
|
11
|
+
var SONG_MEMO_FORMAT_REVISION = 6;
|
|
11
12
|
var MULTI_TRACK_FORMAT_REVISION = 2;
|
|
12
13
|
var HARMONICS_FORMAT_REVISION = 3;
|
|
13
14
|
var TEMPO_CHANGES_FORMAT_REVISION = 4;
|
|
@@ -252,10 +253,24 @@ function normalizeChords(raw, subdivisions) {
|
|
|
252
253
|
}
|
|
253
254
|
return out;
|
|
254
255
|
}
|
|
256
|
+
var MAX_SONG_MEMO_LENGTH = 1e4;
|
|
257
|
+
var DocumentValidationError = class extends Error {
|
|
258
|
+
};
|
|
259
|
+
function normalizeSongMemo(raw) {
|
|
260
|
+
if (typeof raw !== "string") return void 0;
|
|
261
|
+
const memo = raw.replace(/\r\n?/g, "\n");
|
|
262
|
+
if (memo.length > MAX_SONG_MEMO_LENGTH) {
|
|
263
|
+
throw new DocumentValidationError(`\u66F2\u30E1\u30E2\u306F${MAX_SONG_MEMO_LENGTH}\u6587\u5B57\u4EE5\u5185\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);
|
|
264
|
+
}
|
|
265
|
+
return memo.trim() ? memo : void 0;
|
|
266
|
+
}
|
|
255
267
|
function normalizeDocument(data) {
|
|
256
268
|
if (!data || !Array.isArray(data.tuning) || !Array.isArray(data.measures)) {
|
|
257
269
|
throw new Error("Not a valid EZTab document");
|
|
258
270
|
}
|
|
271
|
+
const memo = normalizeSongMemo(data.memo);
|
|
272
|
+
if (memo === void 0) delete data.memo;
|
|
273
|
+
else data.memo = memo;
|
|
259
274
|
data.measures = data.measures.map((m) => {
|
|
260
275
|
let beats = m.beats;
|
|
261
276
|
let rawSubs = m.subdivisions;
|
|
@@ -278,14 +293,14 @@ function normalizeDocument(data) {
|
|
|
278
293
|
);
|
|
279
294
|
const rawChords = Array.isArray(m.chords) ? m.chords : typeof m.chord === "string" && m.chord ? [m.chord] : [];
|
|
280
295
|
const chords = normalizeChords(rawChords, subdivisions);
|
|
281
|
-
const
|
|
296
|
+
const memo2 = normalizeMeasureMemo(m.memo);
|
|
282
297
|
return {
|
|
283
298
|
beats,
|
|
284
299
|
beatUnit,
|
|
285
300
|
subdivisions,
|
|
286
301
|
cells,
|
|
287
302
|
chords,
|
|
288
|
-
...
|
|
303
|
+
...memo2 !== void 0 ? { memo: memo2 } : {}
|
|
289
304
|
};
|
|
290
305
|
});
|
|
291
306
|
if (!Array.isArray(data.keys) || data.keys.length === 0) {
|
|
@@ -536,7 +551,7 @@ function mainMeasures(doc) {
|
|
|
536
551
|
}
|
|
537
552
|
function closeWorkspace(doc) {
|
|
538
553
|
const ws = doc.workspace;
|
|
539
|
-
if (!ws) return doc;
|
|
554
|
+
if (!ws) return closeWorkspace(openWorkspace(doc));
|
|
540
555
|
const bodies = trackBodies(doc);
|
|
541
556
|
const main = bodies[0];
|
|
542
557
|
const {
|
|
@@ -546,6 +561,7 @@ function closeWorkspace(doc) {
|
|
|
546
561
|
tracks: _tr,
|
|
547
562
|
formatRevision,
|
|
548
563
|
tempoChanges: rawTempoChanges,
|
|
564
|
+
memo: rawMemo,
|
|
549
565
|
...rest
|
|
550
566
|
} = doc;
|
|
551
567
|
const tempoChanges = normalizeTempoChanges(doc.tempo, rawTempoChanges, main.measures.length);
|
|
@@ -554,6 +570,8 @@ function closeWorkspace(doc) {
|
|
|
554
570
|
tuning: [...main.tuning],
|
|
555
571
|
measures: main.measures.map(storedMeasure)
|
|
556
572
|
};
|
|
573
|
+
const memo = normalizeSongMemo(rawMemo);
|
|
574
|
+
if (memo !== void 0) out.memo = memo;
|
|
557
575
|
const extras = bodies.slice(1).map(
|
|
558
576
|
(b, i) => ({
|
|
559
577
|
...ws.metas[i + 1],
|
|
@@ -567,6 +585,7 @@ function closeWorkspace(doc) {
|
|
|
567
585
|
if (extras.length > 0) out.tracks = extras;
|
|
568
586
|
if (tempoChanges) out.tempoChanges = tempoChanges;
|
|
569
587
|
let required = 1;
|
|
588
|
+
if (memo !== void 0) required = SONG_MEMO_FORMAT_REVISION;
|
|
570
589
|
if (extras.length > 0) required = Math.max(required, MULTI_TRACK_FORMAT_REVISION);
|
|
571
590
|
if (bodies.some((b) => measuresHaveHarmonics(b.measures))) {
|
|
572
591
|
required = Math.max(required, HARMONICS_FORMAT_REVISION);
|
|
@@ -1021,7 +1040,7 @@ var state = {
|
|
|
1021
1040
|
source: null
|
|
1022
1041
|
};
|
|
1023
1042
|
var server = new McpServer(
|
|
1024
|
-
{ name: "eztab", version: "0.5.
|
|
1043
|
+
{ name: "eztab", version: "0.5.2" },
|
|
1025
1044
|
{
|
|
1026
1045
|
instructions: "All indices are 0-based: measure 0 is the first measure, string 0 is the top (highest) string, and column 0 is the first column. Notes and chords share the same column grid. Subdivisions are per beat and can differ within a measure (e.g. [2,2,3,2] mixes a triplet beat into straight eighths), so columns per measure = the sum of its per-beat subdivisions; get_tab's ruler shows the column indices. add_measures `at` is a 0-based insert position too. No need to ask the user about indexing. Exception: write_measures uses guitar string numbers (1 = top line), matching the labels get_tab prints. To write whole measures (e.g. transcribing a score or an image), prefer write_measures over set_cells \u2014 it takes one string per beat and does the column arithmetic for you. For transcribing from an image, follow the import_tab_from_image prompt. To deliver a result to the EZTab app, call send_to_eztab; to fix an existing tab, list_tabs \u2192 open_tab \u2192 edit \u2192 send_to_eztab. A tab can hold up to 4 tracks (parts, e.g. guitar + bass); track 0 is the main track. Tools that edit notes take an optional 0-based `track` (default 0). Measures and time signatures are shared by all tracks (adding/removing a measure affects every track); subdivisions are per track; chords belong to track 0 and use its columns."
|
|
1027
1046
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hidechae/eztab-mcp",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "MCP server for EZTab
|
|
3
|
+
"version": "0.5.2",
|
|
4
|
+
"description": "MCP server for EZTab — lets an AI agent build and edit guitar/bass tablature.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"eztab-mcp": "dist/server.js"
|