mcpField
I
imagekit-sdk-reference

imagekit-sdk-reference

github.com/imagekit-developer開発2357 回インストール4 週間前に更新
リポジトリ

imagekit-sdk-reference について

imagekit-sdk-referenceは、ImageKit TypeScript SDKを使う開発者やエージェント向けのリファレンススキルです。アセット操作、メタデータ、変換、利用状況の確認に必要なメソッドや型を説明します。

主な機能

  1. 01SDKのシグネチャと型の説明
  2. 02メディアアセットの一覧・検索・管理
  3. 03URLからのファイルアップロード
  4. 04フォルダーとファイルバージョンの操作
  5. 05変換済み画像URLの構築

活用シーン

  1. 01ImageKit SDKを使ったTypeScriptコードの作成
  2. 02メディアライブラリの検索と更新
  3. 03URLで取得できるメディアのアップロード
  4. 04SDKのページネーションとnull許容フィールドへの対応

MCP 対応

`mcp_imagekit_api_*`ツールの呼び出し方を案内し、パラメーター名やエラー処理も説明します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/imagekit-developer/skills --skill imagekit-sdk-reference

インストール後、Claude Code で/imagekit-sdk-referenceを入力して読み込まれたか確認します。

詳細

ImageKit TypeScript SDK リファレンス

mcp_imagekit_api_* ツールを呼び出す前、または ImageKit SDK を使用した TypeScript コードを書く前に、このスキルを読んでください。@imagekit/nodejs の正確なメソッドシグネチャ、パラメーター型、戻り値の形、エラー処理パターンが記載されています。

ルール:

  1. 正確なパラメーター名を使用してください。SDK では camelCase が厳密に指定されています。
  2. assets.list() は (File | Folder)[] を返します。for...of と if (item.type === 'file') で型を絞り込んでください。.filter((i): i is File => ...) は絶対に使用しないでください。searchQuery と型指定された File[] の使い分け、および型述語が失敗する理由の詳細は、search-assets スキルを参照してください。
  3. execute/MCP コードでは、単一の API 呼び出しを try/catch で囲まないでください。ツールがエラーを処理します。特定の失敗に応じて分岐する場合に限り、instanceof ImageKit.APIError ではなく、エラーを ダックタイピング('status' in err)で判定してください。これは、サンドボックスでは SDK の値インポートを利用できないためです。
  4. ページネーションには skip/limit を使用してください(1 リクエストあたり最大 1000 件)。
  5. アップロードには URL のみ使用できます。file パラメーターには URL 文字列を指定する必要があります。ローカルファイルパス、Buffer、ストリームは渡せません。先に upload-files スキルを読んでください。
  6. null 許容のプロパティ(tags、AITags、customCoordinates)には、オプショナルチェーン(?.)または null チェックが必要です。
  7. .find() は T | undefined を返すため、プロパティにアクセスする前に必ず undefined を確認してください。

TypeScript の注意点

assets.list() の結果のユニオン型の絞り込み、つまり for...of と if の使用方法、.filter((i): i is File => ...) の型述語が Deno のグローバル File と衝突する理由、そして searchQuery と型指定された File[] の使い分けについては、search-assets スキルで詳しく説明しています。リスト結果を扱う際は、その内容に従ってください。以下は、そこで扱われていない SDK 固有の注意点です。

パターン問題対処法
.find(i => ...)T | undefined を返すundefined を確認して型を絞り込む
file.tagsstring[] | null?. または null チェックを使用する
file.AITagsArray | null?. または null チェックを使用する
assets.list() の File | Folder における、特定のメンバーだけが持つプロパティユニオン型で共有されるのは name、type、createdAt、updatedAt、customMetadata のみです。それ以外のプロパティには型の絞り込みが必要ですif で一度絞り込めば、その後は自由にアクセスできます。type === 'folder' で分岐してください(→ Folder、それ以外 → File。File.type は 'file' | 'file-version' のためです)
.find() は T | undefined を返します
const item = assets.find((i) => i.name === 'hero.jpg');
// Type: (File | Folder) | undefined

item.fileId; // ❌ Two errors: possibly undefined AND possibly Folder

// ✅ Fix:
if (item && item.type === 'file') {
  item.fileId; // works
}
File の null 許容プロパティ
const file = await client.files.get(fileId);

file.tags.length;     // ❌ tags is string[] | null
file.tags?.length;    // ✅ optional chaining

file.AITags.map(...); // ❌ AITags is Array | null
file.AITags?.map(...); // ✅

型

File
{
  fileId: string; name: string; filePath: string; type: 'file' | 'file-version';
  url: string; thumbnail: string; isPrivateFile: boolean; isPublished: boolean;
  // Media
  fileType: string; // 'image' | 'non-image'
  mime: string; size: number; width: number; height: number; hasAlpha: boolean;
  // Video-only
  duration: number; videoCodec: string; audioCodec: string; bitRate: number;
  // Tags & metadata
  tags: string[] | null;
  AITags: Array<{ name: string; confidence: number; source: string }> | null;
  customMetadata: Record<string, unknown>; description: string;
  customCoordinates: string | null;
  embeddedMetadata: Record<string, unknown>;
  // Versioning
  versionInfo: { id: string; name: string };
  createdAt: string; updatedAt: string;
}
Folder
{
  folderId: string; folderPath: string; name: string; type: 'folder';
  customMetadata: Record<string, unknown>;
  createdAt: string; updatedAt: string;
}
CustomMetadataField
{
  id: string; name: string; label: string;
  schema: { type: 'Text' | 'Number' | 'Date' | 'Boolean' | 'SingleSelect' | 'MultiSelect'; /* ... */ };
}

ファイル操作

ファイルをアップロードする(URL のみ)
// ⚠️ ONLY URL-based uploads work. Local files cannot be uploaded.
const file = await client.files.upload({
  file: 'https://example.com/img.jpg', // URL string ONLY in MCP context
  fileName: 'img.jpg',
  folder: '/uploads',
  tags: ['tag1'],
  customMetadata: { key: 'value' },
  // Key optional params:
  // useUniqueFileName: true,      // default true — appends random suffix
  // isPrivateFile: false,
  // overwriteFile: false,         // replace existing file at same path
  // overwriteTags: false,
  // overwriteCustomMetadata: false,
  // extensions: [{ name: 'google-auto-tagging', maxTags: 5 }],
  // transformation: { pre: 'w-200' },
  // webhookUrl: 'https://...',
});
// Returns: File object
ファイルの詳細を取得する
const file = await client.files.get(fileId); // Returns: File
アセットを一覧表示/検索する
const result = await client.assets.list({
  searchQuery: 'name = "img.jpg"', // Lucene-like syntax
  path: '/uploads',
  fileType: 'image',           // 'image' | 'non-image' | 'all'
  type: 'file',                // 'file' | 'folder' | 'file-version' | 'all'
  sort: 'ASC_NAME',
  skip: 0,
  limit: 100,
});
// Returns: (File | Folder)[] — a flat array, NOT { files, folders }

型の絞り込み方法は searchQuery を使用するかどうかによって異なります。詳細なルールは search-assets スキルを参照してください(トップレベルの type を指定すると型指定された File[] が返されます。searchQuery を指定すると (File | Folder)[] のユニオン型が返されるため、for...of と if で絞り込みます)。

共有プロパティ(File と Folder の両方で安全に使用できます):name、type、customMetadata、createdAt、updatedAt

File のみのプロパティ(型の絞り込みが必要です):fileId、filePath、fileType、mime、size、width、height、url、thumbnail、tags、AITags、description、isPrivateFile、isPublished、customCoordinates、embeddedMetadata、versionInfo、duration、videoCodec、audioCodec、bitRate、hasAlpha

Folder のみのプロパティ:folderId、folderPath

ファイルを更新/削除する
await client.files.update(fileId, { tags: ['newTag'], customMetadata: { key: 'value' } }); // Returns: File
await client.files.delete(fileId); // Returns: void
ファイルをコピー/移動/名前変更する
await client.files.copy({ sourceFilePath: '/a/img.jpg', destinationPath: '/b/', includeFileVersions: false });
await client.files.move({ sourceFilePath: '/a/img.jpg', destinationPath: '/b/' });
await client.files.rename({ filePath: '/a/img.jpg', newFileName: 'new.jpg', purgeCache: false });

一括操作

await client.files.bulk.delete({ fileIds: ['id1', 'id2'] }); // { successfullyDeletedFileIds }
await client.files.bulk.addTags({ fileIds: ['id1'], tags: ['promo'] });    // max 50 files
await client.files.bulk.removeTags({ fileIds: ['id1'], tags: ['old'] });
await client.files.bulk.removeAITags({ fileIds: ['id1'], AITags: ['cat'] });

フォルダー操作

await client.folders.create({ folderName: 'myfolder', parentFolderPath: '/' });
await client.folders.delete({ folderPath: '/myfolder' });

// Copy / move / rename — async operations, return { jobId }
const { jobId } = await client.folders.copy({ sourceFolderPath: '/a', destinationPath: '/b/' });
const { jobId } = await client.folders.move({ sourceFolderPath: '/a', destinationPath: '/b/' });
const { jobId } = await client.folders.rename({ folderPath: '/a', newFolderName: 'renamed' });

// Check job status
const job = await client.folders.job.get(jobId);
// job.status: 'Pending' | 'Completed'

ファイルのバージョン

const versions = await client.files.versions.list(fileId);      // Returns: File[]
const version = await client.files.versions.get(versionId, { fileId }); // Returns: File
await client.files.versions.restore(versionId, { fileId });     // Returns: File
await client.files.versions.delete(versionId, { fileId });      // Returns: void

ファイルのメタデータ

const metadata = await client.files.metadata.getFromURL({ url: 'https://ik.imagekit.io/x/img.jpg' });
// Returns EXIF/IPTC metadata: { height, width, exif, iptc, xmp, ... }

キャッシュの無効化

const purge = await client.cache.invalidation.create({ url: 'https://ik.imagekit.io/x/img.jpg' });
const status = await client.cache.invalidation.get(purge.requestId);
// status.status: 'Pending' | 'Completed'

URL の構築

const url = client.helper.buildSrc({
  urlEndpoint: 'https://ik.imagekit.io/your_id',
  src: '/path/img.jpg',
  transformation: [{ width: 400, height: 300, format: 'webp', quality: 80 }],
  signed: true,
  expiresIn: 3600,
});
// Returns: string

カスタムメタデータフィールド

// Define schema fields for your media library
const field = await client.customMetadataFields.create({
  name: 'brand', label: 'Brand Name',
  schema: { type: 'Text', defaultValue: '', isValueRequired: false },
});
const fields = await client.customMetadataFields.list(); // Returns: CustomMetadataField[]
await client.customMetadataFields.update(field.id, { label: 'Updated Label' });
await client.customMetadataFields.delete(field.id);

アカウントの使用状況

const usage = await client.accounts.usage.get({ startDate: '2025-01-01', endDate: '2025-01-31' });
// { bandwidthBytes, mediaLibraryStorageBytes, extensionUnitsCount, videoProcessingUnitsCount }

ページネーションとエラー処理

// Offset-based pagination — skip / limit (max 1000). No cursor support.
for (let skip = 0; ; skip += 100) {
  const page = await client.assets.list({ skip, limit: 100 });
  if (!page.length) break;
  for (const item of page) {
    if (item.type === 'file') {
      // item is narrowed to File here
    }
  }
}

// Error handling — in execute/MCP code you normally DON'T need try/catch: let the
// error propagate and the tool reports it for you. The ONLY reason to catch is to
// branch on a specific failure (e.g. treat 404 as "not found") — and then you must
// re-throw everything you don't handle. Duck-type the error: a value import of the
// SDK (import ImageKit from '@imagekit/nodejs') is NOT available in the Deno sandbox
// and throws at runtime, so don't rely on `instanceof ImageKit.APIError`.
try {
  return await client.files.get(fileId);
} catch (err) {
  if (err && typeof err === 'object' && 'status' in err) {
    const e = err as { status?: number; message?: string };
    if (e.status === 404) return null;  // the one case we handle
  }
  throw err;  // re-throw anything else — don't swallow it
}
// Auto-retries: connection errors, 408/409/429/5xx — up to 2× with exponential backoff

一括ファイル操作の並列実行

操作するファイルのリストがある場合、ループ内で決して await しないでください。100 件ずつに分割し、各バッチを Promise.allSettled() で並列実行します。

// ✅ files is any array of { fileId, name } — from assets.list(), a prior search, etc.
const CHUNK = 100;
const chunks = [];
for (let i = 0; i < files.length; i += CHUNK) chunks.push(files.slice(i, i + CHUNK));

for (const chunk of chunks) {
  await Promise.allSettled(
    chunk.map(({ fileId, name }) =>
      client.files.update(fileId, { tags: ['promo'] })
        .then(() => ({ fileId, name, status: 'ok' }))
        .catch((err: unknown) => ({ fileId, name, status: 'error', error: String(err) }))
    )
  );
}

同じパターンは files.delete(fileId)、files.copy({...})、files.move({...}) にも適用されます。

delete / addTags / removeTags では、一括エンドポイント(各 50 ID まで)を優先してください。ID を分割し、各チャンクを並列実行します。

const CHUNK = 50;
const chunks = [];
for (let i = 0; i < allFileIds.length; i += CHUNK) chunks.push(allFileIds.slice(i, i + CHUNK));
await Promise.allSettled(chunks.map(ids => client.files.bulk.delete({ fileIds: ids })));

コメント