프로토타입 · 미리 보기: 공식 레지스트리의 모든 서버를 담고 있으며 30분마다 동기화해요. 리뷰와 계정 기능은 다음 단계에서 열려요.
PopNx MCPAI를 쓰는 사람을 위한 MCP 서버 · 쉬운 말로 설명해요

Skill MCP

제작자: chrischall버전 1.2.3i★ –i내 컴퓨터에서 실행
레지스트리 이름io.github.chrischall/skill-mcp

설치

개요

제작자가 쓴 설명(영어 원문)

Serves a directory of Agent Skills over MCP: list, load, read files, run declared scripts

PopNx MCP의 세 기둥

이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.

할 수 있는 일

이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.

  • 연결 방식: 내 컴퓨터에서 실행
  • 전송 방식: stdio
  • 카테고리: 기타

설치

쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.

설치하기 전에

필요한 것

  • npmNode.js 설치(npx 명령어용)

어떤 앱을 쓰세요?

위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.

Claude Desktop → Settings → Developer → Edit Config를 열고 claude_desktop_config.json에 이 내용을 붙여 넣으세요

{
  "mcpServers": {
    "skill": {
      "command": "npx",
      "args": [
        "-y",
        "@chrischall/skill-mcp"
      ],
      "env": {
        "SKILLS_DIR": "your-value"
      }
    }
  }
}

터미널에서 이 명령어를 실행하세요

claude mcp add skill --env SKILLS_DIR=your-value -- npx -y @chrischall/skill-mcp

실행하기 전에 빈 값을 채워 주세요.

Cursor에서 열기

또는 설정을 직접 복사하기

프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요

{
  "mcpServers": {
    "skill": {
      "command": "npx",
      "args": [
        "-y",
        "@chrischall/skill-mcp"
      ],
      "env": {
        "SKILLS_DIR": "your-value"
      }
    }
  }
}

브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.

VS Code에서 열기

또는 설정을 직접 복사하기

프로젝트의 .vscode/mcp.json에 붙여 넣으세요

{
  "servers": {
    "skill": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@chrischall/skill-mcp"
      ],
      "env": {
        "SKILLS_DIR": "your-value"
      }
    }
  }
}

브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.

이 서버는 내 컴퓨터에서 실행되는데, ChatGPT는 인터넷에 있는 서버에만 연결할 수 있어요. 다른 앱을 고르세요.

선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.

직접 입력할 값

  • SKILLS_DIR env
    Directory of skills to serve (':'-separated for several). Defaults to the example skill bundled with this package.

이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.

할 수 있는 일

내 컴퓨터에서 실행돼요. 설치하면 AI 앱에 도구 목록이 나타나요.

기본 점검i

누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 7일 점검

  • ✓ 통과

    제작자와 저장소 일치

    레지스트리 이름이 GitHub 계정 chrischall 기준으로 확인되었고, 이 계정이 저장소를 소유하고 있어요

  • … 아직 점검 안 함

    계속 관리되고 있음

    아직 GitHub에서 이 저장소를 읽어 오지 않았어요

  • … 아직 점검 안 함

    라이선스 있음

    아직 GitHub에서 이 저장소를 읽어 오지 않았어요

  • – 해당 없음

    엔드포인트 응답

    내 컴퓨터에서 실행되는 서버라 인터넷 엔드포인트가 없어요

  • – 해당 없음

    OAuth로 로그인

    내 컴퓨터에서 실행되며, 대신 로컬 설정을 사용해요

  • … 아직 점검 안 함

    도구 설명에 숨겨진 지시 없음

    내 컴퓨터에서 실행돼요. 도구 목록은 인터넷 엔드포인트가 있는 서버에서만 읽을 수 있어요

기타 카테고리의 다른 서버와 비교i

  • 이 카테고리의 다른 서버 32623개 중 0%보다 스타가 많아요
  • 이 카테고리의 다른 서버 32623개 중 80%보다 최근에 레지스트리에 공개됐어요
  • 기본 점검 결과가 이 카테고리의 다른 서버 32623개 중 100%와 같거나 더 좋아요

레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.

자주 묻는 질문

Skill MCP, 안전한가요?

해당하는 기본 점검 1개 중 1개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.

어떤 키나 코드가 필요한가요?

레지스트리에 필수 키가 나와 있지 않아요. 다만 처음 쓸 때 로그인을 요구하는 서버도 있어요.

내 컴퓨터에서 실행되나요, 클라우드에서 실행되나요?

내 컴퓨터에서 실행돼요. AI 앱이 필요할 때 실행하고, 데이터는 제작자의 서버를 거치지 않아요(서버 자체가 온라인 서비스를 호출하는 경우는 제외).

아직 관리되고 있나요?

GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(1.2.3)은 8일 전 레지스트리에 올라왔어요.

어떤 앱에서 쓸 수 있나요?

Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. 내 컴퓨터에 Node.js도 있어야 해요.

대신 쓸 수 있는 건 뭐가 있나요?

같은 카테고리에는: Spec Driven Development, Remote Desktop Commander, Draugr

대안

같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.

카드 보는 법:★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i

Spec Driven Development

제작자: formulahendry

MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.

내 컴퓨터에서 실행★ 440MIT14개월 전 업데이트
설치

Remote Desktop Commander

제작자: desktop-commander

Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.

클라우드에서 실행★ 211그저께 업데이트
설치

Draugr

제작자: draugr-dev

Security scanning for AI agents: SAST, SCA, secrets, IaC, DAST, ranked by real risk.

내 컴퓨터에서 실행오늘 업데이트
설치

제작자의 README

README 열기

제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.

skill-mcp

An MCP server that serves a directory of Agent Skills. Point it at skills; it lists them, hands out their instructions and their bundled files, and runs only the scripts a skill declares.

It is a generic adapter, not a curated set: the skills are content it reads, and the same build serves whatever it is pointed at.

npx @chrischall/skill-mcp                       # serves the example skill bundled here

SKILLS_DIR=~/my-skills npx @chrischall/skill-mcp

The npm package is `@chrischall/skill-mcp` (unscoped skill-mcp is taken by someone else on npm). Everything else — the repo, the binary, the registry identity io.github.chrischall/skill-mcp — is unscoped.

What a skill is

A directory holding SKILL.md: YAML frontmatter (name, description, and optionally the mcp-host: block below) followed by instructions, plus whatever files those instructions refer to. Three layouts are found under each root:

<root>/SKILL.md              # the root IS one skill

/ /SKILL.md # a directory of skills /skills/ /SKILL.md

A skill is served under its DIRECTORY name, never under the name in its own frontmatter (a frontmatter name that disagrees is reported and otherwise ignored; where the root itself is the skill, the root directory names it). That is a security rule, not a tidiness one: the owner's grant names a skill, so a bundle that could choose its own name could claim its neighbour's and be handed the neighbour's granted script and granted variables. For the same reason, two directories that really do contribute one name — only possible across two roots — have both refused and reported, rather than one of them winning by scan order.

The tools

toolargumentsreturns
skill_list—every skill found: name, description, when to use it, file count, whether it declares runnable scripts and exactly which; plus problems, so an empty list is never a mystery
skill_loadnamethe SKILL.md body verbatim, plus a manifest of the bundle's files. Referenced files are not inlined — that is what skill_file is for
skill_filename, paths[]one entry per path, in request order: text, or base64 with its media type, or that path's own error. At most 1 MiB per entry, truncated: true rather than a silent cut
skill_runname, script, args[], confirmToken{exitCode, stdout, stderr, truncated, durationMs}

skill_file takes a paths[] batch, so the files a SKILL.md points at come back in one round trip: at most 8 paths per call, 1 MiB per entry and 4 MiB per call (summed from file sizes before a byte is read, so the answer never depends on the order the paths were listed in). One bad path fails only its own entry — the rest of the batch is still served. Read the caps as bounds on this server's own heap: they cap the allocation, not only the answer, because a hosted child has a hard 256 MiB data limit and a bundle may be larger than that.

Each skill is also registered as an MCP prompt (its body is the message) and each bundled file as a resource (skill:// / ), because a client that supports those surfaces presents a skill better than a tool call does. It is a second door, never the only one: when this server runs on mcp-host and a registration narrows enabledTools, prompts/list and resources/list come back empty and the handshake stops advertising those capabilities — so the tools carry the whole experience.

Discovery reports, it never goes quiet

Anything that keeps a directory from being served comes back in skill_list's problems, with the path and the reason: no SKILL.md, frontmatter that will not parse, a name two directories both claim (both refused), a declared script that is not in the bundle, a symlink leading out of the root or out of a skill, a filename the read tools could not address. One bad skill costs itself and never the listing, and there is no third outcome where something is dropped in silence — a symlinked skill directory is served when it stays inside the root (so skills/foo -> ../shared/foo works) and reported when it does not. It is served under its *target* directory's name — skills/foo -> ../bar is the skill bar, reported as a name-mismatch so a grant is written against the right name — and a directory reached twice (a link to a skill that is also listed directly) is one skill, not a duplicate.

Problem reasons

Each entry in problems is {path, reason, detail}. detail is prose for a person; reason is the stable value to switch on.

reasonmeaning
root-unreadablea configured root could not be read at all
no-skill-mda candidate directory holds no SKILL.md
unreadable-skill-mdSKILL.md is not a regular file, or could not be read
malformed-frontmatterthe frontmatter does not parse
declarationthe mcp-host: block was refused, or carries an unknown key (named in detail); the skill's scripts are affected, its instructions are not
duplicate-nametwo directories contribute one skill name; both are refused
name-mismatchthe frontmatter name disagrees with the directory name, which wins
unusable-namethe directory's own name is not addressable, so the skill is skipped
declared-script-missinga declared script is not in the bundle
symlink-escapea symlink leads out of the root or out of a skill
unusable-patha filename the read tools could not address, left out of the manifest
file-limita skill holds more files or directories than the per-skill cap (2000 each); the manifest lists what was walked
skill-limitmore skills than MAX_SKILLS (32) were found; the rest are ignored
grantMCP_SKILL_RUN names a script the skill does not declare, so that row grants nothing
environ-unscrubbedhosted, and the exec-time environment block could not be wiped, so no script runs (see the env allowlist note below)

The set is additive. New reasons arrive without a major version bump (environ-unscrubbed is the most recent), so a client that switches on reason must treat a value it does not recognise as a generic problem and show its detail, never fail on it.

The execution fence

skill_run executes third-party code. Every rule below narrows which code runs and what it is handed; each has its own test.

  • Only a script the skill DECLARES. Not "any file under scripts/", not "anything executable". An undeclared path is refused, saying it must be declared and listing the ones that are.
  • Only inside that skill's own directory. The path is checked as a string first (plain segments; no leading /, no . or .., no backslash, no percent escape, no NUL) and then again after resolution: the real path, with symlinks followed, must still be inside the skill's real directory, and it must be a regular file. Both checks, because a string check alone misses a symlink planted inside the bundle and a resolved check alone accepts shapes that should never have been joined. The same discipline governs skill_file: a read out of a skill directory is another skill's bundle at best.
  • An argv array, never a shell string. spawn with shell: false, no interpolation, no sh -c. Arguments are passed through verbatim.
  • An interpreter from a closed set, named by the declaration — never inferred from the extension and never taken from the file's own shebang, since a file that can choose its own interpreter has already chosen its own program. v1 runs `node` and nothing else (see *What v1 cannot run*).
  • Bounded, and the call always returns. A wall-clock timeout (60 s default, per-script override, hard 300 s ceiling), 1 MiB captured per stream with truncated: true rather than a silent cut, and one skill_run at a time. On timeout the process group is signalled, which reaches the script and any child that stayed in its group. It does not reach a grandchild that detached into a group of its own, and such a grandchild also holds the stdio pipes open — so the run settles on the process exiting plus a short drain, under a hard deadline, rather than on the pipes closing. That is what guarantees the tool call returns within its budget and frees the one-at-a-time lock; it is not a guarantee that a deliberately detached grandchild is dead. Bounding *that* is the tier's job (an unprivileged uid, prlimit NPROC, and a machine that stops), not this adapter's.
  • An env allowlist. A script gets PATH, HOME, LANG, TZ, TMPDIR, MCP_DATA_DIR when the host set one, the egress proxy variables (HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy, NO_PROXY, no_proxy, NODE_USE_ENV_PROXY) when the host set them — on mcp-host's isolated tier the network is fenced and a script without them cannot reach even an allowlisted host — and exactly the variables that script asked for and the owner granted — never this server's own environment. The fixed half mirrors mcp-host's INSTALL_ALLOWLIST (packages/runner-node/src/spawn-env.ts), for the reason that file gives: a host constant a hosted declaration cannot widen by one name. This decides what a script is handed, not what a hostile script can reach. A script runs as the same uid as this server. On Linux a same-uid process can read /proc/ /environ, so at boot the server wipes that exec-time environment block (src/scrub-environ.ts; process.env keeps every value) and that one-line read comes back empty. If a kernel or sandbox refuses that wipe, a hosted server runs no script at all — skill_run refuses and skill_list reports environ-unscrubbed — unless the owner sets MCP_SKILL_ALLOW_UNSCRUBBED=1; standalone it only warns on stderr. The values still live in the server's memory, reachable through ptrace or /proc/ /mem on a kernel at Yama ptrace_scope = 0. Real isolation between skills that do not trust each other needs the tier (a distinct uid for scripts, /proc mounted hidepid=2, or a non-dumpable server); until then, only put skills in one registration if you would give each of them every credential it holds.
  • A non-zero exit is a normal, reported outcome — exit code, stdout and stderr all come back. It is never an exception that loses the output.
  • `skill_run` asks before it runs anything. On a client that can show a confirmation prompt (Claude Code) the user is asked there, unless the server sets MCP_CONFIRM_ELICITATION=off. Otherwise the first call starts no process and returns status: "confirmation-required" with a preview of exactly what would run — the interpreter, the argv, the working directory, the timeout, and the names of the variables the script would be handed (field by field in the preview) — plus a confirmToken. Only a repeat call with the same arguments and that token runs the script, once. A token is bound to that exact run: changing the skill, script or argv is refused as DRAFT_CHANGED, and a used token as TOKEN_REUSED. See Confirmations.
The skill_run preview

The first call's preview.willRun is what the user approves, and it is the confirmToken's payload: the token is bound to it. Names only — never a value.

field
skillthe skill, by its directory name
interpreterthe declared interpreter (node)
argvthe script path followed by the arguments, exactly as they will be passed
cwdthe skill's own directory, where the script runs
timeoutMsthe wall-clock budget, after the 300 s clamp

| envNames | every variable the script will be handed, sorted — not onl

앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요

PopNx에게 묻기