SOLARI API & SDK
모든 워크플로를 위한 하나의 API.
CLI 와 MCP 서버가 실행하는 읽기 전용 도구 전부를 HTTP 호출 한 번으로 — TypeScript·Python SDK 를 쓰면 메서드 호출 한 번으로. 같은 데이터, 같은 액세스 토큰, 주고받는 건 JSON.
https://solari.sh/mcp/api/v1인증
CLI 가 발급하는 bearer 토큰 하나.
solari CLI 로 한 번 로그인하고, 그 액세스 토큰을 코드가 도는 곳에 넘기세요.
- solari auth token
- 로그인한 계정의 액세스 토큰을 출력해요. 만료됐으면 먼저 갱신해요. 8시간 유효.
- SOLARI_TOKEN
- SDK 와 CLI 가 이 변수를 읽어요. CI 나 컨테이너는 따로 로그인할 필요가 없어요.
모든 요청에 Authorization: Bearer <token> 으로 보내세요.
엔드포인트
엔드포인트 넷. 나머지는 도구가 해요.
도구 이름·인자·결과는 solari help all --json 과 MCP 서버가 설명하는 그대로예요.
- GET/tools
- 이 계정이 부를 수 있는 모든 도구와 JSON 입력 스키마.
- GET/tools/{name}
- 도구 하나의 스키마와 설명.
- POST/tools/{name}
- 도구 실행. JSON 본문이 인자, 응답이 결과예요.
- GET/me
- 토큰 뒤의 계정.
예시
브랜드 하나를 한 번에 찾기.
응답은 CLI 가 --json 으로 찍는 것과 같아요. found 와, 잘 맞는 순서의 items.
curl -sS https://solari.sh/mcp/api/v1/tools/solari_catalog_instagram_account_search \
-H "Authorization: Bearer $(solari auth token)" \
-H "Content-Type: application/json" \
-d '{"query":"nike","limit":3}'SDK
HTTP 대신 클라이언트로.
두 클라이언트 모두 이 엔드포인트를 얇게 감싼 의존성 없는 라이브러리예요. 점으로 이은 경로가 도구 이름이 돼요: catalog.instagram.account.search 는 solari_catalog_instagram_account_search.
TypeScript · Node, Bun, Deno, Workers, 브라우저
npm install @brandazine/solari-sdkimport { Solari } from "@brandazine/solari-sdk";
const solari = new Solari({ token: process.env.SOLARI_TOKEN });
const hits = await solari.tools.catalog.instagram.account.search({ query: "nike", limit: 3 });Python 3.9+ · 표준 라이브러리만
pip install solari-sdkfrom solari_sdk import Solari
solari = Solari() # reads SOLARI_TOKEN
hits = solari.tools.catalog.instagram.account.search(query="nike", limit=3)호출 여섯 개. 두 언어 모두 같은 모양.
메서드 하나가 위 엔드포인트 하나에 대응해요. 결과는 도구의 JSON 그대로이고, 클라이언트에서 캐시하지 않아요.
- TS
new Solari({ token?, baseUrl?, fetch?, timeoutMs?, userAgent? })PYSolari(token=None, base_url=…, timeout=150, user_agent=None, transport=None) - 클라이언트 생성. token 이 없으면 SOLARI_TOKEN 을 읽고, baseUrl 기본값은 solari.sh. fetch 나 transport 를 주입하면 네트워크 없이 테스트할 수 있어요.
- TS
await solari.listTools()PYsolari.list_tools() - GET /tools — 이 계정이 부를 수 있는 모든 도구와 JSON 입력 스키마.
- TS
await solari.getTool(name)PYsolari.get_tool(name) - GET /tools/{name} — 도구 하나의 스키마와 설명.
- TS
await solari.call<T>(name, args)PYsolari.call(name, arguments=None, **kwargs) - POST /tools/{name} — 전체 이름으로 도구 실행. TypeScript 는 결과 타입을 지정할 수 있어요.
- TS
await solari.tools.catalog.instagram.account.search(args)PYsolari.tools.catalog.instagram.account.search(**kwargs) - 같은 호출을 점 경로로. 도구 레지스트리에서 생성되므로 경로·인자 이름·enum 값이 TypeScript 와 Python(pyright/mypy) 타입 검사에 걸립니다.
- TS
await solari.me()PYsolari.me() - GET /me — 토큰 뒤의 계정.
에러 타입 하나에 봉투가 그대로.
2xx 가 아니면 SolariError 가 API 의 status·code·message·tool 을 담고 올라와요. 429·502·503·504 는 retryable 이 true 이고, 서버가 보낸 Retry-After 초도 실려요. 네트워크 실패는 같은 타입에 status 0.
import { Solari, SolariError } from "@brandazine/solari-sdk";
try {
await solari.call("solari_insight_instagram_brand_overview", { username: "nike" });
} catch (error) {
if (error instanceof SolariError && error.retryable) {
// error.status, error.code, error.tool, error.retryAfterSeconds
}
}from solari_sdk import Solari, SolariError
try:
solari.call("solari_insight_instagram_brand_overview", username="nike")
except SolariError as error:
if error.retryable:
... # error.status, error.code, error.tool, error.retry_after_seconds오류
실패는 전부 JSON 봉투로.
2xx 가 아니면 error.code, error.message, 그리고 도구가 얽혔으면 error.tool 이 실려요. 레이트리밋과 앱 기동 중에는 Retry-After 헤더가 붙어요.
{
"error": {
"code": "invalid_arguments",
"message": "limit: expected number, received string",
"tool": "solari_catalog_instagram_account_search"
}
}- 400invalid_arguments
- 본문이 도구 입력 스키마와 맞지 않아요. 메시지에 문제 필드가 적혀 있어요.
- 400invalid_json
- 본문이 JSON 객체가 아니에요.
- 400tool_error
- 도구가 호출을 거절했어요. 예: 계정 참조가 빠짐.
- 401unauthorized
- 토큰이 없거나 만료·폐기됐어요. 새로 발급하세요.
- 403forbidden
- 이 SOLARI 계정으로는 쓸 수 없는 도구예요.
- 404tool_not_found
- 이 계정에 그런 이름의 도구가 없어요. 목록을 먼저 확인하세요.
- 429rate_limited
- 호출이 너무 잦아요. Retry-After 초만큼 기다리세요.
- 502upstream_error
- SOLARI 가 호출을 끝내지 못했어요. 잠시 후 다시 시도하세요.
- 503app_warming_up
- Studio 앱이 켜지는 중이에요. Retry-After 초 뒤에 다시 시도하세요.
- 504upstream_timeout
- 호출이 제한 시간을 넘겼어요. 범위를 줄이거나 다시 시도하세요.
그리고