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
آخر نشاط في المصدر
٢٣ أكتوبر ٢٠٢٦ في ٠٤:٣٩
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٩١٬٦٥٢
التفرعات
١١٬٨٨٠

خيارات التثبيت

يُحدَّد 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, 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`.
عرض على GitHub