xurl — X (Twitter) API 공식 CLI
xurl은 X 개발자 플랫폼의 X API 공식 CLI입니다. 일반적인 작업을 위한 단축 명령어와 모든 v2 엔드포인트에 대한 원시 curl 스타일 액세스를 모두 지원합니다. 모든 명령어는 JSON을 stdout으로 반환합니다.
이 스킬을 사용하여 다음 작업을 수행할 수 있습니다:
- 게시글 작성, 답글, 인용, 삭제
- 원시 게시글 검색 (실제 게시글 JSON, ID로 상호작용 가능) 및 타임라인/멘션 읽기
- 좋아요, 리포스트, 북마크
- 팔로우, 언팔로우, 차단, 뮤트
- 다이렉트 메시지
- 미디어 업로드 (이미지 및 비디오)
- 모든 X API v2 엔드포인트에 대한 원시 액세스
- 멀티 앱 / 멀티 계정 워크플로우
이 스킬은 이전의 xitter 스킬(타사 Python CLI를 래핑)을 대체합니다. xurl은 X 개발자 플랫폼 팀이 유지 관리하며, OAuth 2.0 PKCE 자동 갱신을 지원하고 훨씬 더 넓은 API 표면을 제공합니다.
비밀 보안 (필수)
에이전트/LLM 세션 내에서 작업 시 중요한 규칙:
- 절대로
~/.xurl을 읽거나, 출력하거나, 구문 분석하거나, 요약하거나, 업로드하거나, LLM 컨텍스트로 보내지 마십시오. - 절대로 사용자에게 채팅에 자격 증명/토큰을 붙여넣도록 요청하지 마십시오.
- 사용자는 자신의 기기에서 수동으로
~/.xurl에 비밀 정보를 입력해야 합니다. Docker에서는 Hermes 툴 서브프로세스가 보는~여야 합니다. 아래 Docker 참고 사항을 확인하세요. - 절대로 에이전트 세션에서 인라인 시크릿이 있는 인증 명령을 실행하거나 권장하지 마십시오.
- 절대로 에이전트 세션에서
--verbose/-v를 사용하지 마십시오. 인증 헤더/토큰이 노출될 수 있습니다. - 자격 증명이 있는지 확인하려면
xurl auth status명령어만 사용하십시오.
에이전트 명령어에서 금지된 플래그 (인라인 시크릿을 허용함):
--bearer-token, --consumer-key, --consumer-secret, --access-token, --token-secret, --client-id, --client-secret
앱 자격 증명 등록 및 자격 증명 순환은 사용자가 에이전트 세션 외부에서 수동으로 수행해야 합니다. 자격 증명이 등록된 후, 사용자는 xurl auth oauth2로 인증합니다(이 역시 에이전트 세션 외부에서). 토큰은 YAML 형식으로 ~/.xurl에 유지됩니다. 각 앱은 격리된 토큰을 가집니다. OAuth 2.0 토큰은 자동으로 갱신됩니다.
설치
한 가지 방법을 선택하세요. Linux에서는 셸 스크립트나 go install이 가장 쉽습니다.
# 셸 스크립트 (~/.local/bin에 설치, sudo 불필요, Linux + macOS에서 작동)
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash
# Homebrew (macOS)
brew install --cask xdevplatform/tap/xurl
# npm
npm install -g @xdevplatform/xurl
# Go
go install github.com/xdevplatform/xurl@latest
설치 확인:
xurl --help
xurl auth status
xurl이 설치되었지만 auth status에 앱이나 토큰이 표시되지 않으면 사용자가 수동으로 인증을 완료해야 합니다. 다음 섹션을 참조하세요.
일회성 사용자 설정 (사용자가 에이전트 외부에서 실행)
이 단계는 사용자가 직접 수행해야 하며, 에이전트가 대신 수행해서는 안 됩니다. 비밀 정보를 붙여넣는 과정이 포함되기 때문입니다. 사용자에게 이 블록을 안내하고 직접 실행하지 마십시오.
-
https://developer.x.com/en/portal/dashboard 에서 앱을 만들거나 엽니다.
-
리다이렉트 URI를
http://localhost:8080/callback으로 설정합니다. -
앱의 Client ID와 Client Secret을 복사합니다.
-
로컬에 앱을 등록합니다 (사용자가 실행):
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET -
인증합니다 (토큰을 앱에 바인딩하려면
--app지정):xurl auth oauth2 --app my-app(OAuth 2.0 PKCE 플로우를 위해 브라우저가 열립니다.)
X가 OAuth 후
/2/users/me조회에서UsernameNotFound오류 또는 403을 반환하면, 핸들을 명시적으로 전달하세요 (xurl v1.1.0+):xurl auth oauth2 --app my-app YOUR_USERNAME이렇게 하면 토큰이 핸들에 바인딩되고 깨진
/2/users/me호출을 건너뜁니다. -
앱을 기본값으로 설정하여 모든 명령어가 해당 앱을 사용하도록 합니다:
xurl auth default my-app -
확인:
xurl auth status xurl whoami
이후 에이전트는 추가 설정 없이 아래 명령어를 사용할 수 있습니다. OAuth 2.0 토큰은 자동으로 갱신됩니다.
자주 하는 실수:
xurl auth oauth2에서--app my-app을 생략하면 OAuth 토큰이 내장된default앱 프로필에 저장됩니다. 이 프로필에는 client-id 또는 client-secret이 없습니다. OAuth 흐름이 성공한 것처럼 보여도 명령어가 인증 오류로 실패합니다. 이 문제가 발생하면xurl auth oauth2 --app my-app과xurl auth default my-app을 다시 실행하세요.
Docker HOME 문제: 공식 Hermes Docker 레이아웃에서
/opt/data는HERMES_HOME이지만, Hermes 툴 서브프로세스는HOME으로/opt/data/home을 사용합니다. 즉, Hermes가 실행하는xurl명령어의 경우~/.xurl은/opt/data/.xurl이 아닌/opt/data/home/.xurl로 확인됩니다. 동일한 HOME으로 사용자 설정을 실행하세요:HOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME HOME=/opt/data/home xurl auth status
HOME=/opt/data xurl auth status는 성공하지만HOME=/opt/data/home xurl auth status에 앱이나 토큰이 표시되지 않으면 Hermes 툴 호출에서 자격 증명을 볼 수 없습니다.
빠른 참조
| 동작 | 명령어 |
|---|---|
| 게시 | xurl post "Hello world!" |
| 답글 | xurl reply POST_ID "Nice post!" |
| 인용 | xurl quote POST_ID "My take" |
| 게시글 삭제 | xurl delete POST_ID |
| 게시글 읽기 | xurl read POST_ID |
| 게시글 검색 | xurl search "QUERY" -n 10 |
| 내 정보 | xurl whoami |
| 사용자 조회 | xurl user @handle |
| 홈 타임라인 | xurl timeline -n 20 |
| 멘션 | xurl mentions -n 10 |
| 좋아요 / 좋아요 취소 | xurl like POST_ID / xurl unlike POST_ID |
| 리포스트 / 실행 취소 | xurl repost POST_ID / xurl unrepost POST_ID |
| 북마크 / 제거 | xurl bookmark POST_ID / xurl unbookmark POST_ID |
| 북마크 목록 / 좋아요 목록 | xurl bookmarks -n 10 / xurl likes -n 10 |
| 팔로우 / 언팔로우 | xurl follow @handle / xurl unfollow @handle |
| 팔로잉 / 팔로워 | xurl following -n 20 / xurl followers -n 20 |
| 차단 / 차단 해제 | xurl block @handle / xurl unblock @handle |
| 뮤트 / 뮤트 해제 | xurl mute @handle / xurl unmute @handle |
| DM 보내기 | xurl dm @handle "message" |
| DM 목록 | xurl dms -n 10 |
| 미디어 업로드 | xurl media upload path/to/file.mp4 |
| 미디어 상태 | xurl media status MEDIA_ID |
| 앱 목록 | xurl auth apps list |
| 앱 제거 | xurl auth apps remove NAME |
| 기본 앱 설정 | xurl auth default APP_NAME [USERNAME] |
| 요청별 앱 지정 | xurl --app NAME /2/users/me |
| 인증 상태 | xurl auth status |
참고:
POST_ID는 전체 URL도 허용합니다 (예:https://x.com/user/status/1234567890) — xurl이 ID를 추출합니다.- 사용자 이름은 앞에
@가 있거나 없이 작동합니다.
명령어 세부 사항
게시
xurl post "Hello world!"
xurl post "Check this out" --media-id MEDIA_ID
xurl post "Thread pics" --media-id 111 --media-id 222
xurl reply 1234567890 "Great point!"
xurl reply https://x.com/user/status/1234567890 "Agreed!"
xurl reply 1234567890 "Look at this" --media-id MEDIA_ID
xurl quote 1234567890 "Adding my thoughts"
xurl delete 1234567890
읽기 및 검색
xurl search는 인증된 계정으로 X 인덱스를 쿼리하고 원시 게시글 객체(IDs, 작성자, 전체 텍스트)를 반환하므로 결과에 대해 즉시 답글, 좋아요, 리포스트, 인용 등의 상호작용을 할 수 있습니다. 주제에 대한 요약된 답변이 아닌 실제 게시글이 필요할 때 사용하세요.
xurl read 1234567890
xurl read https://x.com/user/status/1234567890
xurl search "golang"
xurl search "from:elonmusk" -n 20
xurl search "#buildinpublic lang:en" -n 15
X Articles의 경우 read 단축 명령어 대신 원시 API 모드를 사용하세요. xurl read는 게시글 ID 또는 게시글 URL을 예상합니다. /2/tweets/... 엔드포인트 앞에 read를 넣지 마십시오. article 트윗 필드를 요청하고 JSON 응답에서 data.article.plain_text를 가져오세요:
xurl --app APP_NAME '/2/tweets/2057909493250539891?expansions=author_id,attachments.media_keys,referenced_tweets.id&tweet.fields=created_at,lang,public_metrics,context_annotations,entities,possibly_sensitive,conversation_id,in_reply_to_user_id,referenced_tweets,article'
사용자, 타임라인, 멘션
xurl whoami
xurl user elonmusk
xurl user @XDevelopers
xurl timeline -n 25
xurl mentions -n 20
상호작용
xurl like 1234567890
xurl unlike 1234567890
xurl repost 1234567890
xurl unrepost 1234567890
xurl bookmark 1234567890
xurl unbookmark 1234567890
xurl bookmarks -n 20
xurl likes -n 20
소셜 그래프
xurl follow @XDevelopers
xurl unfollow @XDevelopers
xurl following -n 50
xurl followers -n 50
# 다른 사용자의 그래프
xurl following --of elonmusk -n 20
xurl followers --of elonmusk -n 20
xurl block @spammer
xurl unblock @spammer
xurl mute @annoying
xurl unmute @annoying
다이렉트 메시지
xurl dm @someuser "Hey, saw your post!"
xurl dms -n 25
미디어 업로드
# 자동 유형 감지
xurl media upload photo.jpg
xurl media upload video.mp4
# 명시적 유형/카테고리
xurl media upload --media-type image/jpeg --category tweet_image photo.jpg
# 비디오는 서버 측 처리가 필요함 — 상태 확인 (또는 폴링)
xurl media status MEDIA_ID
xurl media status --wait MEDIA_ID
# 전체 워크플로우
xurl media upload meme.png # 미디어 ID 반환
xurl post "lol" --media-id MEDIA_ID
원시 API 액세스
단축 명령어는 일반적인 작업을 다룹니다. 그 외의 경우, 모든 X API v2 엔드포인트에 대해 원시 curl 스타일 모드를 사용하세요:
# GET
xurl /2/users/me
# POST with JSON body
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'
# DELETE / PUT / PATCH
xurl -X DELETE /2/tweets/1234567890
# 사용자 정의 헤더
xurl -H "Content-Type: application/json" /2/some/endpoint
# 강제 스트리밍
xurl -s /2/tweets/search/stream
# 전체 URL도 작동
xurl https://api.x.com/2/users/me
글로벌 플래그
| 플래그 | 단축 | 설명 |
|---|---|---|
--app | 특정 등록된 앱 사용 (기본값 오버라이드) | |
--auth | 인증 유형 강제: oauth1, oauth2, 또는 app | |
--username | -u | 사용할 OAuth2 계정 (여러 개 있을 경우) |
--verbose | -v | 에이전트 세션에서 금지 — 인증 헤더 누출 |
--trace | -t | X-B3-Flags: 1 추적 헤더 추가 |
스트리밍
스트리밍 엔드포인트는 자동으로 감지됩니다. 알려진 엔드포인트:
/2/tweets/search/stream/2/tweets/sample/stream/2/tweets/sample10/stream
모든 엔드포인트에서 -s를 사용하여 강제로 스트리밍할 수 있습니다.
출력 형식
모든 명령어는 JSON을 stdout으로 반환합니다. 구조는 X API v2를 따릅니다:
{ "data": { "id": "1234567890", "text": "Hello world!" } }
오류도 JSON으로 반환됩니다:
{ "errors": [ { "message": "Not authorized", "code": 403 } ] }
일반적인 워크플로우
이미지와 함께 게시
xurl media upload photo.jpg
xurl post "Check out this photo!" --media-id MEDIA_ID
대화에 답글
xurl read https://x.com/user/status/1234567890
xurl reply 1234567890 "Here are my thoughts..."
검색 및 상호작용
xurl search "topic of interest" -n 10
xurl like POST_ID_FROM_RESULTS
xurl reply POST_ID_FROM_RESULTS "Great point!"
활동 확인
xurl whoami
xurl mentions -n 20
xurl timeline -n 20
여러 앱 (자격 증명은 수동으로 사전 구성)
xurl auth default prod alice # prod 앱, alice 사용자
xurl --app staging /2/users/me # staging에 대해 일회성 사용
오류 처리
- 오류 발생 시 0이 아닌 종료 코드.
- API 오류는 여전히 JSON으로 stdout에 출력되므로 구문 분석할 수 있습니다.
- 인증 오류 → 사용자에게 에이전트 세션 외부에서
xurl auth oauth2를 다시 실행하도록 안내. - 호출자의 사용자 ID가 필요한 명령어(좋아요, 리포스트, 북마크, 팔로우 등)는
/2/users/me를 통해 자동으로 가져옵니다. 거기서 인증 실패가 발생하면 인증 오류로 표시됩니다.
에이전트 워크플로우
- 사전 요구 사항 확인:
xurl --help및xurl auth status. xurl search를 사용하기 전에 의도를 확인하세요. 작업에 실제 게시글 객체, 인증된 계정 컨텍스트가 필요하거나 X 쓰기 작업으로 이어질 때 사용하세요. 사용자가 주제 요약이 아닌 상호작용할 수 있는 게시글을 원할 때 적합한 표면입니다.- 기본 앱에 자격 증명이 있는지 확인하세요.
auth status출력을 구문 분석하세요. 기본 앱은▸로 표시됩니다. 기본 앱에oauth2: (none)이 표시되지만 다른 앱에 유효한 oauth2 사용자가 있는 경우 사용자에게xurl auth default <that-app>을 실행하여 수정하라고 알리세요. 이것이 가장 흔한 설정 실수입니다. 사용자가 사용자 정의 이름으로 앱을 추가했지만 기본값으로 설정하지 않아 xurl이 계속 빈default프로필을 시도하는 경우입니다. - 인증이 완전히 누락된 경우 중단하고 사용자를 "일회성 사용자 설정" 섹션으로 안내하세요. 스스로 앱을 등록하거나 비밀 정보를 전달하지 마십시오.
- 저렴한 읽기 명령어(
xurl whoami,xurl user @handle,xurl search ... -n 3)로 시작하여 연결 가능성을 확인하세요. - 쓰기 작업(게시, 답글, 좋아요, 리포스트, DM, 팔로우, 차단, 삭제) 전에 대상 게시글/사용자와 사용자의 의도를 확인하세요.
xurl명령어 출력(또는 원시 X API 응답)만이 상태 변경 X 작업이 발생했음을 증명합니다. 검색 결과, 요약 또는 이전 컨텍스트와 같은 다른 출처를 기반으로 쓰기 작업이 완료되었다고 보고하지 마십시오.- JSON 출력을 직접 사용하세요. 모든 응답이 이미 구조화되어 있습니다.
~/.xurl내용을 대화에 절대 붙여넣지 마십시오.
문제 해결
| 증상 | 원인 | 해결 방법 |
|---|---|---|
| OAuth 흐름이 성공한 후 인증 오류 | 토큰이 명명된 앱 대신 (client-id/secret이 없는) default 앱에 저장됨 | xurl auth oauth2 --app my-app 실행 후 xurl auth default my-app 실행 |
OAuth 중 unauthorized_client | X 대시보드에서 앱 유형이 "Native App"으로 설정됨 | 사용자 인증 설정에서 "Web app, automated app or bot"으로 변경 |
OAuth 직후 /2/users/me에서 UsernameNotFound 또는 403 | X가 /2/users/me에서 사용자 이름을 안정적으로 반환하지 않음 | xurl auth oauth2 --app my-app YOUR_USERNAME (xurl v1.1.0+)을 다시 실행하여 핸들을 명시적으로 전달 |
| 모든 요청에서 401 | 토큰 만료 또는 잘못된 기본 앱 | xurl auth status 확인 |
xurl을 찾을 수 없음 | PATH에 없거나 설치되지 않음 | 셸 스크립트를 다시 실행하거나 수동으로 ~/.local/bin을 PATH에 추가 |
| Docker에서 명령어가 작동하지 않음 | HOME 불일치 | HOME=/opt/data/home xurl을 사용하거나 심볼릭 링크 생성: ln -s /opt/data/home/.xurl /opt/data/.xurl |
한계
- 공간(Space) 관련 작업은 지원되지 않습니다.
- 트렌드, 리스트, 게시글 분석 등 일부 엔드포인트는 OAUTH 2.0과 함께 사용할 수 없습니다. 필요한 경우 각 요청에
--auth oauth1을 사용하세요. - 비디오를 60fps로 게시하려면
profile: { video: { quality: 60fps } }카테고리로 수동 업로드가 필요합니다. - DM 미디어 공유는 현재 지원되지 않습니다.
참고 사항
타임라인은 결과의 결과
xurl timeline은 홈 타임라인에 있는 가장 최근 게시글 N개를 반환합니다. 누군가의 게시글을 찾고 있다면, 해당 사용자의 게시글이 타임라인에 나타났을지 여부를 추측하거나 출처를 오해하지 마십시오. 확실한 방법은 xurl user @handle을 사용하여 사용자 객체를 가져오고 xurl search "from:handle" -n 20을 사용하는 것입니다. xurl timeline은 무작위 검색이 아닙니다.
리포스트는 부드러운 북마크입니다
xurl repost는 리포스트를 생성합니다. 나중에 보기 위한 목록으로 리포스트를 사용하지 마십시오. xurl bookmark를 사용하세요. (리포스트는 사용자에게 알림을 보냅니다.)
캐싱 없음
xurl search는 매번 X API에 직접 쿼리합니다. 동일한 검색을 여러 번 실행하면 반환되는 게시글이 다를 수 있습니다.