project-structure · modelcontextprotocol — скилл для Claude Code: куда положить новый файл
Скилл разбирает устройство репозитория modelcontextprotocol/servers и подсказывает, в какой файл или каталог добавить новый код.
npx skills add modelcontextprotocol/servers --skill project-structure -a claude-codeЧто делает project-structure
Репозиторий modelcontextprotocol/servers держит семь серверов, и у каждого своя раскладка. Скилл описывает уровень ниже общего дерева из AGENTS.md: что лежит внутри каждого сервера и куда идёт новый файл — инструмент, ресурс, промпт, транспорт, вспомогательный модуль, флаг командной строки или корневой скрипт. Пригодится, когда раскладка сервера непонятна или нужно решить, писать код прямо в entry-файле или выносить в отдельный модуль.
Общей библиотеки между серверами нет. Каждый каталог под src/ — самостоятельный пакет со своей версией и публикацией, поэтому хелпер, нужный двум серверам, пишется в обоих: expandHome есть и в filesystem, и в memory. Кросс-серверный импорт добавлять нельзя — это первое, на чём споткнётся наивный рефакторинг.
Четыре TypeScript-сервера — npm workspaces корневого package.json с одной формой: точка входа index.ts, исходники в корне workspace, тесты в __tests__/, сборка tsc в dist/. Три Python-сервера — независимые проекты на uv с server.py, где живут модели Pydantic, логика и serve(). Ни один сервер не стартует при импорте: каждый собирает себя в фабрике createServer(...), а транспорт подключается только при запуске процесса.
Какие задачи решает
- найти, в каком файле регистрируются инструменты сервера
everything - решить, выносить ли новый инструмент в отдельный модуль или писать в entry-файле
- добавить транспорт и не забыть
caseвindex.tsи скриптstart:… - понять, почему хелпер продублирован в двух серверах, и не ломать это импортом
- разложить новый инструмент Python-сервера по модели,
list_toolsиcall_tool
Примеры запросов агенту
- Куда положить новый инструмент для сервера
everything? - Я добавляю флаг командной строки в Python-сервер — какой файл править?
- Помоги выбрать между entry-файлом и отдельным модулем для этого кода
Как установить project-structure
1Через Skills CLI (Vercel)
npx skills add modelcontextprotocol/servers --skill project-structure -a claude-code2Вручную: положить файлы
~/.claude/skills/project-structure/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/project-structure/
1Через Skills CLI (Vercel)
npx skills add modelcontextprotocol/servers --skill project-structure -a codex2Вручную: положить файлы
.agents/skills/project-structure/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add modelcontextprotocol/servers --skill project-structure -a cursor2Вручную: положить файлы
.cursor/skills/project-structure/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install modelcontextprotocol/servers project-structure2Вручную: положить файлы
.github/skills/project-structure/SKILL.md1Через Skills CLI (Vercel)
npx skills add modelcontextprotocol/servers --skill project-structure -a gemini-cli2Командой платформы
gemini skills install https://github.com/modelcontextprotocol/servers --path .claude/skills/project-structureВручную: положить файлы
.devin/skills/project-structure/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add modelcontextprotocol/servers --skill project-structure -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора7
Другие версии project-structure
Похожие
Рядом в теме «Настройка агента: память, контекст, субагенты»
Всё по теме «Настройка агента: память, контекст, субагенты» →Вопросы о project-structure
Как установить project-structure в Claude?
Выполните npx skills add modelcontextprotocol/servers --skill project-structure -a claude-code. Скилл окажется в ~/.claude/skills/project-structure/SKILL.md.
Что делает project-structure?
Показывает, как устроены семь серверов репозитория, и подсказывает место для нового файла: инструмента, ресурса, промпта, транспорта, хелпера, флага или корневого скрипта.
Можно ли вынести общий хелпер в отдельный модуль для нескольких серверов?
Нет. Каждый каталог под src/ — самостоятельный пакет, поэтому нужный двум серверам хелпер пишется в обоих, как expandHome в filesystem и memory.
Исходный текст
SKILL.md · Apache-2.0
---
name: project-structure
description: "Find where code lives in this repo's seven servers and decide where a new file goes. Use when choosing the file or directory for a new tool, resource, prompt, transport, helper module, command-line flag or root script; when a server's layout is unclear; or when asking whether code belongs in a server's entry file or a module of its own."
disable-model-invocation: false
---
# Project structure
The top-level tree, with each server's package name and registry, is in
[`AGENTS.md`](../../../AGENTS.md) under **Project structure**. This skill is the
level below it: what is inside each server, and where a new file goes. Test
placement and harnesses are `/testing`; building and running a server is
`/local-dev`.
There is **no shared library between servers**. Each directory under `src/` is
a complete package that versions and publishes on its own, so a helper two
servers need is written in both (`expandHome` exists in `filesystem` and in
`memory`, and the copy in `memory` says so). Do not add a cross-server import.
## The TypeScript servers
All four are npm workspaces of the root `package.json` and share one shape: the
entry point is `index.ts`, sources sit at the workspace root (there is no
`src/` inside a server), tests are in `__tests__/`, and `tsc` writes `dist/`.
Each has the same four config files: `package.json`, `tsconfig.json` (the
build), `tsconfig.test.json` (the no-emit typecheck program, which also
includes the tests) and `vitest.config.ts`.
| Server | Layout | Where its features are registered |
| --- | --- | --- |
| `everything` | `index.ts` picks a transport from `argv`; `server/` holds the factory; `tools/`, `resources/`, `prompts/` hold one file per feature plus an `index.ts`; `transports/` holds one file per transport; `version.ts` reads the package version; `docs/` is shipped | Each feature file exports a `register…` function, wired into its area's `index.ts` (`registerTools`, `registerResources`, `registerPrompts`), which `server/index.ts` calls from `createServer()` |
| `filesystem` | `index.ts` is the stdio entry point (argv → allowed directories, `main()`); `server.ts` exports `createServer(allowedDirectories)`; `lib.ts` holds the file operations and path validation, with the allow-list passed in rather than held globally; `path-utils.ts`, `path-validation.ts` and `roots-utils.ts` are focused helpers, and `pinned-directory.ts` runs the write operations inside their verified directory; `version.ts` reads the package version | Inline in `createServer()` in `server.ts`, with `server.registerTool(...)` |
| `memory` | `index.ts` holds the `KnowledgeGraphManager`, `createServer(memoryFilePath)` and the stdio `main()`; `version.ts` reads the package version | Inline in `createServer()`; the resource and its subscription handlers are exported `register…` functions in the same file |
| `sequentialthinking` | `index.ts` holds `createServer()` and the stdio `main()`; `lib.ts` holds `SequentialThinkingServer`, the logic; `version.ts` reads the package version | Inline in `createServer()` |
Three things about `everything` that the table cannot hold:
- **`server/index.ts` exports `createServer()`**, which returns
`{ server, cleanup }`. Every transport file calls it, once per stdio process
or once per HTTP session. A tool that depends on what the client can do
(roots, sampling, elicitation) is registered through
`registerConditionalTools`, which runs after `initialize`, not through
`registerTools`.
- **`docs/` is part of the server, not only documentation.** The build copies
it into `dist/docs`, every file in it is served as a static resource, and
`docs/instructions.md` is returned as the server's `instructions`. A file
added there becomes a resource a client can list.
- **Its own maps are `src/everything/docs/structure.md` and
`src/everything/docs/extension.md`.** A change to the server's files updates
`structure.md`, and `src/everything/AGENTS.md` holds the rules that apply
only inside that directory.
**No server starts on import.** Each one builds its server in a
`createServer(...)` factory, and its entry file connects a transport only when
it is the process entry point (an `isEntryPoint()` or `isMainModule()` check
that compares real paths, so the npm bin symlink still starts it). Keep it that
way: a module that binds a port, connects stdio or installs a signal handler at
import cannot be driven in-process by the tests. `/testing` covers the
in-process harness.
## The Python servers
`fetch`, `git` and `time` are independent `uv` projects with the same layout:
```
src/<server>/
├── pyproject.toml dependencies, the console script, pytest and coverage config
├── uv.lock, .python-version
├── src/mcp_server_<name>/
│ ├── __init__.py main(): the command-line flags, then asyncio.run(serve(...))
│ ├── __main__.py python -m mcp_server_<name>
│ └── server.py everything else
└── tests/ pytest suite, driving serve() in-process
```
`server.py` holds the Pydantic input models, the functions that do the work,
and `serve()`. `serve()` constructs the `Server`, declares the tools (and, in
`fetch`, the prompts) with the `@server.list_tools()` / `@server.call_tool()`
decorators inside its body, and then runs it over stdio. So a new tool is a
set of edits in `server.py`: its input model, its entry in `list_tools`, and
its branch in `call_tool`. In `git` and `time` there is a fourth: tool names
are members of an enum (`GitTools`, `TimeTools`) that `list_tools` and
`call_tool` both dispatch on, so the new name is added there first. `fetch`
has one tool and no enum. The `Server` object is local to `serve()` and not
importable.
## Where to put a new file
| It is… | It goes in |
| --- | --- |
| A tool, resource or prompt for `everything` | Its own kebab-case file in `tools/`, `resources/` or `prompts/`, exporting a `register…` function, wired into that directory's `index.ts` |
| A transport for `everything` | `src/everything/transports/`, plus a `case` in `src/everything/index.ts` and a `start:…` script |
| A tool for `filesystem`, `memory` or `sequentialthinking` | A `server.registerTool(...)` call inside that server's `createServer()` (`server.ts` in `filesystem`, `index.ts` in the other two); the logic it calls goes in `lib.ts` (or the class it extends) |
| A helper module for `everything` | A kebab-case `.ts` file in the feature area it supports, beside its users (`server/logging.ts`, `server/roots.ts`, `resources/session.ts`), imported with the `.js` extension |
| A helper module for `filesystem`, `memory` or `sequentialthinking` | A kebab-case `.ts` file at the workspace root, imported with the `.js` extension |
| A tool for a Python server | `server.py`: the tool-name enum member (`git`, `time`), the model, the `list_tools` entry, the `call_tool` branch |
| A command-line flag for a Python server | `__init__.py`, passed into `serve()` |
| A test | `/testing` |
| Root tooling (a guard, a release helper) | `scripts/<name>.mjs`, with a sibling `<name>.test.mjs` when it has logic worth testing; shared helpers in `scripts/lib/` |
| A design document | `docs/` |
| A procedure for agents | `.claude/skills/<name>/SKILL.md`, with a row in the Skills index |
A new server directory is not on this list: the repository does not accept new
servers (`CONTRIBUTING.md`).
## What a new file is checked against
A TypeScript file in a new location is still inside the gate, because two
guards enumerate tracked files rather than trusting a glob:
`verify:typecheck-coverage` fails when a tracked `.ts` file is in no project
that `typecheck` runs, and `verify:format-coverage` fails when a tracked source
file matches no `prettier --check` glob. Both run in `npm run validate:guards`.
If one fires on a file you added, the fix is to bring the file into the
existing config, not to exclude it.
When a file or directory is added, removed, renamed or given a different
purpose, every entry that describes it changes in the same PR (`AGENTS.md`,
**Maintenance rules**): the root `README.md`, the server's own `README.md`,
the tree in `AGENTS.md`, and for `everything`, `docs/structure.md`.
© modelcontextprotocol · Apache-2.0 · modelcontextprotocol/servers