AI 에이전트를 위해
에이전트를 한 단계로 연결하세요. 소셜 채널 운영은 에이전트가 맡습니다.
Markaestro는 소프트웨어가 운영하도록 만들어졌습니다. Claude Code 같은 MCP 클라이언트는 브라우저로 로그인해 하나의 브랜드에 묶인 키를 받고, 다른 에이전트는 설정에서 같은 키를 받습니다. 어느 쪽이든 에이전트는 게시할 수 있는 계정을 찾고, 미디어를 업로드하고, 게시물을 작성·예약하고, 게시한 뒤 실제로 나간 내용을 보고할 수 있습니다. 대상은 Facebook, Instagram, TikTok, LinkedIn, Threads, Pinterest입니다.
설치할 SDK도, 관리할 플랫폼 자격 증명도 없습니다. 팀이 대시보드에서 계정을 한 번 연결하면, 그 뒤로 에이전트는 하나의 Bearer 토큰 API하고만 통신합니다.
자율성을 위해 설계되었지만, 목적에 맞게 제한됩니다
왜 API 키 하나가 연동의 전부인가
에이전트에게 소셜 미디어를 다루게 하는 데 있어 어려운 부분은 HTTP 자체가 아닙니다. 혼란에 빠진 모델이 잘못된 브랜드에 게시하거나, 재시도로 인해 중복 게시하거나, 아무도 검토하지 않은 콘텐츠를 내보내지 않도록 보장하는 것입니다. 이러한 보장은 여러분의 프롬프트가 아니라 API 인터페이스 자체에 내장되어 있습니다.
MCP 클라이언트
클라이언트에서 로그인하세요. 붙여넣을 것이 없습니다.
Claude Code, Claude, Cursor, ChatGPT, Grok, Grok Bot, OpenClaw, Hermes를 비롯해 Model Context Protocol을 사용하는 모든 클라이언트는 자격 증명 설정 없이 Markaestro의 호스팅 MCP 서버에 연결할 수 있습니다. 첫 도구 호출에서 브라우저가 열립니다. 로그인하고, 에이전트가 작업할 워크스페이스와 브랜드를 고르고, 권한을 확인한 뒤 허용을 누르세요. 클라이언트는 그 브랜드에 묶인 키를 받고 스스로 갱신합니다.
이는 PKCE와 동적 클라이언트 등록을 갖춘 표준 OAuth 2.1로, 다른 호스팅 MCP 서버와 같은 방식이므로 Markaestro 전용 플러그인 없이도 동작합니다. 서버는 https://markaestro.com/api/public/v1/mcp에 있으며 공개 API 위에서 31개 도구를 제공합니다. 브랜드와 대상 검색, 미디어 업로드, 초안과 예약 게시물, 작업 실행 폴링이 있는 게시, 일괄 작업, 웹훅, 채널별 규칙입니다.
에이전트 연결
에이전트를 선택하세요. 세 단계면 게시할 수 있습니다.
아래의 모든 클라이언트는 같은 호스팅 MCP 서버에 연결됩니다. 대부분은 브라우저로 로그인합니다. 첫 도구 호출에서 동의 페이지가 열리고, 에이전트가 작업할 워크스페이스와 브랜드를 선택하면 클라이언트는 그 브랜드에 묶인 키를 받습니다. 브라우저를 열 수 없는 클라이언트는 워크스페이스 API 키를 대신 사용합니다. 같은 서버, 같은 권한, 설정의 같은 목록입니다.
Claude Code
플러그인이 스킬과 호스팅 서버를 함께 설치합니다. 설정할 것도, 붙여 넣을 것도 없습니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- Claude Code가 설치되어 있고 Anthropic 계정에 로그인되어 있어야 합니다.
로그인
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- 터미널에서 플러그인 명령 두 개를 실행하거나, 세 번째 명령으로 서버만 추가합니다.
# The plugin bundles the skill and the hosted server.
claude plugin marketplace add D3vBaba/Markaestro
claude plugin install markaestro@markaestro
# Or add just the server. No key, no header: the first call opens the browser.
claude mcp add --transport http markaestro https://markaestro.com/api/public/v1/mcpClaude
claude.ai와 Claude Desktop은 서버 URL을 사용자 지정 커넥터로 받아 같은 동의 페이지로 로그인합니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- 사용자 지정 커넥터는 Claude 유료 요금제에서 사용할 수 있습니다. Team과 Enterprise에서는 소유자가 활성화해야 할 수 있습니다.
로그인
- Markaestro 옆의 연결을 클릭합니다. 동의 페이지가 새 탭에서 열립니다.
- 워크스페이스와 브랜드를 선택하고 권한을 확인한 뒤 허용을 클릭합니다. 탭이 닫히고 커넥터가 연결됨으로 표시됩니다.
- 채팅에서 에이전트가 사용하게 하려면 도구 메뉴에서 Markaestro를 켭니다.
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- 설정, 커넥터, 사용자 지정 커넥터 추가를 엽니다.
- 아래 서버 URL을 붙여 넣고 OAuth 클라이언트 필드는 비워 둔 채 추가를 클릭합니다.
https://markaestro.com/api/public/v1/mcpCursor
한 번의 클릭으로 Cursor에 서버가 추가됩니다. 첫 도구 호출에서 브라우저 로그인이 열리고, Cursor는 토큰을 OS 키체인에 보관합니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- MCP가 활성화된 Cursor. 원격 MCP 서버는 모든 Cursor 요금제에서 동작합니다.
로그인
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- Cursor에 추가를 클릭하고 Cursor의 설치 확인을 승인합니다.
- 또는 JSON을 프로젝트의 .cursor/mcp.json(git으로 팀과 공유)이나 ~/.cursor/mcp.json(본인만)에 붙여 넣습니다.
// .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)
{
"mcpServers": {
"markaestro": {
"url": "https://markaestro.com/api/public/v1/mcp"
}
}
}공유 빌드 머신이나 CI에서는 헤더에 넣은 워크스페이스 API 키가 로그인을 대신합니다.
// Without a browser: pass a workspace API key instead.
{
"mcpServers": {
"markaestro": {
"url": "https://markaestro.com/api/public/v1/mcp",
"headers": { "Authorization": "Bearer mk_live_..." }
}
}
}ChatGPT
ChatGPT는 개발자 모드의 사용자 지정 앱으로 Markaestro에 연결하고 동의 페이지로 로그인합니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- 개발자 모드에는 ChatGPT Pro, Business, Enterprise 또는 Edu가 필요합니다. Pro는 읽기 도구만, Business, Enterprise, Edu는 모든 도구를 제공합니다.
- Business, Enterprise, Edu에서는 관리자가 워크스페이스에 사용자 지정 앱을 허용해야 할 수 있습니다.
로그인
- ChatGPT가 도구를 스캔하는 동안 동의 페이지가 열립니다. 워크스페이스와 브랜드를 선택하고 허용을 클릭한 뒤 만들기를 클릭합니다.
- 채팅에서 더하기 버튼, 더 보기, Markaestro를 차례로 클릭하면 도구를 사용할 수 있습니다.
- ChatGPT는 연결마다 한 번 Markaestro에 자신을 등록합니다. 다시 연결하면 따로 해지할 수 있는 새 연결이 만들어집니다.
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- 설정, 앱 및 커넥터, 고급 설정을 열고 개발자 모드를 켭니다.
- 앱 및 커넥터로 돌아가 만들기를 클릭합니다. 이름을 Markaestro로 하고 서버 URL을 붙여 넣은 뒤 인증으로 OAuth를 선택하고 도구 스캔을 클릭합니다.
https://markaestro.com/api/public/v1/mcpGrok
Grok은 세 가지 방법으로 Markaestro에 연결합니다. grok.com의 사용자 지정 커넥터, Grok Build 터미널, xAI API의 원격 MCP 도구입니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- grok.com 커넥터는 개인 요금제에서 동작합니다. Grok Business와 Enterprise는 팀 관리자가 커넥터를 프로비저닝해야 합니다.
- xAI API 경로는 서버 측에서 실행되므로 항상 워크스페이스 API 키를 사용합니다.
로그인
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- grok.com: grok.com/connectors를 열고 New Connector, Custom을 선택한 뒤 서버 URL을 붙여 넣습니다. 대화 상자가 클라이언트 ID를 요구하면 아래 값을 사용합니다.
- Grok Build: 터미널에서 두 명령을 실행합니다. Grok Build는 Claude Code의 .mcp.json이나 Cursor의 mcp.json에 있는 Markaestro 항목도 가져옵니다.
- xAI API: Responses API 요청의 tools 배열에 도구 블록을 추가합니다.
grok.com 사용자 지정 커넥터
Server URL: https://markaestro.com/api/public/v1/mcp
grok.com's Custom Connector asks only for a name and this URL. It registers
itself and opens the browser sign-in, no client id or secret to enter.
(If a future dialog does ask, use client id markaestro-grok-web with a blank secret.)Grok Build 터미널
# Grok Build (terminal). The first tool call opens the browser.
grok mcp add --transport http markaestro https://markaestro.com/api/public/v1/mcp
grok mcp doctor markaestro
# Headless: pass a workspace API key instead.
grok mcp add --transport http markaestro https://markaestro.com/api/public/v1/mcp \
--header "Authorization: Bearer ${MARKAESTRO_API_KEY}"xAI Responses API 도구 블록
// xAI Responses API: one entry in the request's "tools" array.
// Server-side, so it always uses a workspace API key.
{
"type": "mcp",
"server_url": "https://markaestro.com/api/public/v1/mcp",
"server_label": "markaestro",
"authorization": "Bearer mk_live_...",
"allowed_tools": ["list_products", "list_destinations", "upload_media",
"create_post", "publish_post", "get_job_run"]
}Grok Bot
Grok Bot은 클라우드 컴퓨터에서 실행되며 고정 키로 사용자 지정 MCP 서버를 받습니다. 베타에는 아직 사용자 지정 서버용 브라우저 로그인이 없습니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- Grok Bot은 SuperGrok 요금제와 Cursor Pro에서 초기 베타로 제공됩니다. Enterprise는 대기 목록으로 운영됩니다.
- 에이전트 범위를 가진 워크스페이스 API 키가 있어야 합니다. 아래 버튼으로 만들 수 있습니다.
API 키 사용
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- Bot의 커넥터 설정을 열고 사용자 지정 MCP 서버를 추가합니다.
- 서버 URL을 붙여 넣고 아래 값으로 키를 헤더로 추가합니다.
커넥터 대화 상자용 헤더 값
Server URL: https://markaestro.com/api/public/v1/mcp
Header name: Authorization (or x-api-key if that is the only field)
Header value: Bearer mk_live_... (with x-api-key: just mk_live_...)OpenClaw
OpenClaw는 CLI에서 원격 MCP 서버를 추가하고 루프백 포트로 로그인을 마치므로 게이트웨이를 실행하는 머신에서 동작합니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- OpenClaw가 설치되어 있고 게이트웨이가 실행 중이어야 합니다.
- 브라우저가 없는 서버는 --code 대체 방식으로 로그인을 마칠 수 있습니다.
로그인
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- 세 명령을 실행하거나 ~/.openclaw/openclaw.json에 서버 블록을 추가합니다.
- Markaestro 스킬이 ClawHub에 올라오면 openclaw skills install markaestro로 에이전트 지침도 추가할 수 있습니다.
openclaw mcp add markaestro \
--url https://markaestro.com/api/public/v1/mcp \
--transport streamable-http \
--auth oauth
openclaw mcp login markaestro # prints the sign-in URL; add --code <code> when headless
openclaw mcp reload동일한 설정 항목
// ~/.openclaw/openclaw.json
{
"mcp": {
"servers": {
"markaestro": {
"url": "https://markaestro.com/api/public/v1/mcp",
"transport": "streamable-http",
"auth": "oauth"
}
}
}
}브라우저 없이
# Without a browser: a workspace API key from the environment.
openclaw mcp add markaestro \
--url https://markaestro.com/api/public/v1/mcp \
--transport streamable-http \
--header "Authorization: Bearer ${MARKAESTRO_API_KEY}"Hermes
Hermes Agent는 config.yaml에서 HTTP MCP 서버를 등록하고 스스로 로그인해 토큰을 ~/.hermes/mcp-tokens에 저장합니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- Hermes Agent가 설치되어 있어야 합니다. 비밀 값은 ~/.hermes/.env에 두고 설정에서 ${VAR}로 참조합니다.
로그인
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- ~/.hermes/config.yaml에 mcp_servers 블록을 추가합니다.
- 실행 중인 세션에서 /reload-mcp를 보냅니다. 도구는 mcp_markaestro_<tool>로 표시됩니다.
# ~/.hermes/config.yaml
mcp_servers:
markaestro:
url: "https://markaestro.com/api/public/v1/mcp"
auth: oauth브라우저 없이
# Without a browser: a workspace API key, kept in ~/.hermes/.env
mcp_servers:
markaestro:
url: "https://markaestro.com/api/public/v1/mcp"
headers:
Authorization: "Bearer ${MARKAESTRO_API_KEY}"기타 MCP 클라이언트
Streamable HTTP와 동적 클라이언트 등록을 포함한 OAuth 2.1을 지원하는 클라이언트라면 서버 URL만으로 연결됩니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- 클라이언트가 Streamable HTTP로 원격 MCP 서버를 지원하고 OAuth를 위해 브라우저를 열 수 있어야 합니다. 열 수 없다면 API 키 탭을 사용하세요.
로그인
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- 클라이언트의 MCP 설정에 서버 URL을 추가합니다. 아래 JSON은 일반적인 mcpServers 형식입니다.
- 클라이언트 ID나 비밀 값을 설정하지 마세요. 클라이언트는 첫 사용 시 스스로 등록합니다.
{
"mcpServers": {
"markaestro": {
"type": "http",
"url": "https://markaestro.com/api/public/v1/mcp"
}
}
}API 키
CI 작업, cron 워커, 브라우저를 열 수 없는 클라이언트용입니다. Authorization 헤더의 워크스페이스 API 키로 같은 서버에 같은 권한으로 접근합니다.
시작하기 전에
- 이메일이 인증된 워크스페이스 소유자 또는 관리자이며, 워크스페이스에 활성 요금제와 브랜드가 하나 이상 있어야 합니다.
- 키를 만들 수 있어야 합니다. 이메일이 인증된 워크스페이스 소유자 또는 관리자.
API 키 사용
확인
- 에이전트에게 list_products를 호출하게 하세요. 허용한 브랜드 하나와 연결된 채널이 응답으로 와야 합니다.
- 연결은 설정, API에 연결된 에이전트 배지, 마지막 사용 시각, 요청 수와 함께 표시됩니다. 언제든 거기서 해지할 수 있습니다.
서버 추가
- 브랜드 하나에 묶이고, 에이전트에 필요한 범위만 가지며, 만료가 있는 키를 만듭니다.
- 호스팅 서버에는 bearer 헤더로, 로컬 stdio 서버에는 MARKAESTRO_API_KEY로 전달합니다. stdio 서버는 디스크의 파일도 업로드할 수 있습니다.
# CI, cron, or any client without a browser: pass a key instead.
claude mcp add --transport http markaestro https://markaestro.com/api/public/v1/mcp \
--header "Authorization: Bearer mk_live_..."
# Local stdio server (can also upload files from disk)
claude mcp add markaestro -e MARKAESTRO_API_KEY=mk_live_... -- npx -y @markaestro/mcp{
"mcpServers": {
"markaestro": {
"type": "http",
"url": "https://markaestro.com/api/public/v1/mcp",
"headers": { "Authorization": "Bearer mk_live_..." }
}
}
}클라이언트가 연결될 때 일어나는 일
다섯 단계 모두 클라이언트와 브라우저가 처리합니다. 사용자는 동의 페이지만 보게 됩니다.
POST /api/public/v1/mcp → 401 + WWW-Authenticate클라이언트가 자격 증명 없이 MCP 엔드포인트를 호출합니다. Markaestro는 보호 리소스 메타데이터 문서를 가리키는 WWW-Authenticate 헤더와 함께 401을 응답합니다. 이 헤더가 로그인이 가능하다는 것을 클라이언트에 알립니다.
GET /.well-known/oauth-protected-resource · /.well-known/oauth-authorization-server클라이언트는 두 개의 공개 문서를 읽습니다. 어떤 인가 서버가 엔드포인트를 보호하는지, 그리고 그 서버의 등록·인가·토큰 엔드포인트가 어디에 있는지입니다. 둘 다 markaestro.com에서 제공되며 캐시할 수 있습니다.
POST /api/public/v1/oauth/register클라이언트는 이름과 콜백 주소로 자신을 등록합니다. 루프백 주소, https 콜백, 네이티브 앱 스킴은 허용되고, 실제 호스트로 향하는 일반 http는 거부됩니다. 사전에 공유된 클라이언트 ID는 필요 없습니다.
GET /oauth/authorize (browser)브라우저에 동의 페이지가 열립니다. 이메일이 인증된 워크스페이스 소유자 또는 관리자가 워크스페이스와 브랜드를 고르고 권한을 조정한 뒤 허용을 누릅니다. Markaestro는 일회용 코드와 함께 브라우저를 클라이언트로 돌려보냅니다.
POST /api/public/v1/oauth/token클라이언트는 코드와 PKCE verifier를 액세스 토큰과 리프레시 토큰으로 교환합니다. 액세스 토큰은 선택한 브랜드에 묶인 일반 워크스페이스 API 키입니다. 30일 후 만료되며, 리프레시하면 시크릿이 교체되고 30일 더 연장됩니다.
토큰은 진짜 API 키입니다
스코프, 브랜드 바인딩, 속도 제한, 구독 확인, 멱등성, 취소는 수동으로 만든 키와 같은 코드 경로를 따릅니다. 따로 이해해야 할 두 번째 권한 모델은 없습니다.
설정에서 확인하고 취소할 수 있습니다
연결된 에이전트는 설정의 API에 연결된 에이전트 배지, 마지막 사용 시각, 요청량과 함께 표시됩니다. 거기서 취소하면 클라이언트의 다음 호출은 실패합니다. 연결을 끊을 때 클라이언트가 자기 토큰을 직접 취소할 수도 있습니다.
연결 하나에 브랜드 하나
모든 연결은 동의 시 선택한 정확히 하나의 브랜드에 묶입니다. 에이전트가 두 번째 브랜드에서 작업하게 하려면 다시 연결해 그 브랜드를 고르세요. 클라이언트는 허용되지 않은 브랜드에 절대 접근할 수 없습니다.
코드와 리프레시 토큰은 일회용입니다
인가 코드는 10분 동안 유효하고 원자적으로 소비되므로 재사용된 코드는 실패합니다. 리프레시 토큰은 사용할 때마다 교체되고 해시로 저장됩니다. 사용되지 않는 클라이언트 등록은 180일 후 만료됩니다.
엔드포인트
MCP 클라이언트를 만들거나 흐름을 감사하는 분을 위한 내용입니다. 모든 것은 두 well-known 문서에서 발견할 수 있으며, 수동으로 설정할 것은 없습니다.
# Discovery (public, cacheable)
GET /.well-known/oauth-protected-resource RFC 9728
GET /.well-known/oauth-authorization-server RFC 8414
# Authorization server
POST /api/public/v1/oauth/register RFC 7591, public clients (PKCE) or client_secret
GET /oauth/authorize?response_type=code&client_id=…&redirect_uri=…
&code_challenge=…&code_challenge_method=S256&state=…
POST /api/public/v1/oauth/token grant_type=authorization_code | refresh_token
POST /api/public/v1/oauth/revoke RFC 7009
# Token response
{ "access_token": "mk_live_<ws>.<client>.<secret>", "token_type": "Bearer",
"expires_in": 2592000, "refresh_token": "…", "scope": "products.read posts.write …" }에이전트 루프
처음부터 끝까지, 단 5번의 호출
Markaestro의 모든 자동화는 이 루프의 변형입니다. 1단계부터 3단계까지는 Connect API입니다, 대부분의 에이전트가 대상으로 삼아야 할 평면적인 인터페이스입니다. 4단계와 5단계는 명시적 발행과 실행 추적을 위해 전체 /api/public/v1 API에 접근합니다.
GET /api/connect/v1/social-accounts해당 키의 브랜드에 연결된, 발행 가능한 모든 계정을 반환합니다. 각 계정에는 플랫폼, 사용자명, 불투명한 ID가 포함됩니다. 매 실행 시작 시 호출하세요, 연결 상태는 변할 수 있습니다.
POST /api/connect/v1/media/create-upload-url → PUT단시간 유효한 1회용 서명 URL을 발급받고, 그곳으로 원본 바이트를 PUT합니다. 미디어 ID를 돌려받습니다. 이미지는 최대 10MB이며, 전체 API에서는 최대 250MB의 동영상도 지원합니다.
POST /api/connect/v1/posts캡션, 미디어 ID, 계정 ID를 그대로 전달하세요. 검토를 위해 초안 상태로 둘 수도 있고, is_draft false와 scheduled_at을 함께 보내 캘린더에 등록할 수도 있습니다.
POST /api/public/v1/posts/:id/publish비동기 실행을 큐에 추가합니다. LinkedIn, Threads, Pinterest는 공식 API를 통해 전송됩니다. Facebook, Instagram, TikTok은 워크스페이스의 '발행 대기' 큐에 들어가 사람이 직접 게시하기를 기다립니다.
GET /api/public/v1/job-runs/:id · webhooks실행 ID를 폴링하거나, 웹훅 엔드포인트를 등록해 Markaestro가 post.published, post.action_required, post.failed를 여러분에게 푸시하도록 하세요. 발행이 동기적으로 완료되었다고 절대 가정하지 마세요.
퀵스타트
4단계 명령으로 완성하는 실제 작동 연동
먼저 키를 발급하세요: 설정 → API를 열고, 접근을 허용할 브랜드를 선택하고, 필요한 권한 범위를 체크한 다음, 선택적으로 유효기간을 설정하세요. 키는 단 한 번만 표시되므로, 바로 에이전트의 시크릿 저장소에 저장하세요. 키 생성에는 이메일이 인증된 관리자 또는 소유자 권한이 필요합니다.
# The API is served from the marketing apex and the app subdomain alike.
export MARKAESTRO_URL="https://markaestro.com"
export MARKAESTRO_API_KEY="mk_live_<workspaceId>.<clientId>.<secret>"
# 1. What can this key post to?
curl -s "$MARKAESTRO_URL/api/connect/v1/social-accounts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"{
"data": [
{
"id": "prod_123#instagram:instagram:ig_123",
"product_id": "prod_123",
"product": "Northwind Coffee",
"platform": "instagram",
"username": "northwindcoffee"
}
]
}# 2. Mint a signed upload url, then PUT the bytes.
RESP=$(curl -s -X POST "$MARKAESTRO_URL/api/connect/v1/media/create-upload-url" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "mime_type": "image/png", "size_bytes": 184320, "name": "cold-brew.png" }')
# → { "media_id": "ast_777", "upload_url": "https://.../media/upload?token=..." }
curl -X PUT "<upload_url>" \
-H "Content-Type: image/png" \
--data-binary @cold-brew.pngis_draft: false와 scheduled_at 타임스탬프를 함께 보내면 게시물을 캘린더에 등록할 수 있습니다.# 3. Put it on the calendar. Pass the account id back verbatim.
curl -X POST "$MARKAESTRO_URL/api/connect/v1/posts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"caption": "Cold brew season starts Friday.",
"media": ["ast_777"],
"social_accounts": ["prod_123#instagram:instagram:ig_123"],
"is_draft": false,
"scheduled_at": "2026-08-14T15:00:00.000Z"
}'
# 4. Check where everything stands.
curl -s "$MARKAESTRO_URL/api/connect/v1/posts?limit=20" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"바로 사용 가능
도구 정의와 에이전트 브리프
복사해서 바로 사용할 수 있는 두 가지가 있습니다. 첫 번째는 발행 루프 전체를 다루는 도구 스키마 세트입니다, JSON Schema로 작성되어 있어 Claude 도구 정의, OpenAI 함수, 또는 여러분이 직접 호스팅하는 MCP 서버의 입력 형식으로 그대로 사용할 수 있습니다. 두 번째는 모델이 예상치 못한 행동을 하지 않도록 막는 운영 브리프입니다.
[
{
"name": "markaestro_list_accounts",
"description": "List the social accounts this Markaestro key can publish to. Call this first in every run. Never hardcode account ids. Returns id, platform, and username.",
"input_schema": { "type": "object", "properties": {}, "required": [] }
},
{
"name": "markaestro_upload_media",
"description": "Upload one image or video to Markaestro and return a media asset id. Images: png, jpeg, webp, gif up to 10 MB. Video: mp4, mov, webm up to 250 MB.",
"input_schema": {
"type": "object",
"properties": {
"file_path": { "type": "string", "description": "Local path to the file to upload." },
"mime_type": { "type": "string", "description": "MIME type of the file." }
},
"required": ["file_path", "mime_type"]
}
},
{
"name": "markaestro_create_post",
"description": "Create a post for one channel. Facebook, Instagram, and TikTok are manual-first: a human posts them natively from the To Post queue. Omit delivery_mode unless the user explicitly asked for unattended publishing.",
"input_schema": {
"type": "object",
"properties": {
"channel": {
"type": "string",
"enum": ["facebook", "instagram", "tiktok", "linkedin", "threads", "pinterest", "x"]
},
"caption": { "type": "string", "description": "Caption text, max 4000 characters." },
"media_asset_ids": {
"type": "array",
"items": { "type": "string" },
"description": "Ids from markaestro_upload_media. Instagram and TikTok require at least one."
},
"destination_id": {
"type": "string",
"description": "From markaestro_list_accounts. Required only when the brand has more than one destination on that channel."
},
"delivery_mode": {
"type": "string",
"enum": ["manual_reminder", "direct_publish", "platform_inbox"],
"description": "Omit for the channel default."
}
},
"required": ["channel", "caption"]
}
},
{
"name": "markaestro_publish_post",
"description": "Queue an async publish run for an existing post. Returns a run id. Poll it, do not assume the post is live.",
"input_schema": {
"type": "object",
"properties": { "post_id": { "type": "string" } },
"required": ["post_id"]
}
},
{
"name": "markaestro_list_posts",
"description": "List posts for this brand, newest first. Filter by status: draft, scheduled, publishing, published, platform_action_required, failed, partial_failed.",
"input_schema": {
"type": "object",
"properties": {
"status": { "type": "string" },
"limit": { "type": "integer", "minimum": 1, "maximum": 100 }
},
"required": []
}
},
{
"name": "markaestro_delete_post",
"description": "Remove a post from Markaestro. Use it to cancel something scheduled. Deleting an already-published post does NOT retract the live copy on the platform.",
"input_schema": {
"type": "object",
"properties": { "post_id": { "type": "string" } },
"required": ["post_id"]
}
}
]You have a Markaestro API key for exactly one brand. Markaestro is the
publishing layer: you supply the caption and the media, it handles the
platform rules, the calendar, and delivery.
Base URL: https://markaestro.com
Auth: Authorization: Bearer $MARKAESTRO_API_KEY
Rules:
- Call GET /api/connect/v1/social-accounts before posting. Pass the returned
account ids back verbatim. Never invent or cache an id across runs.
- Upload media before creating a post; posts reference media ids, not files.
- Facebook, Instagram, and TikTok are manual-first. Creating and publishing
them queues a reminder for a human. That is the intended behavior. Only
send deliveryMode "direct_publish" if the operator explicitly asked for it.
- Send a unique Idempotency-Key on every POST. Reuse the SAME key when
retrying the SAME request; never reuse it for a different one.
- On 429, wait the number of seconds in Retry-After, then retry. On 4xx other
than 429, do not retry. Report the error code and requestId and stop.
- Publishing is async. POST /publish returns a run id; poll
GET /api/public/v1/job-runs/<id> until succeeded or failed.
- To cancel, list with ?status=scheduled and DELETE the post id. Deleting a
published post does not remove it from the platform.
- Never claim a post is live until a run reports succeeded or a post reports
published.에이전트가 직접 이 내용을 가져올 수도 있습니다: curl https://markaestro.com/llms.txt는 전체 API에 대한 순수 텍스트 브리프, 엔드포인트, 규칙, 오류 처리를 포함, 를 반환하며, 컨텍스트에 담길 만큼 충분히 작은 크기입니다.
예제 시나리오
에이전트가 실제로 실행하는 4가지 워크플로우
# Full control: draft → publish → poll. No productId needed:
# the key is already bound to one brand.
POST_ID=$(curl -s -X POST "$MARKAESTRO_URL/api/public/v1/posts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: post-2026-08-14-linkedin" \
-d '{
"channel": "linkedin",
"caption": "We shipped agent-driven publishing.",
"mediaAssetIds": ["ast_777"]
}' | jq -r .post.id)
RUN_ID=$(curl -s -X POST "$MARKAESTRO_URL/api/public/v1/posts/$POST_ID/publish" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Idempotency-Key: publish-$POST_ID" | jq -r .run.id)
# queued → running → succeeded | failed
curl -s "$MARKAESTRO_URL/api/public/v1/job-runs/$RUN_ID" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"# Review the queue, then cancel what the operator rejected.
curl -s "$MARKAESTRO_URL/api/public/v1/posts?status=scheduled&limit=100" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"
curl -X DELETE "$MARKAESTRO_URL/api/public/v1/posts/pst_123" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"
# → { "deleted": true, "id": "pst_123" }# One call, up to 25 posts. Per-item results: one bad item
# does not fail the batch.
curl -X POST "$MARKAESTRO_URL/api/public/v1/posts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: week-33-drop" \
-d '{
"posts": [
{ "channel": "instagram", "caption": "Monday", "mediaAssetIds": ["ast_1"] },
{ "channel": "facebook", "caption": "Tuesday", "mediaAssetIds": ["ast_2"] },
{ "channel": "linkedin", "caption": "Thursday" }
]
}'
# → { "results": [...], "created": 3, "total": 3 }# Let Markaestro call you instead of polling.
curl -X POST "$MARKAESTRO_URL/api/public/v1/webhook-endpoints" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-agent.example.com/hooks/markaestro",
"events": ["post.published", "post.action_required", "post.failed"]
}'
# Each delivery carries:
# X-Markaestro-Event post.action_required
# X-Markaestro-Timestamp 2026-08-14T15:00:04.000Z
# X-Markaestro-Signature HMAC of the body with your webhook secret
# The secret is shown once at creation and stored hashed. Verify before acting.안전장치
에이전트가 할 수 있는 것과 할 수 없는 것
자율성은 영향 범위가 작을 때만 유용합니다. Markaestro의 기본 설정은 호출자가 잘못될 수 있는 소프트웨어라는 전제를 따릅니다.
Facebook, Instagram, TikTok은 수동 우선 방식
여러분의 에이전트가 이러한 채널을 위해 생성한 게시물은 기본적으로 manual_reminder 방식을 사용합니다: Markaestro는 이 채널들에 대해 플랫폼 API를 절대 호출하지 않습니다. 발행 처리는 게시물을 워크스페이스의 '발행 대기' 큐로 이동시키고, 그곳에서 사람이 미디어를 다운로드해 직접 게시하고 확인합니다, 그 결과 게시물은 마치 수동으로 작성된 것처럼 보이며, 공개적으로 존재하기 전에 반드시 사람이 검토합니다. 에이전트는 deliveryMode: "direct_publish"로 개별 게시물을 공식 API 발행으로 전환할 수 있으며, TikTok의 경우 이는 크리에이터 받은함 전달을 의미할 뿐, 감독 없는 공개 게시가 되는 일은 절대 없습니다. LinkedIn, Threads, Pinterest는 여러분의 에이전트가 명시적으로 요청하면 프로그래매틱 방식으로 발행됩니다.
키의 권한 범위를 좁히세요
에이전트에게 필요한 권한만 선택하세요: products.read, media.write, posts.read, posts.write, posts.publish, job_runs.read, webhooks.manage. 캘린더만 조회하는 리서치 에이전트에게는 posts.read만 부여하면 충분합니다.
유효기간을 설정하세요
키는 유효기간을 설정해 생성할 수 있습니다. 만료된 키는 폐기된 키와 완전히 동일하게 동작하므로, 에이전트 환경에서 유출된 키는 저절로 작동을 멈춥니다.
회전 및 폐기하세요
설정 → API에서 키를 그 자리에서 회전하거나 완전히 폐기할 수 있습니다. 모든 키는 마지막 사용 시각과 요청량을 보여주므로, 조용해진 에이전트나 통제를 벗어난 에이전트를 쉽게 파악할 수 있습니다.
속도 제한이 적용됩니다
엔드포인트당 분당 60회, 키당 분당 240회입니다. 모든 응답에는 X-RateLimit-Limit, -Remaining, -Reset이 포함되며, 429 응답에는 Retry-After가 포함됩니다. 무리하게 요청을 반복하지 말고 이를 따르세요.
Markaestro는 여러분을 대신해 글을 작성하지 않습니다
생성 단계는 존재하지 않습니다. 캡션은 여러분의 에이전트에서, 미디어는 여러분의 라이브러리나 에이전트의 처리 과정에서 나옵니다. Markaestro는 목소리가 아니라 손입니다.
삭제는 Markaestro 측에서만 이루어집니다
예약된 게시물을 삭제하면 발행 전에 취소됩니다. 발행된 게시물을 삭제하면 Markaestro의 추적만 중단될 뿐입니다, 실제 게시물은 누군가 플랫폼에서 직접 제거할 때까지 그대로 유지됩니다.
오류 처리
재시도할 가치가 있는 오류를 가르치세요
모든 오류 응답은 안정적인 error 코드와 requestId를 포함한 JSON입니다. 에이전트가 실패를 보고할 때 requestId를 함께 인용하도록 하세요, 지원팀이 해당 호출을 추적하는 데 필요한 정보입니다.
| 상태 코드 | 오류 코드 | 에이전트가 취해야 할 조치 |
|---|---|---|
| 401 | UNAUTHENTICATED | 키가 없거나, 폐기되었거나, 만료되었습니다. 중단하고 사람에게 새 키를 요청하세요, 재시도해도 소용없습니다. |
| 403 | FORBIDDEN | 이 호출에 필요한 권한이 키에 없습니다. 어떤 호출이 실패했는지 보고하세요. 권한은 설정 → API에서 변경할 수 있습니다. |
| 403 | API_KEY_NOT_BOUND_TO_PRODUCT | 브랜드 바인딩 이전에 발급된 키입니다. 대체 키를 요청하세요. |
| 400 | VALIDATION_* | 요청 페이로드가 채널 규칙을 위반했습니다(미디어 누락, 잘못된 전달 방식, 잘못된 scheduled_at 등). 요청을 수정하세요. 변경 없이 재시도하지 마세요. |
| 400 | VALIDATION_IDEMPOTENCY_KEY_REUSED | 동일한 Idempotency-Key가 다른 요청 본문과 함께 전송되었습니다. 서로 다른 요청마다 새 키를 발급하세요. |
| 400 | VALIDATION_POST_IS_PUBLISHING | 발행 실행이 진행 중인 상태에서 게시물을 삭제하려 했습니다. 실행이 완료될 때까지 기다린 후 삭제하세요. |
| 409 | VALIDATION_POST_ALREADY_PUBLISHING | 이 게시물에 대한 발행 실행이 이미 큐에 있습니다. 다시 발행하지 말고, 기존 실행 상태를 폴링하세요. |
| 402 | SUBSCRIPTION_REQUIRED | 이 워크스페이스에 활성 요금제가 연결되어 있지 않습니다. 워크스페이스 소유자에게 설정에서 결제를 확인하도록 요청하세요. |
| 402 | QUOTA_EXCEEDED_MEDIA_UPLOADS | 워크스페이스가 월간 업로드 할당량에 도달했습니다. 업로드를 중단하고 이를 알리세요, 기존 미디어는 계속 발행됩니다. |
| 404 | NOT_FOUND | 해당 ID는 이 키의 브랜드 범위 밖에 있습니다. 키가 소유하지 않은 ID를 탐색할 수 없도록 403 대신 404로 응답됩니다. |
| 429 | RATE_LIMITED | Retry-After에 명시된 초만큼 대기한 후, 동일한 Idempotency-Key로 같은 요청을 재시도하세요. |
원하는 기술 스택을 사용하세요
HTTPS 요청을 보낼 수 있다면, 발행할 수 있습니다
도입해야 할 Markaestro 전용 클라이언트 라이브러리도, 표준화해야 할 프레임워크도 없습니다. 베어러 토큰, JSON 입력, JSON 출력이 전부입니다.
Claude 및 Claude Agent SDK
위의 도구 정의를 도구 목록에 그대로 추가하세요. JSON Schema 형식은 이미 Claude의 도구 사용 형식과 일치합니다.
OpenAI의 function calling
동일한 스키마가 함수 정의로 그대로 매핑됩니다, input_schema를 parameters로 이름만 바꾸면 됩니다.
MCP 클라이언트
Claude Code, Claude, Cursor, ChatGPT, Grok, Grok Bot, OpenClaw, Hermes: 호스팅 서버 URL을 추가하고 브라우저로 로그인하세요. stdio 전용 클라이언트에서는 npx -y @markaestro/mcp가 같은 31개 도구를 로컬에서 실행합니다.
n8n, Make, Zapier
모든 엔드포인트는 베어러 토큰을 포함한 평범한 HTTP 요청입니다. SDK도, 서명 절차도, 에이전트를 위한 OAuth 과정도 필요 없습니다.
LangChain 및 LlamaIndex
표준 REST 도구입니다. 2단계 미디어 업로드가 유일하게 여러 번 호출이 필요한 흐름이며, 단 두 줄이면 됩니다.
cron 작업과 curl
모든 에이전트에 프레임워크가 필요한 것은 아닙니다. 위의 퀵스타트는 4단계 명령만으로 완성되는, 실제로 작동하는 완전한 연동입니다.