시작하기

Minds 클라이언트 라이브러리

구성된 Mind를 애플리케이션에 포함합니다. Minds CLI로 설정한 후 메시징, 이벤트 및 Builder API 라우트를 위한 타입이 지정된 Node 클라이언트입니다.

@animocabrands/minds-client-libMind를 애플리케이션이나 제품에 래핑하고 임베드하는 방법입니다. 대부분의 빌더는 Minds CLI 로 시작해 Mind를 나열하고, 세부 정보를 확인하고, Cognition을 모니터링하고, Circle을 관리하고, Bazaar를 탐색한 다음, 출시할 준비가 되면 여기로 넘어옵니다. 이 라이브러리는 동일한 Builder API 를 TypeScript 타입과 함께 제공합니다: 메시징, waitForReply, SSE 이벤트, 그리고 터미널에서 이미 실행해 본 계정 라우트까지.
패키지를 프로젝트의 서버 측에 추가하세요. UI, 브랜딩, 사용자 흐름은 그대로 유지됩니다. 클라이언트는 타입이 지정된 HTTP와 api.build로의 스트리밍을 처리합니다. 계정 설정 을 완료하고, CLI로 Mind를 검증한 다음 아래 예제를 연결하거나, 구성이 완료되면 코딩 에이전트에게 전달하세요.

설치

**Node 22+**가 필요합니다.
npm install @animocabrands/minds-client-lib

인증

계정 및 메시징 라우트에 대해 Builder API 키를 전달합니다. 라이브러리는 인증된 라우트(≥0.1.2)에서 X-Api-Key 보냅니다. **X-Access-Key**는 더 이상 사용되지 않으므로 사용하지 마세요. 환경 변수 이름은 MINDS_BUILDER_API_KEY로 유지됩니다.
import {
  BUILDER_API_KEY_ENV,
  BUILDER_API_KEY_HEADER,
  createMindsClient,
} from "@animocabrands/minds-client-lib";
 
const builderApiKey = process.env[BUILDER_API_KEY_ENV];
if (!builderApiKey) throw new Error(`${BUILDER_API_KEY_ENV} is not set`);
 
const client = createMindsClient({ builderApiKey });

클라이언트 생성

import { createMindsClient } from "@animocabrands/minds-client-lib";
 
const client = createMindsClient({ builderApiKey: yourBuilderApiKey });
createMindsClient({})는 공개 Bazaar 카탈로그(client.bazaar.*)에만 유효합니다. 키를 제공하지 않은 경우 인증 메서드는 생성 시점이 아니라 호출 시점missing_builder_api_key 코드와 함께 MindsApiError를 발생시킵니다.

Minds 목록

listMinds()는 계정의 모든 Mind(mindId, name, model, species 및 관련 필드)를 반환합니다.
const minds = await client.listMinds();
const mindId = minds[0]?.mindId;
humanId는 Builder API 키에서 자동으로 확인됩니다. 명시적으로 재정의해야 할 때는 listMinds({ humanId })를 전달하세요.

Mind 세부 정보

getMind(mindId)는 이메일, 지갑 주소, 체인, 종, isEnabled 등 전체 세부 정보를 반환합니다:
const detail = await client.getMind(mindId);
console.log(detail.email, detail.walletAddress, detail.chain);

Cognition 잔액 및 사용량

Mind별 Cognition 사용량과 잔액 조회는 CLI 명령과 동일하게 동작합니다. Mind는 대화할 때뿐만 아니라 추론하고, 도구를 실행하고, 자율 작업을 수행할 때도 Cognition을 소비합니다. 두 메서드 모두 mindId(UUID)와 선택적 AbortSignal을 받습니다. Cognition은 Mind의 추론, 도구 사용 및 자율 작업을 지원합니다. 시간에 따른 사용량 및 도구별 사용량을 보려면 getCognitionUsagegetCognitionUsageByTool을 사용하세요. 남은 Cognition 잔액을 보려면 getCognitionBalance를 사용하세요:
const mindId = (await client.listMinds())[0]?.mindId;
if (!mindId) throw new Error("No Minds on this account");
 
const usage = await client.getCognitionUsage(mindId, { interval: "1d" });
console.log(usage.items); // [{ bucket, value }, ...]
 
const byTool = await client.getCognitionUsageByTool(mindId, { interval: "day" });
console.log(byTool.summary); // [{ tool, callCount, creditsUsed, ... }, ...]
console.log(byTool.timeline); // [{ tool, timeBucket, callCount, creditsUsed }, ...]
 
const balance = await client.getCognitionBalance(mindId);
console.log(balance.cognition);
두 사용량 메서드는 서로 다른 간격 값을 허용합니다. getCognitionUsage1m, 5m, 15m, 1h, 1d, 1w, 1M을 허용하고, getCognitionUsageByToolhour, day, week, month만 허용합니다. 선택적 startTimeendTime(ISO 날짜-시간)으로 두 메서드 모두 조회 기간을 제한할 수 있습니다.

Mind 상태

Mind를 삭제하지 않고 활성화하거나 비활성화합니다:
await client.updateMindStatus(mindId, { isEnabled: false });
await client.updateMindStatus(mindId, { isEnabled: true });
updateMindStatus는 업데이트된 BuilderMind를 반환합니다.

Circles

Mind의 Circle은 인간 협력자의 집합입니다. getCircleCircleMember[] 배열을 직접 반환하고, addCircleMembersremoveCircleMembers는 이메일별 결과와 요약을 담은 CircleMutationResult 엔벨로프를 반환합니다:
const members = await client.getCircle(mindId);
console.log(members.map((m) => m.email));
 
const added = await client.addCircleMembers(mindId, {
  emails: ["someone@company.com", "peer@company.com"],
  isActive: true,
});
console.log(added.summary);
 
const removed = await client.removeCircleMembers(mindId, {
  emails: ["someone@company.com"],
});
console.log(removed.items);
Circle은 인간 협력자 이메일만 허용하며 빌더를 위한 Mind @hellominds.ai 주소는 허용하지 않습니다. 이 API를 통해 Mind 간 Circle 멤버십은 지원되지 않습니다. listCirclesForAccount()listMinds()를 호출한 다음 각 Mind에 대해 병렬로 getCircle()을 호출하는 편의 기능입니다. 핫 패스 대신 계정 전체 개요를 파악하는 데 사용하세요.

Bazaar 카탈로그

공개 Bazaar 카탈로그는 client.bazaar로 사용할 수 있으며 API 키가 필요하지 않습니다. ID 검색(skillId, appId)을 위해 Bazaar를 사용한 다음, 아래의 Mind 장착 메서드로 해당 ID를 장착하세요. 라우트 형태는 API 참조 의 Bazaar 및 Minds 태그에 있으며, CLI는 minds bazaar를 통해 동일한 카탈로그를 제공합니다. 조회된 목록의 각 항목에는 플랫폼 전체에서 해당 항목을 장착한 Mind의 수를 나타내는 equippedCount가 포함될 수 있습니다. 이는 플랫폼 전체의 인기이며, Mind별 장착된 세트는 listEquippedSkills / listEquippedApps를 사용하세요.
const catalog = createMindsClient({}).bazaar;
 
const skills = await catalog.listSkills({ search: "research", page: 1, pageSize: 25 });
const skill = await catalog.getSkill("skill_abc123");
 
const apps = await catalog.listApps({ search: "notion", tier: "verified" });
const app = await catalog.getApp("app_xyz789");
 
const result = await catalog.collectSearchResults({
  scanMax: 200,
  max: 50,
  sort: "equipped",
  fetchPage: (page, pageSize) => catalog.listSkills({ search: "agent", page, pageSize }),
  getEquippedCount: (s) => s.equippedCount ?? 0,
  getName: (s) => s.name,
  getCreatedAt: (s) => s.createdAt,
});
앱은 appIdappName(name 아님)을 사용합니다. collectSearchResultsscanMax까지 자동 페이지 매김을 수행하고, 클라이언트 측 정렬/필터를 적용하며, 스캔된 세트가 max를 초과하면 truncated를 보고합니다. sort: "equipped"는 Mind별 장착 상태가 아니라 equippedCount 내림차순(플랫폼 인기)으로 정렬합니다.

스킬과 앱 장착

Mind에서 스킬과 앱을 나열, 장착 또는 장착 해제합니다(Builder API 키가 필요합니다). 본문은 { ids: string[] }를 사용합니다. 뮤테이션은 skillId / appId, isEquipped, changed가 포함된 { results: [...] }를 반환합니다(앱 결과에는 appVersionIdversion도 포함될 수 있음):
const equippedSkills = await client.listEquippedSkills(mindId);
await client.equipSkills(mindId, { ids: [skill.skillId] });
await client.unequipSkills(mindId, { ids: [skill.skillId] });
 
const equippedApps = await client.listEquippedApps(mindId);
await client.equipApps(mindId, { ids: [app.appId] });
await client.unequipApps(mindId, { ids: [app.appId] });
카탈로그를 탐색해야 하는 경우 먼저 client.bazaar로 ID를 검색하세요. 장착된 스킬에는 source가 포함됩니다: mind는 카탈로그 또는 Mind가 작성한 스킬, system은 플랫폼 스킬(예: Skill Architect)입니다.

대화

메시지를 보내기 전에 안정적인 별칭(예: main)을 Mind에 바인딩하세요:
await client.ensureConversation("main", mindId);
ensureConversation은 멱등성을 가지며 해당 Mind에 별칭이 이미 있는 경우 기존 대화가 반환됩니다. 별칭을 직접 관리할 때의 하위 수준 도우미:
const conversations = await client.listConversations();
const conversation = await client.getConversation("main");
await client.createConversation({ alias: "main", mindId });

전송 및 내역

await client.sendMessage({ alias: "main", messageText: "Hello" });
 
const rows = await client.getHistory("main", { limit: 50 });
const after = rows.at(-1)?.fingerprint;
const newer = await client.getHistory("main", { after, limit: 50 });
getHistory는 인간과 Mind의 전체 대화 기록을 반환합니다. 행에는 senderType(1 = 인간, 0 = Mind)이 사용됩니다. 동일한 필드가 subscribeEvents / eventsIterator / waitForReply의 SSE 이벤트에도 나타납니다. sendMessage에는 aliasmessageText가 필요합니다. 선택적 attachments아웃바운드 객체를 허용하며, fileNamemimeType이 포함된 공개 HTTPS url을 선호합니다:
await client.sendMessage({
  alias: "main",
  messageText: "Summarize this PDF in one sentence.",
  attachments: [
    {
      url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
      fileName: "dummy.pdf",
      mimeType: "application/pdf",
      extension: "pdf",
    },
  ],
});
이미지 URL은 동일한 형태(mimeType: "image/png" 등)를 사용합니다. getHistory, waitForReply 및 SSE 이벤트에 대한 Mind 회신에는 다음과 같은 인바운드 아티팩트가 포함될 수 있습니다:
// One attachment on a Mind reply (PDF; artifact body truncated)
{
  artifactId: "7388b65d-144a-49ff-a4dc-cb7c23ded982",
  slug: "whale_watchtower_skill_artifact_1_0_5",
  logicalType: "document",
  mimeType: "application/pdf",
  extension: "pdf",
  artifact: "JVBERi0xLjQK...",
}
아웃바운드 전송은 인라인 페이로드에 content를 사용하고, 인바운드 회신은 동일한 역할에 artifact를 사용합니다. sluglogicalType은 선택적 문자열이며, 값을 고정 열거형이 아닌 힌트로 취급합니다. 필드 세부 정보는 API 참조 를 확인하세요. getLatestHistoryFingerprint는 최신 메시지의 지문을 반환합니다. 이를 getHistory에서 after로 전달하여 최신 행만 가져오거나, waitForReply 전에 afterFingerprint로 전달하여 전송 후 도착한 회신을 발견하세요.
별칭이 마지막으로 대화한 Mind 확인:
const mindId = await client.getMindIdForAlias("main");

Mind 답장 대기

waitForReply는 먼저 라이브 이벤트 스트림에서 수신 대기한 다음, 회신이 도착하거나 시간이 초과될 때까지 기록을 폴링합니다.
const before = await client.getLatestHistoryFingerprint("main");
 
await client.sendMessage({ alias: "main", messageText: "Summarize our plan." });
 
const outcome = await client.waitForReply({
  alias: "main",
  timeoutMs: 180_000,
  afterFingerprint: before,
  sentMessageText: "Summarize our plan.",
});
 
if (!outcome.timedOut) {
  console.log(outcome.reply.messageText);
}
SSE 또는 내역 행을 직접 필터링할 때 패키지의 isReplyEvent를 사용하세요.

라이브 이벤트 (SSE)

콜백으로 구독:
const sub = client.subscribeEvents({
  alias: "main",
  onEvent: (event) => {
    console.log(event.messageText);
  },
  onError: (err) => console.error(err),
});
 
// later
sub.close();
또는 비동기 반복자 사용:
for await (const event of client.eventsIterator({ alias: "main" })) {
  console.log(event.fingerprint, event.messageText);
}
프로세스가 종료될 때 취소하려면 반복자 또는 구독 옵션에 signal을 전달하세요.

오류

실패한 HTTP 호출은 status, code, message가 포함된 MindsApiError를 발생시킵니다. builderApiKey 없이 인증 메서드를 호출하면 호출 시점에 missing_builder_api_key가 발생합니다. 401/403은 Builder API 키 누락 또는 폐기로 해석하세요. 429에는 재시도 안내가 포함될 수 있습니다.

메서드

영역메서드
AccountlistMinds, getMind
CognitiongetCognitionUsage, getCognitionUsageByTool, getCognitionBalance
Mind statusupdateMindStatus
EquiplistEquippedSkills, equipSkills, unequipSkills, listEquippedApps, equipApps, unequipApps
CirclesgetCircle, addCircleMembers, removeCircleMembers, listCirclesForAccount
Bazaarbazaar.listSkills, bazaar.getSkill, bazaar.listApps, bazaar.getApp, bazaar.collectSearchResults
ConversationscreateConversation, listConversations, getConversation, ensureConversation, getMindIdForAlias
MessagingsendMessage, getHistory, getLatestHistoryFingerprint
ReplieswaitForReply, isReplyEvent, isReplyHistoryRow
EventssubscribeEvents, eventsIterator, parseSseChunk
타입(BuilderMind, Conversation, MessageRecord, MessagingEvent, CognitionBalance, BazaarSkill, BazaarApp, EquippedSkill, EquippedApp, CircleMember, CircleMutationResult, CognitionUsageResponse, CognitionUsageByToolResponse, UpdateMindStatusBody, …) 및 parseHumanIdFromBuilderApiKey는 패키지 엔트리에서 내보내집니다.