ReMe/reme2/mcp/server.py
huangsen 8465f6d06e ```
docs(protocol): add typed edge link protocol documentation

Add comprehensive documentation for the link protocol supporting
typed edges in body text. This includes specification for three
legal inline forms (bare wikilink, line-level Dataview,
inline-bracketed Dataview), predicate syntax rules, and the
machine-managed Relations section convention for organizing
discovered edges.

fix(memory): update path reference from vault_root to working_dir

Change the memory_create operation's path anchoring from
vault_root to working_dir to maintain consistency with the
current working directory configuration.

refactor(components): remove edge_extractor module and simplify parsing

Remove the edge_extractor component module entirely and
inline edge extraction logic directly into LinkedFileParser
using parse_wikilinks utility. This simplifies the architecture
by eliminating the separate edge extraction component and
delegating edge discovery to the maintainer's enrichment operations.

feat(parser): update parse method signature and simplify edge extraction

Modify LinkedFileParser to return (FileNode, list[FileChunk])
tuple instead of ParsedFile, remove dependency on BaseEdgeExtractor,
and implement direct wikilink parsing from body text only.
```
2026-05-11 19:45:53 +08:00

74 lines
2.5 KiB
Python

"""vault MCP server entry point.
Usage:
python -m reme2.mcp.server [config=path/to/yaml] [service.transport=stdio]
python reme2/mcp/server.py [config=path/to/yaml] [service.transport=stdio]
By default loads `reme2/config/service.yaml` and starts the
ReMe2 application with the MCP service registered.
Env vars:
VAULT_PATH — override vault watch path (overrides config + cli args).
"""
import os
import sys
from pathlib import Path
# Make this work whether invoked as `python -m reme2.mcp.server` (repo
# root already on sys.path) or `python reme2/mcp/server.py` (only this
# file's dir is on sys.path — without this, `import reme2.mcp.steps`
# would fail with ModuleNotFoundError).
_REPO_ROOT = Path(__file__).resolve().parents[2]
if str(_REPO_ROOT) not in sys.path:
sys.path.insert(0, str(_REPO_ROOT))
from dotenv import load_dotenv # noqa: E402
# Load .env from repo root before anything else touches env vars
# (embedding/llm clients read them at construction time).
load_dotenv(_REPO_ROOT / ".env")
# Eagerly import side-effect modules so all @R.register() decorators run
# before Application introspects the registry.
import reme2 # noqa: E402,F401
import reme2.mcp.steps # noqa: E402,F401
import reme2.memory # noqa: E402,F401 -- registers retriever + maintainer
import reme2.memory.ingestor # noqa: E402,F401
import reme2.memory.summarizer # noqa: E402,F401
import reme2.component.service.mcp_service # noqa: E402,F401
from reme2.application import Application # noqa: E402
from reme2.config import parse_args # noqa: E402
_DEFAULT_CONFIG = str(_REPO_ROOT / "reme2" / "config" / "service.yaml")
def main() -> None:
argv = list(sys.argv[1:])
if not argv or argv[0].startswith("config=") or "=" in argv[0]:
argv.insert(0, "start")
if not any(a.startswith("config=") for a in argv[1:]):
argv.insert(1, f"config={_DEFAULT_CONFIG}")
vault_path = os.environ.get("VAULT_PATH")
if vault_path:
argv.append(f"components.file_store.default.working_dir={vault_path}")
argv.append(f"components.file_store.default.db_path={vault_path}/.reme")
argv.append(f"service.sidecar_info_path={vault_path}/.reme/sidecar.json")
sidecar_port = os.environ.get("VAULT_HTTP_PORT")
if sidecar_port:
argv.append(f"service.sidecar_http_port={sidecar_port}")
action, config = parse_args(*argv)
if action != "start":
raise SystemExit("reme2.mcp.server only supports the 'start' action")
app = Application(**config)
app.run_app()
if __name__ == "__main__":
main()