Skip to main content

project-structure

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.

ソース情報

リポジトリ
modelcontextprotocol/servers
ソースの最終更新活動
2026年10月4日 23:05
検出された SKILL.md の言語
英語
スター
91,295
フォーク
11,788

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
2 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
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; `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`.
GitHubで見る