MCP와 TypeScript SDK
MCP와 SDK는 공개 REST API를 사용해요. Station 범위, OAuth 스코프, 요금, 요청 한도와 감사 기록도 REST와 같아요. 현재 개발 환경의 주소는 https://dev.api.endueos.com이에요.
MCP 연결
섹션 제목: “MCP 연결”Streamable HTTP 엔드포인트는 **https://dev.api.endueos.com/api/v1**예요. REST API는 그 아래 경로를 사용해요. HTTP MCP를 지원하는 클라이언트에 다음 값을 넣으세요. 클라이언트마다 설정 파일 형식은 다를 수 있어요.
{ "url": "https://dev.api.endueos.com/api/v1", "headers": { "Authorization": "Bearer <Station의 osk_ 키>" }}initialize 후 tools/list를 호출하면 공개 JSON REST 작업이 도구로 나와요. 목록은 50개씩 반환하므로 nextCursor가 있으면 이어서 읽으세요. 도구 이름은 OpenAPI의 operationId예요. 예를 들어:
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "installWorkspaceApp", "arguments": { "workspace_id": "wsp_…", "body": { "slug": "libreoffice" }, "idempotency_key": "install-office-1" } }}응답의 structuredContent에는 status, body, request_id, location, retry_after가 있어요. REST 오류는 isError: true로 유지돼요. 202는 접수 상태예요. getCommand와 getCommandOutput으로 결과를 확인하세요. 바이너리 파일·화면·이벤트 스트림은 REST를 직접 사용해요. 외부 URL이나 인증 주체 헤더를 도구 인자로 지정할 수 없어요.
OAuth 2.1
섹션 제목: “OAuth 2.1”Station 키 대신 OS OAuth 액세스 토큰도 사용할 수 있어요. 클라이언트를 OS에 등록하고 Authorization Code + PKCE(S256)로 동의받으세요. 자동 동적 등록은 제공하지 않아요. 토큰 발급·갱신과 보관은 MCP 클라이언트가 담당해요.
- 보호 리소스 메타데이터:
/.well-known/oauth-protected-resource/api/v1 - 인증 서버 메타데이터:
/.well-known/oauth-authorization-server resource:https://dev.api.endueos.com/api/v1- Workspace 조회:
workspaces:read, 설치·실행·세션 변경:workspaces:write - 명령 조회:
devices:read, 일반 명령 취소:devices:control
인증이 없으면 401의 WWW-Authenticate에 메타데이터 주소가 나와요. 다른 resource로 발급을 요청하면 invalid_target이에요. 토큰의 Station과 스코프는 도구 호출마다 다시 확인해요. 브라우저의 Origin도 허용된 출처여야 해요. 서버 클라이언트는 Origin을 보낼 필요가 없어요.
TypeScript SDK
섹션 제목: “TypeScript SDK”개발 빌드를 설치하세요. 이 파일은 develop의 SDK 소스로 빌드하며, 운영 npm 릴리스와 별개예요.
npm install https://dev.endueos.com/downloads/endue-os-sdk-0.3.0-dev.1210.tgzimport { EndueOsClient, EndueOsError } from '@endue-os/sdk';
const os = new EndueOsClient({ baseUrl: 'https://dev.api.endueos.com', token: () => process.env.ENDUE_OS_TOKEN!,});const catalog = await os.call('listWorkspaceAppCatalog', { station_id: process.env.ENDUE_STATION_ID!,});console.log(catalog.body.data.apps);
const installed = await os.call('installWorkspaceApp', { workspace_id: process.env.ENDUE_WORKSPACE_ID!, body: { slug: 'libreoffice' }, idempotency_key: 'install-office-1',});if (installed.status === 202) { const terminal = await os.waitForCommand(installed.body.data.command_id, { timeoutMs: 120_000, }); console.log(terminal.data.status);}call의 작업 이름·인자·응답은 OpenAPI에서 생성한 타입으로 검사돼요. body는 REST 봉투 그대로예요. 토큰 공급 함수는 요청마다 호출되므로 갱신된 OAuth 토큰을 반환할 수 있어요. SDK가 토큰을 저장하거나 쓰기 요청을 자동 재시도하지 않아요.
call과 waitForCommand에 signal을 전달해 클라이언트 대기를 취소할 수 있어요. 대기 취소가 서버 작업까지 취소하지는 않아요. 실제 작업 중단은 cancelCommand 또는 cancelLocalAgentRun을 호출하세요. EndueOsError는 status, code, requestId, retryAfter, details를 제공해요. 요청 ID는 장애 확인에 사용하고, 토큰과 Secret 값은 로그에 남기지 마세요.