@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 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.1では `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 = 5;
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 memo = normalizeMeasureMemo(m.memo);
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
- ...memo !== void 0 ? { memo } : {}
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.1" },
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.1",
4
- "description": "MCP server for EZTab \u2014 lets an AI agent build and edit guitar/bass tablature.",
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"