Skip to content

[WIP] Add M365 integration support to Project Memory MCP server - #3

Closed
Santi-49 with Copilot wants to merge 1 commit into
mainfrom
copilot/add-m365-integration-support-again
Closed

[WIP] Add M365 integration support to Project Memory MCP server#3
Santi-49 with Copilot wants to merge 1 commit into
mainfrom
copilot/add-m365-integration-support-again

Conversation

Copilot AI commented Mar 29, 2026

Copy link
Copy Markdown
Contributor
  • Add M365Ref, SyncSource, SyncState models to src/models.py; update RefsIndexEntry with m365_refs
  • Add SYNC_YAML_TEMPLATE to src/templates.py
  • Extend src/filesystem.py: M365 ref parser, _sync.yaml protection, sync state methods (get_sync_state, update_sync_state, add_sync_source, list_projects_due_for_sync, list_projects_due_for_synthesis, resolve_m365_ref), extend get_refs_for
  • Register 6 new tools + memory://m365 resource in src/server.py; update get_project_context deep mode
  • Add generate_m365_guide() to src/guide.py
  • Add tests: TestSyncState, TestM365RefParser, TestRefsIndexM365, TestResolveM365Ref, TestListDueForSync, TestM365GuideResource
Original prompt

Build Prompt — M365 Integration Layer (Phase 4a + 4b)

What you are adding

Extend the existing Project Memory MCP server with M365 integration support.
This covers three things:

  1. _sync.yaml — new per-project file for M365 source registration and sync watermarks
  2. Four new sync state tools on the memory MCP server
  3. resolve_m365_ref tool for resolving M365 references from project files
  4. Extended _refs-index.json parsing to index M365 reference tokens
  5. Updated reference parser to handle the new [tm:], [ol:], [sp:] syntax

Critical design constraint — M365 optional

The memory MCP server must work perfectly without any M365 connection.
M365 is an optional enhancement layer, not a dependency.

Rules:

  • No tool may fail or error because M365 is unavailable
  • No tool may import or depend on any M365 library
  • Tools that would benefit from M365 data return what they have locally
    and include a m365_available: false flag in the result when M365
    is not reachable — they never block or raise
  • _sync.yaml files are valid and useful even with no M365 configured
  • A project with no _sync.yaml is fully functional — treat missing
    _sync.yaml as "no M365 sources configured", not as an error

Part 1 — _sync.yaml schema

Location

projects/{slug}/_sync.yaml

Full schema

# Auto-managed by sync pipeline. Do not edit manually.
# Missing file = no M365 sources configured for this project. Not an error.

last_sync: null                    # ISO 8601 UTC datetime or null if never synced

sources:
  teams:
    - id: "teams-general"          # stable kebab-case slug, used in [tm:id] refs
      label: "General channel"     # human-readable, used in summaries
      channel_id: "19:abc123..."   # M365 Teams channel ID
      last_processed_at: null      # ISO 8601 UTC datetime or null
      last_message_id: null        # Teams epoch timestamp string or null (watermark)
      unprocessed_count: 0         # estimated unprocessed messages since watermark
      enabled: true                # false = skip this source in pipeline runs

  outlook:
    - id: "outlook-internal"
      label: "Internal thread"
      folder_id: "AAMkAGI2..."     # Outlook folder ID
      last_processed_at: null
      last_message_id: null        # Outlook message ID string (watermark)
      unprocessed_count: 0
      enabled: true

  sharepoint:
    - id: "sp-contracts"
      label: "Contracts library"
      site_url: "https://company.sharepoint.com/sites/acme"
      library: "Contracts"         # SharePoint document library name
      last_processed_at: null
      last_modified_etag: null     # SharePoint ETag for change detection (watermark)
      unprocessed_count: 0
      enabled: true

pipeline:
  correspondence_frequency: daily    # daily | weekly | manual
  knowledge_frequency: weekly        # daily | weekly | manual
  last_knowledge_synthesis: null     # YYYY-MM-DD or null
  next_knowledge_synthesis: null     # YYYY-MM-DD or null (computed on update)
Rules
_sync.yaml is auto-managed. Add it to the is_manifest() family — block direct writes via write_file. Only writable via sync state tools.
Missing _sync.yaml is not an error anywhere in the server. All sync state tools return {"result": null, "warnings": ["No _sync.yaml found"]}.
id fields within each source list must be unique within their type (two teams sources cannot share an id, but teams and outlook can).
id values are kebab-case. Enforce on add_sync_source.
enabled: false sources are preserved in the file but skipped by list_projects_due_for_sync.
Part 2 — Reference syntax extension
New token types
Extend the existing reference parser in src/filesystem.py to recognise three new token types in Markdown file bodies:

Code

[tm:source-id]                   Teams channel reference
[tm:source-id/message-id]        Specific Teams message
[ol:source-id]                   Outlook folder/thread reference
[ol:source-id/message-id]        Specific email message
[sp:source-id]                   SharePoint library root
[sp:source-id/path/to/file.pdf]  Specific SharePoint file
Parsing rules
Square bracket syntax [type:...] — distinct from existing [[link]] syntax
source-id is the id field from _sync.yaml sources, not a raw M365 ID
Everything after the first / in the ref is the optional path/message-id
Refs with unregistered source IDs produce a warning (same pattern as unresolved @refs) — file is still written
The parser must not choke on malformed refs — skip and warn, never raise
_refs-index.json extension
Add a new m365_refs array to each file entry alongside existing refs, tags, links:

JSON

{
  "entries": {
    "projects/acme-portal/knowledge/contract-summary.md": {
      "path": "projects/acme-portal/knowledge/contract-summary.md",
      "refs": ["john-doe", "acme-corp"],
      "tags": ["legal"],
      "links": ["acme-portal"]...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

Created from [VS Code](https://code.visualstudio.com/docs/copilot/copilot-coding-agent).

<!-- START COPILOT CODING AGENT TIPS -->
---

📱 Kick off Copilot coding agent tasks wherever you are with [GitHub Mobile](https://gh.io/cca-mobile-docs), available on iOS and Android.

Copilot stopped work on behalf of Santi-49 due to an error March 29, 2026 11:12
Copilot AI requested a review from Santi-49 March 29, 2026 11:12
@Santi-49 Santi-49 closed this Mar 29, 2026
@Santi-49
Santi-49 deleted the copilot/add-m365-integration-support-again branch March 29, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants