list-collections.tsā¢5.13 kB
import { z } from "zod";
import { api } from "../api";
import { MCP_CONFIG } from "../config";
import { SMART_CONTRACTS_USER_LIMIT, SMART_CONTRACTS_ADMIN_LIMIT } from "../utils/constants";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// Input schema - no parameters needed for listing collections
export const listCollectionsInputSchema = z.object({});
export interface CollectionListResult {
success: boolean;
data?: {
personalCollections: Array<{
id: string;
name: string;
symbol: string;
type: string;
status: string;
ercType: string;
assetCount: number;
address?: string;
createdAt?: string;
}>;
commonCollections: Array<{
id: string;
name: string;
symbol: string;
type: string;
status: string;
ercType: string;
assetCount: number;
address?: string;
}>;
externalCollections: Array<{
id: string;
name: string;
symbol: string;
type: string;
status: string;
ercType: string;
assetCount: number;
address?: string;
}>;
limits: {
personal: {
current: number;
max: number;
canCreateMore: boolean;
};
};
};
error?: string;
}
export async function listCollections(): Promise<CollectionListResult> {
try {
// Get user info first to determine limits and filter contracts
const accountResponse = await api.account.getMe({
deviceId: MCP_CONFIG.DEVICE_ID,
});
if (accountResponse.status !== "ok" || !accountResponse.ok) {
return {
success: false,
error: "Failed to get user account information",
};
}
const user = accountResponse.ok;
const isAdmin = user.role === "ADMIN";
const userId = user.userId;
const smartContractsLimit = isAdmin ? SMART_CONTRACTS_ADMIN_LIMIT : SMART_CONTRACTS_USER_LIMIT;
// Get contracts list
const contractsResponse = await api.contracts.list(null);
if (contractsResponse.status !== "ok") {
return {
success: false,
error: contractsResponse.errorCode || "Failed to load collections",
};
}
const contracts = contractsResponse.data || [];
// Group contracts like in Raycast
const personalContracts = contracts
.filter((contract) => contract.type !== "EXTERNAL" && userId === contract.userId)
.map((contract) => ({
id: contract.id,
name: contract.name,
symbol: contract.symbol,
type: contract.type,
status: contract.status,
ercType: contract.ercType,
assetCount: contract.count ?? 0,
address: contract.address || undefined,
createdAt: contract.createdAt ? new Date(contract.createdAt.seconds * 1000).toISOString() : undefined,
}));
const commonContracts = contracts
.filter((contract) => contract.type === "EXTERNAL")
.map((contract) => ({
id: contract.id,
name: contract.name,
symbol: contract.symbol,
type: contract.type,
status: contract.status,
ercType: contract.ercType,
assetCount: contract.count ?? 0,
address: contract.address || undefined,
}));
const externalContracts = contracts
.filter((contract) => contract.type !== "EXTERNAL" && userId !== contract.userId)
.map((contract) => ({
id: contract.id,
name: contract.name,
symbol: contract.symbol,
type: contract.type,
status: contract.status,
ercType: contract.ercType,
assetCount: contract.count ?? 0,
address: contract.address || undefined,
}));
return {
success: true,
data: {
personalCollections: personalContracts,
commonCollections: commonContracts,
externalCollections: externalContracts,
limits: {
personal: {
current: personalContracts.length,
max: smartContractsLimit,
canCreateMore: personalContracts.length < smartContractsLimit,
},
},
},
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "Unknown error occurred",
};
}
}
export function registerListCollectionsTool(server: McpServer, config?: { apiKey?: string }): void {
server.tool(
"list_collections",
"List all user collections (personal, common, and external)",
{},
{
title: "View Collections",
},
async () => {
if ((!MCP_CONFIG.API_KEY || MCP_CONFIG.API_KEY === "") && config?.apiKey) {
MCP_CONFIG.API_KEY = config.apiKey;
}
if (!MCP_CONFIG.API_KEY || MCP_CONFIG.API_KEY === "") {
return {
content: [
{
type: "text",
text: "API key is required to use this tool.",
},
],
};
}
const result = await listCollections();
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
},
);
}