Files
cowork-local/docs/project-context-mcp-team-guide.md
T
thanhnv e0ab653a61
CI / test (pull_request) Canceled after 0s
feat(mcp): add project knowledge search
Complete the Project Context MCP MVP with the second read-only tool,
search_project_knowledge, so an agent can go from an issue's requirement
to the project documents that explain it, with citable evidence.

Retrieval reuses what Cowork already owns instead of adding a vector DB,
an embedding pipeline, or a new RAG framework:
- core/projects.py already defines a project's knowledge as the files at
  its workspace root, so that folder is the entire corpus. Isolation is
  structural, not a filter applied after the fact.
- core/doc_extract.py already extracts docx/pptx/xlsx/pdf/text, so the
  provider inherits format support and duplicates none of it.

Security properties:
- Read-only. The workspace root resolves from the identity, never from
  the request; project_id only verifies scope and is never routing
  authority. Symlinks escaping the workspace are dropped.
- Policy runs before provider resolution; target and access resolution
  are separate seams so a pilot local root can become an on-behalf-of
  served backend without changing the tool or the provider.
- Bounded output per detail mode with cursor pagination; no unlimited
  mode. Backend failures map to safe errors that leak no internals.

score is honest term coverage, not a fabricated similarity; the upgrade
path is documented on _score_chunk.

Adds tests/test_project_context_knowledge.py (40 tests) and
tests/test_project_context_e2e.py, which proves the two tools compose:
issue -> requirement -> related knowledge -> evidence.
2026-09-04 10:46:41 +09:00

4.3 KiB

Project Context MCP — hướng dẫn làm song song

Mục tiêu: hoàn thiện ba tool trên cùng một server project_context. Không tạo server, registry, policy hay error envelope mới. Shared skeleton đã khóa sẵn thứ tự an toàn:

validate input → policy ALLOW → resolve provider → gọi upstream → validate output

Chia việc

Người Tool Chỉ sửa Branch đề xuất
Member A get_project_issue_context tools/issue_context.py, providers/issue.py, test riêng feat/mcp-issue-context
Member B search_project_knowledge tools/knowledge_search.py, providers/knowledge.py, test riêng feat/mcp-knowledge-search
Member C get_project_change_context tools/change_context.py, providers/change.py, test riêng feat/mcp-change-context

Trước khi gửi task, thay Member A/B/C bằng username thật trên ba issue. Mỗi người không sửa foundation.py, registry.py, runtime.py, server.py hoặc file của người khác. Nếu shared contract cần đổi, mở một PR nhỏ riêng và để cả ba người rebase sau khi PR đó merge.

Bắt đầu trong 5 phút

  1. Chạy python --version và xác nhận Python 3.11+ như baseline trong requirements.txt.

  2. Tạo branch từ commit template chứa tài liệu này sau khi PR template merge.

  3. Đọc input/output model trong module tool được giao; không thêm field riêng của Gitea/Jira/Redmine.

  4. Implement provider read-only trong module providers/<tool>.py; credential chỉ lấy sau policy ALLOW.

  5. Thêm test happy, invalid, not-found, timeout, DENIED với resolver.calls == 0, output sai schema, truncation/cursor và source mở được có revision.

  6. Chạy:

    python -m pytest tests/test_project_context_mcp_template.py tests/test_project_context_<tool>.py -q
    

    Lệnh trên chạy trực tiếp từ root repo cowork_local; tests/conftest.py đã thiết lập import path.

Definition of Done của từng người

  • Tool trả đúng schema, có project_id và source gồm system, url, revision, retrieved_at.
  • Provider-neutral: đổi Gitea sang GitHub/Jira/Redmine không đổi schema hay tool name.
  • Sai project bị DENIED trước khi resolve credential và trước mọi upstream call.
  • Không log/return token; lỗi ngoài dự kiến không lộ exception; read không có side effect.
  • Output lớn có truncated, returned, remaining, next_cursor; không cắt im lặng.
  • Test riêng pass, test shared pass, PR chỉ chạm đúng vùng sở hữu trong bảng trên.

Chạy server sau khi provider đã cấu hình

COWORK_MCP_ACTOR_ID=<actor> \
COWORK_MCP_ORG_UNIT=<org> \
COWORK_MCP_CUSTOMER=<customer> \
COWORK_MCP_PROJECT=<project> \
GITEA_BASE_URL=<https://gitea.example> \
GITEA_TOKEN=<service-account-token> \
PROJECT_CONTEXT_REPO_MAP='{"<org>/<customer>/<project>":"<owner>/<repo>"}' \
PROJECT_CONTEXT_KNOWLEDGE_ROOT=<path chứa 1 thư mục con cho mỗi project> \
python -m cowork_local.mcp_servers.project_context_server

Target map ưu tiên key đủ org_unit/customer/project; key project chỉ là legacy fallback cho pilot env cũ. Không commit giá trị môi trường hoặc credential. Cowork kết nối bằng stdio với command Python và args -m cowork_local.mcp_servers.project_context_server.

Knowledge search (search_project_knowledge)

Corpus là workspace của chính project: PROJECT_CONTEXT_KNOWLEDGE_ROOT/<identity.project> — cùng định nghĩa "knowledge" mà core/projects.py đã dùng (file ở workspace root), và tái sử dụng core/doc_extract.py để đọc docx/pptx/xlsx/pdf/text. Không thêm vector DB, embedding pipeline hay RAG framework mới.

  • Thư mục được resolve từ identity, không bao giờ từ project_id trong request; project_id chỉ dùng để verify scope. Symlink trỏ ra ngoài workspace bị loại.
  • score là term-coverage (lexical), không phải similarity giả. Upgrade path: thay riêng _score_chunk bằng semantic ranker khi corpus đủ lớn.
  • Bound theo detail: summary 3 kết quả / 200 ký tự, standard 5 / 600, full 10 / 1200. top_k chỉ thu hẹp, không nới rộng. Không có unlimited mode.