MCP + SDK

ForTem MCP Documentation

ForTem provides two ways for game developers to manage NFT items on the SUI blockchain: an MCP Server that AI coding assistants (Claude Code, Cursor, VS Code Copilot) can call directly, and a JavaScript SDK (@fortemlabs/sdk-js) for server-side operations. Use them individually or together.

What is MCP?

The Model Context Protocol (MCP) is an open standard that lets AI coding assistants call external APIs as "tools." Instead of writing API integration code yourself, you describe what you want in natural language and the AI assistant calls ForTem's MCP server directly -- creating collections, minting items, querying ownership, and more.

Why use ForTem MCP?

  • Zero boilerplate -- ask your AI assistant to "create a collection" and it handles the API call
  • Faster iteration -- manage NFT items without leaving your editor
  • Works alongside SDK -- use MCP for management tasks, SDK for production server-side logic

Quick Start

Prerequisites

  • A ForTem developer account and API key (from the ForTem developer dashboard)
  • An AI coding assistant that supports MCP (Claude Code, Cursor, VS Code Copilot, etc.)

MCP Server URLs

EnvironmentURL
Productionhttps://mcp.fortem.gg/mcp
Developmenthttps://mcp-dev.fortem.gg/mcp

Connect MCP Server

MCP authenticates via OAuth in the browser — no API key needed for MCP setup. Just add the server URL.

// .mcp.json in your project root
{
  "mcpServers": {
    "fortem": {
      "type": "http",
      "url": "https://mcp.fortem.gg/mcp"
    }
  }
}
When you first use a ForTem MCP tool, your browser will open for OAuth authentication. No API key is needed in the config.
// .cursor/mcp.json in your project root
{
  "mcpServers": {
    "fortem": {
      "type": "http",
      "url": "https://mcp.fortem.gg/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "fortem": {
      "type": "http",
      "url": "https://mcp.fortem.gg/mcp"
    }
  }
}
API Key is only needed for the SDK (server-side operations like image upload and minting). Get it from the ForTem developer dashboard.

SDK Installation

npm install @fortemlabs/sdk-js

When to Use MCP vs SDK vs Both

TaskMCPSDKRecommendation
Create collection Yes Yes Both work, MCP is simpler
List collections Yes Yes MCP is faster for quick lookups
Mint item (no image) Yes Yes MCP is simpler
Mint item (with image) No Yes MCP has base64 size limit — Why?
Upload image No Yes MCP cannot handle large base64 payloads — Why?
Query items Yes Yes MCP is faster for quick lookups
Verify user Yes Yes MCP is simpler
Server-side verification No Yes Serverless functions need SDK
Rule of thumb: Use MCP for queries and management tasks. Use SDK for file uploads and server-side logic.

MCP Tools Reference

These tools are automatically available to your AI assistant once the MCP server is configured.

developer_create_collection
Create a new NFT collection. Returns the collection ID and on-chain object ID.
developer_list_collections
List all collections owned by the authenticated developer.
developer_create_item
Mint a new item in a collection. Requires collection ID, name, description, quantity, recipient address, and redeem code.
developer_list_items
List all items in a given collection.
developer_get_item
Get details of a specific item by collection ID and redeem code.
developer_verify_user
Verify a wallet user's identity and ownership.
developer_upload_image
Upload an image for an item. Limited by base64 payload size -- for images over a few KB, use the SDK instead.

SDK Reference

Authentication

import { createFortemClient } from '@fortemlabs/sdk-js';

const fortem = createFortemClient({
  apiKey: 'YOUR_API_KEY',
  network: 'mainnet'
});

// Get nonce and authenticate
const { data: { nonce } } = await fortem.auth.getNonce();
await fortem.auth.getAccessToken(nonce);

Image Upload

Constraints: 256x256 pixels, max 200KB, JPEG/PNG/WebP only.
const file = new File([buffer], 'image.png', { type: 'image/png' });
const { data: { itemImage } } = await fortem.items.uploadImage(collectionId, file);

Mint Item

await fortem.items.create(collectionId, {
  name: 'Flame Sword',
  description: 'A legendary weapon forged in fire',
  quantity: 1,
  redeemCode: 'a1b2-c3d4-e5f6-7890',
  recipientAddress: '0x...',
  itemImage: itemImage, // IPFS hash from uploadImage
  attributes: [
    { trait_type: 'Element', value: 'Fire' },
    { trait_type: 'Rarity', value: 'Legendary' }
  ]
});

Get Item

const { data: item } = await fortem.items.get(collectionId, redeemCode);

AI Prompt Templates

Copy these prompts into your AI coding assistant to perform common ForTem operations.

Creating a Collection

Prompt
Use the fortem MCP to create an NFT collection.
- Name: [name]
- Description: [description]
Return the collection ID and objectId.

Minting Items with Images

Prompt
Use the fortem SDK to upload images and mint items.
MCP has base64 size limits, so image upload MUST use the SDK.

1. Install @fortemlabs/sdk-js if not installed
2. Upload these images to fortem and get IPFS hashes:
   - [image paths]
3. Mint items with the uploaded hashes:
   - Collection ID: [ID]
   - Recipient wallet: [address]
   - Redeem code: generate random xxxx-xxxx-xxxx-xxxx format
   - Quantity: [N]

SDK auth:
const fortem = createFortemClient({ apiKey: '[KEY]', network: 'mainnet' });
const { data: { nonce } } = await fortem.auth.getNonce();
await fortem.auth.getAccessToken(nonce);

Image upload:
const file = new File([buffer], 'filename.png', { type: 'image/png' });
const { data: { itemImage } } = await fortem.items.uploadImage(collectionId, file);

Create a Node.js script to run this. Read API key from .env.local.

Redeem Code Verification (Server-side)

Prompt
Create a serverless function to verify fortem redeem codes.

Flow:
1. Client sends POST { redeemCode, walletAddress }
2. Server uses fortem SDK: items.get(collectionId, redeemCode)
3. Verify: item exists, status is 'REDEEMED', owner matches wallet
4. Use KV store for duplicate prevention
5. Return card info on success

Security: API key server-side only, wallet ownership check, server-side dedup.

Image Constraints

PropertyRequirement
Max file size200KB
Dimensions256 x 256 pixels
FormatsJPEG, PNG, WebP
Upload methodSDK only (MCP has base64 size limit)
Tip: Use sharp or canvas to resize images before uploading.
import sharp from 'sharp';

const resized = await sharp('input.png')
  .resize(256, 256, { fit: 'cover' })
  .png({ quality: 80 })
  .toBuffer();

// Verify size
if (resized.length > 200 * 1024) {
  throw new Error('Image exceeds 200KB limit');
}

Redeem Code Format

PropertySpecification
Formatxxxx-xxxx-xxxx-xxxx (16 hex characters with dashes)
GenerationMust use crypto.randomBytes (cryptographically secure)
UniquenessMust be unique per item
PredictabilityMust never be predictable or sequential
import crypto from 'crypto';

function generateRedeemCode() {
  const bytes = crypto.randomBytes(8);
  const hex = bytes.toString('hex');
  return `${hex.slice(0,4)}-${hex.slice(4,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}`;
}

// Example output: "a3f1-b2c4-d5e6-7890"

Complete Example: Game Item Minting Pipeline

A full Node.js script that authenticates, resizes an image, uploads it, and mints an NFT item.

import { createFortemClient } from '@fortemlabs/sdk-js';
import sharp from 'sharp';
import crypto from 'crypto';
import fs from 'fs';
import { config } from 'dotenv';

config({ path: '.env.local' });

// ── Config ──────────────────────────────────────
const API_KEY      = process.env.FORTEM_API_KEY;
const COLLECTION_ID = process.env.FORTEM_COLLECTION_ID;
const RECIPIENT     = process.env.RECIPIENT_WALLET;
const IMAGE_PATH    = './assets/sword.png';

// ── Generate redeem code ────────────────────────
function generateRedeemCode() {
  const hex = crypto.randomBytes(8).toString('hex');
  return `${hex.slice(0,4)}-${hex.slice(4,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}`;
}

async function main() {
  // 1. Authenticate
  const fortem = createFortemClient({
    apiKey: API_KEY,
    network: 'mainnet'
  });
  const { data: { nonce } } = await fortem.auth.getNonce();
  await fortem.auth.getAccessToken(nonce);
  console.log('Authenticated successfully');

  // 2. Resize image to 256x256, ensure under 200KB
  const resized = await sharp(IMAGE_PATH)
    .resize(256, 256, { fit: 'cover' })
    .png({ quality: 80 })
    .toBuffer();

  if (resized.length > 200 * 1024) {
    throw new Error(`Image too large: ${(resized.length / 1024).toFixed(1)}KB`);
  }
  console.log(`Image resized: ${(resized.length / 1024).toFixed(1)}KB`);

  // 3. Upload image to ForTem (returns IPFS hash)
  const file = new File([resized], 'sword.png', { type: 'image/png' });
  const { data: { itemImage } } = await fortem.items.uploadImage(
    COLLECTION_ID, file
  );
  console.log(`Uploaded image: ${itemImage}`);

  // 4. Mint item with all attributes
  const redeemCode = generateRedeemCode();
  await fortem.items.create(COLLECTION_ID, {
    name: 'Flame Sword',
    description: 'A legendary weapon forged in the heart of a volcano',
    quantity: 1,
    redeemCode: redeemCode,
    recipientAddress: RECIPIENT,
    itemImage: itemImage,
    attributes: [
      { trait_type: 'Element', value: 'Fire' },
      { trait_type: 'Rarity', value: 'Legendary' },
      { trait_type: 'Attack', value: '95' }
    ]
  });

  // 5. Log the redeem code
  console.log(`Minted successfully!`);
  console.log(`Redeem code: ${redeemCode}`);
  console.log(`Recipient:   ${RECIPIENT}`);
}

main().catch(console.error);
Environment variables (.env.local):
FORTEM_API_KEY=your_api_key_here
FORTEM_COLLECTION_ID=your_collection_id
RECIPIENT_WALLET=0x...

FAQ

Why can't I upload images or mint items with images directly through MCP?

The ForTem MCP server is hosted on AWS (cloud), not on your local machine. This means it cannot access files on your local filesystem. For example, if your image is at /Users/name/image.png, the MCP server running on AWS has no way to read that file.

Additionally, LLMs have inherent limitations when generating images as base64 data, making it impractical to pass image data through the MCP protocol reliably.

This is NOT a blocker. You can easily handle image uploads using the ForTem SDK alongside MCP. See the prompt example below.

Workaround: Use SDK for Image Upload + MCP for Everything Else

When using an AI coding assistant (Claude, Cursor, etc.) with the ForTem MCP connected, simply instruct it to use the SDK for image uploads and MCP for the rest. The AI assistant can read local files, call the SDK, and use MCP tools — all in one workflow.

Prompt Example
Use my ForTem API key from .env to upload images via the SDK (cURL or @fortemlabs/sdk-js),
then mint the items using the ForTem MCP.

1. Upload image from ./assets/sword.png using the SDK
2. Use the returned IPFS hash to mint the item via MCP:
   - Collection ID: [ID]
   - Name: Legendary Sword
   - Recipient: [wallet address]
   - Redeem code: generate random xxxx-xxxx-xxxx-xxxx format

The AI assistant will automatically handle the SDK authentication, file reading, image upload, and MCP minting — all from a single prompt.

If there is enough demand in the future, we may provide a local MCP server (similar to tools like Phaser Editor or Figma) that can directly access your filesystem for seamless image uploads.

Troubleshooting

ProblemCauseSolution
MCP auth failure Session expired or invalid API key Reload your IDE or re-save .mcp.json
Image upload fails via MCP base64 payload exceeds size limit Use SDK items.uploadImage() instead
413 Entity Too Large Image exceeds 200KB Compress/resize with sharp before upload
Default image shown after mint Wrong itemImage hash Use the exact hash returned from uploadImage response
redeemCode collision Duplicate code generated Use crypto.randomBytes and check uniqueness
SDK token expired Access token has 5-minute TTL SDK auto-refreshes; re-authenticate if issues persist
recipientAddress error Missing or empty wallet address Provide a valid SUI wallet address (starts with 0x)