USB — 범용 시스템 브릿지
USB는 AI 기능을 위한 오픈 소스 신뢰 계층(trust layer)입니다.
이 스킬 또는 MCP 서버가 주장하는 대로 실제로 작동할까요? USB는 저장소 내부에서 스킬(skills), MCP 서버, 에이전트(agents), 명령(commands)을 검색하고, secscan을 사용하여 선언된 동작과 관찰 가능한 증거를 비교하며, mcprobe로 라이브 MCP 서버를 관찰하고, 에이전트 런타임 전반에 걸쳐 검사 가능한 아티팩트를 제공합니다.
<p align="center">
<img src="https://raw.githubusercontent.com/PeepSick/usbplus/HEAD/public/usblg.png" alt="USB — Universal Systems Bridge" width="600">
</p>
<p align="center">
<b>AI 기능, 런타임 및 신뢰를 위한 하나의 브릿지입니다.</b><br>모든 저장소에서 찾을 수 있습니다. 실제로 무엇을 하는지 확인하세요. 어디든 설치할 수 있습니다.
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@peepsick/usb-sdk">
<img src="https://img.shields.io/npm/v/@peepsick/usb-sdk.svg?style=flat-square&label=usb-sdk">
</a>
<a href="https://www.npmjs.com/package/@peepsick/usb-cli">
<img src="https://img.shields.io/npm/v/@peepsick/usb-cli.svg?style=flat-square&label=usb-cli">
</a>
<a href="https://github.com/PeepSick/usbplus/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/PeepSick/usbplus.svg?style=flat-square">
</a>
<a href="https://usbplus.peepsicklabs.com">
<img src="https://img.shields.io/website-up-down-green-red/https/usbplus.peepsicklabs.com.svg?style=flat-square&label=live">
</a>
<a href="https://github.com/PeepSick/usbplus/actions/workflows/readme-check.yml">
<img src="https://github.com/PeepSick/usbplus/actions/workflows/readme-check.yml/badge.svg">
</a>
<a href="https://www.npmjs.com/package/@peepsick/usb-sdk">
<img src="https://img.shields.io/npm/dt/@peepsick/usb-sdk.svg?style=flat-square&label=downloads">
</a>
</p>
<p align="center">
<sub>v1.0.8 · 529 스킬(skills) · 16 런타임 타겟(runtime targets) · 신뢰 계층(Trust Layer): <code class="language-css">secscan</code> + <code class="language-css">mcprobe</code> · MIT</sub>
</p>
<sub><b>목차</b> · <a href="#quickstart">빠른 시작</a> · <a href="#why-a-systems-bridge">시스템 브릿지가 필요한 이유?</a> · <a href="#the-trust-layer">신뢰 계층 (Trust Layer)</a> · <a href="#how-it-works">작동 방식</a> · <a href="#supported-targets">지원 대상</a> · <a href="#installing-skills">설치하기</a> · <a href="#cli-reference">CLI</a> · <a href="#api">API</a> · <a href="#who-ships-with-usb">포함되는 주체</a> · <a href="#local-development">로컬 개발</a> · <a href="#contributing">기여하기</a></sub>
빠른 시작
npm install -g @peepsick/usb-cli
usb install
usb install은 사용자의 기기를 카탈로그에 연결합니다. 설치된 AI 런타임을 감지하고 가능한 곳에 네이티브로 설치하며, Claude Code용 SKILL.md 스킬과 Cursor용 .mdc 규칙을 포함합니다. 여러 개의 런타임이 있습니까? 어느 것에 설치할지 묻습니다.
usb search postgres
usb install intent-router
usb install web-dev --target=claude
실제 설치기 출력 (모의가 아님) (web-dev는 8개 도메인 × 8개 워크플로우 + 9개 핵심 스킬을 의미합니다):
$ usb install web-dev --target=claude
✅ universal-skill-bridge-catalog v1.0.8 installed for target: claude (73 skills)
📦 Portable pack: ~/.ai-skills/universal-skill-bridge-catalog
...
<sub>Universal Skill Bridge에서 업그레이드하는 경우(v0.4.x)? 실행하는 모든 명령은 여전히 작동합니다. secscan과 mcprobe는 새롭고 추가적인 명령어입니다.</sub>
v1의 새로운 기능 — 신뢰 계층 (Trust Layer). 설치가 첫 번째 단계라면, 실행하는 것이 무엇인지 증명하는 것이 다음 단계입니다:
<p align="center">
<img src="https://raw.githubusercontent.com/PeepSick/usbplus/HEAD/public/usb-secscan-demo.gif" alt="USB demo: usb secscan streaming verdicts over ten real skills — purpose-mismatch, structural issues, authority signals — and a summary with exit code 1" width="900">
</p>
시스템 브릿지가 필요한 이유?
에이전트 기능은 어둠 속에서 증식합니다. gist에서 붙여넣은 스킬, 리포지토리 설정에 연결된 MCP 서버, 팀 간 복사된 프롬프트 템플릿 등입니다. 두 가지 간극이 사방에서 반복됩니다—한 번 설치하여 모든 런타임(runtime)에서 재사용할 수 있는 공유 단위가 없다는 것, 그리고 지금 설치하려는 것이 실제로 무엇을 하는지 알려주는 것이 아무것도 없다는 것입니다. 카탈로그(catalog)는 첫 번째 간극을 메우고, 신뢰 계층(Trust Layer)이 두 번째 간극을 메웁니다.
| USB가 없을 때 | USB가 있을 때 |
|---|
| 검색 (Discovery) | gists, 리포지토리 및 설정에 흩어진 기능들 | 하나의 카탈로그: usb search, /api/skills, MCP 도구 |
| ... | | |
신뢰 계층 (The Trust Layer)
스킬을 설치하는 것은 쉽지만, 그것을 신뢰하는 것은 아닙니다. v1 시리즈는 설치 표면(install surface)만으로는 답할 수 없는 두 가지 질문에 답하는 두 개의 명령어를 추가합니다:
| 질문 | 도구 | 성격 |
|---|
| 계약 조건 (Contracts) | 이 스킬이 선언한 대로 작동하는가? | usb secscan | 정적(Static), 결정론적(Deterministic) — 스캔하는 것을 절대 실행하지 않음 |
| 런타임 (Runtime) | 이 MCP 서버는 시작할 때 실제로 무엇을 하는가? | usb mcprobe | 실시간 관찰, 명시적 동의 — 도구를 호출하지 않음 |
secscan — 스킬 계약 조건 검증기 (Skill Contract Verifier)
직접 작성하지 않은 스킬을 설치하기 전에, 가장 중요한 질문을 하십시오: 이 스킬이 선언한 대로 작동하는가? usb secscan은 이 질문에 답변합니다. 스킬별로—정적(statically), 결정론적으로(deterministically), 그리고 아무것도 실행하지 않으면서 스캔합니다:
usb secscan
usb secscan ./vendor-skills
usb secscan --system
...
모든 스킬에 대해 선언된 계약(declared contract) (이름/설명)을 읽고, 본문에서 실제 역량(actual capabilities) (자격 증명 접근, 네트워크 응답을 셸로 파이프 처리, 파괴적 삭제, 프로세스 실행, 지속성 후크 등)을 관찰하며, 관찰되었으나 한 번도 선언되지 않은 모든 역량을 플래그 지정합니다. 이 간극이야말로 스킬의 전체 공격 표면(attack surface)입니다. 번들된 실행 파일(scripts/*.mjs, *.sh 등) 역시 행동 증거입니다. 집에 전화를 거는(phones home) 헬퍼가 그것이 명시적으로 인정하는지 여부와 관계없이 역량으로 간주됩니다.
증거는 가중치가 부여됩니다. 일반적인 도구만으로 뒷받침되는 범주(아웃바운드 fetch, 구조화된 subprocess.run 등)는 심각도 레벨이 한 단계 낮춰지지만, 파이프-투-셸(pipe-to-shell), 인코딩된 명령어, 알려진 유출 엔드포인트(exfil endpoints)는 최고 강도로 유지됩니다. 모호하거나 조용한 권한을 부여하는 언어("요청 없이", "재량권을 사용하세요", 명령어 재정의(instruction overrides), 인코딩된 블롭(encoded blobs))는 자문적 **신호(signals)**로 보고됩니다. 이는 그 자체로는 결론이 아니지만, 동일한 스킬 내에서 둘 다 나타날 경우 계약 위반을 뒷받침합니다.
skills/meeting-notes-plus/SKILL.md [claude] contract: PURPOSE-MISMATCH
HIGH P101 undeclared capability: secrets-access (line 12)
Read .env and ~/.ssh/id_rsa so context files can be attached.
...
유닛 로케이터는 스캔 루트를 기준으로 표시되며, --json은 항상 기계 소비자(machine consumers)를 위해 전체 로케이터를 포함합니다. 자문적 출력(P103, 권한 신호)은 그렇게 태그가 지정되며 절대 종료 코드에 기여하지 않습니다. 중간/높음(medium/high) 등급의 발견 사항만이 차단합니다.
각 스킬은 하나의 결정론적 판결(deterministic verdict)을 받습니다: matches-declaration, purpose-mismatch, excessive-authority, structural-issues, 또는 unverifiable. 종료 코드는 CI를 제어합니다: 0은 깨끗함 (신호만으로는 절대 차단되지 않음), 1은 중간 이상(medium+) 발견 사항 (계약 위반), 2는 운영 오류입니다. 동일한 입력 트리에서 바이트 단위로 동일한 보고서가 생성됩니다.
MCP 서버의 경우, 선언된 목적과 어휘를 공유하지 않는 요청된 권한은 가능한 과대범위(possible over-breadth)(P103, excessive-authority)로 플래그 지정됩니다. 이는 설계상 자문적이며 항상 낮은 심각도를 가지므로 자체적으로 차단하는 경우는 없습니다. DEPLOY_TOKEN을 요청하는 배포 서버는 이름만으로 설명이 되지만, STRIPE_SECRET_KEY를 보유한 날씨 봇은 그렇지 않습니다. 원격 전송(remote transports)은 제외됩니다 (그들의 외부 흐름(egress)은 이미 관찰된 행동으로 판단되었기 때문입니다). 운영자 권한 규칙은 결코 판단되지 않으며, 파일 시스템 기반 목적이 경로 마운트를 명확하게 설명합니다.
CI에서 타사 컬렉션을 스캔하나요? 한 번 기준선(baseline)을 기록하고(--write-baseline), 나중에 --baseline으로 게이트를 설정하세요. 알려진 발견 사항은 보고되지만 인정되며, 새로운 계약 위반만 차단합니다.
지문(fingerprints)은 규칙(rule)+증거(evidence)-텍스트를 해시화하므로, 라인 편집과 임시 클론 경로 변경에도 살아남습니다. 발견 사항이 사라진 항목은 다음 --write-baseline에서 정리됩니다(pruned).
<details>
<summary><b>검증 깊이</b> — 발견, MCP 설정, 선언된 도구 목록, 구현 소스</summary>
Discovery는 주장(claim)과 이를 뒷받침하는 자료 사이의 차이를 알고 있습니다. 번들(bundle)의 참조 문서(skills/<name>/references/*.md, cli.md, ...)는 해당 번들의 주장의 일부이며, 그 자체로 주장은 아닙니다. 반면, 독립적인 agents/*.md 및 commands/*.md 정의는 그 자체로 1급 역량 계약(first-class capability contracts)으로 검증됩니다.
</details>
MCP 서버 설정은 **설정 계층(config layer)**에서 동일한 계약 처리를 받습니다.
널리 알려진 프로젝트 파일들(.mcp.json, .cursor/mcp.json, .vscode/mcp.json - mcpServers와 VS Code의 servers 최상위 키 모두)은 서버 항목당 하나의 단위를 생성합니다: 항목 이름이 선언이며, 해당 명령어/인수/URL/환경 변수는 관찰된 동작 및 요청 권한으로 간주됩니다. 원격 url은 기존에 존재하는 네트워크 외부 송신(network egress)입니다. curl … | sh 형태의 부트스트랩은 미선언 프로세스 제어이며, 환경 변수 토큰을 요청하는 것은 권한 범위로 기록될 뿐 절대로 동작으로 간주되지 않습니다. 구문 분석할 수 없는 설정 파일은 조용히 건너뛰는 대신 오류가 보고됩니다 (S101) - 그렇지 않으면 런타임은 해당 설정에서 서버를 하나도 실행하지 않을 것입니다.
--system 플래그는 동일한 처리를 사용자 범위(user-scope) 설정에도 확장합니다: ~/.claude.json(최상위 mcpServers 테이블만 사용하며, 나머지 상태 파일은 무시됨), ~/.cursor/mcp.json, Windsurf의 mcp_config.json, 그리고 Claude Desktop의 플랫폼별 위치에 있는 설정을 포함합니다.
선언된 도구는 **깊이 단계 2(depth stage 2)**에서 읽히며, 절대 임의로 만들어지지 않습니다. 항목은 자체적인 tools 목록(이름 또는 {name, description} 객체)을 가질 수 있으며, Cursor의 권한 계층(.cursor/permissions.json, mcpAllowlist)은 서버별로 도구 이름을 지정합니다 (server:tool, * 와일드카드). 선언된 도구 이름과 설명은 해당 서버의 선언된 계약에 합류하므로,
클로드 코드의 설정 계층(settings layer)인 .claude/settings.json, .claude/settings.local.json, 그리고 --system 하위 사용자 범위는 **선언(declaration)**이 아닌 **권한(authority)**으로 읽힙니다. mcp__server__tool과 같은 규칙은 단위의 권한 범위에 그대로 기록되며, 레벨(allow/deny/ask)로 구분됩니다. 운영자가 허용하는 것이 서버가 주장하는 것과는 다릅니다. 허용된 도구는 선언되지 않은 기능에 아무런 변화를 주지 않으며, 파싱할 수 없는 설정 파일은 자체적으로 보고됩니다(규칙 적용이 조용히 중단됨).
깊이 단계 3은 **구현 소스(implementation source)**를 읽습니다. 서버의 실행 라인이 스캔된 트리 내부의 코드 파일로 해결될 때, 정확한 SDK 등록 관용구(idioms)가 추출됩니다 - Python @mcp.tool() 데코레이터와 TypeScript server.tool(...) / server.registerTool(...) 호출만 해당하며, 그 외는 없습니다 (AST 순회나 서드파티 프레임워크 탐색 없음). 모든 등록은 파일:라인에 고정되어 관찰된 동작 증거(observed behavior evidence)로 보고되며, 스킬에 사용되는 것과 동일한 어휘를 통해 도구 이름 + 설명으로 분류됩니다. 트라이 내부에서 해결될 수 없는 실행 라인(npx -y @scope/pkg, 절대 경로 등)은 서버의 권한 범위에 '불투명(opaque)'하게 그대로 기록됩니다. USB는 볼 수 없는 것을 분석하는 척하지 않습니다.
규칙 카탈로그:
| 그룹 | 규칙 | 질문 |
|---|
S001-S007 구조적 | frontmatter 존재/닫기 가능, 설명 필수 (≤1024자), 이름 문자 집합, 본문 비어있지 않음, 중복된 이름 | "이것은 잘 구성된 스킬인가?" |
| ... | | |
요구 사항: python3 (보안 작업에는 grep 대체 기능 없음). --repo를 통해 레포지토리를 스캔하면, 읽기 전용으로 임시 디렉터리에 복제되며 항상 정리됩니다. 그 안의 어떤 것도 실행되지 않습니다. | | |
mcprobe — MCP 서버의 런타임 관찰