Skip to main content

Sync Microsoft Teams 1:1 + group chat messages into EvolutionDB long-term memory.

Project description

evolutiondb-teams-sync

Stream Microsoft Teams 1:1 and group chat messages into EvolutionDB so they become part of the long-term memory the MCP server already exposes to Claude, ChatGPT, Gemini, and Copilot. After running the sync, "what did Ahmet say last week about the release plan" becomes a normal search_memory call from any MCP-aware client.

Channel messages, meeting transcripts, and call recordings are out of scope. They need higher-privilege Graph permissions that require tenant admin consent — this client deliberately stays inside scopes a user can self-consent to.


Before you enable this

A few non-technical things to settle first:

  • Other people's words land in the memory too. A 1:1 chat or group chat captures everyone's messages, not just yours. Some workplaces treat external archiving of colleagues' messages as a policy violation independent of the technical access controls. This is an HR / legal question, not a permissions question.
  • Microsoft sees the request. Every Graph API call is logged against your account in the tenant audit log. Your IT team can see that an app is reading your chats.
  • Token revocation is one click. You can pull the plug at any time from https://myaccount.microsoft.com/applications — the sync daemon's next call gets a 401 and stops.

If those are fine in your environment, continue.


One-time setup

1. Register an Entra ID app

  1. Open https://portal.azure.comMicrosoft Entra IDApp registrationsNew registration. (Microsoft renamed Azure Active Directory to Microsoft Entra ID in 2023; legacy docs that say "Azure AD" mean the same thing.)
  2. Name: EvolutionDB Memory Sync (or anything you like).
  3. Supported account types: Accounts in this organizational directory only (single tenant) is enough.
  4. Redirect URI: leave blank — the device-code flow doesn't use one.
  5. After registration, open Authentication → enable Allow public client flows → save.
  6. Open API permissionsAdd a permissionMicrosoft GraphDelegated permissions → tick:
    • Chat.Read
    • User.Read
    • offline_access
  7. Copy the Application (client) ID and the Directory (tenant) ID from the app's Overview page.

None of these scopes require tenant admin consent — you can grant them to yourself the first time you log in.

2. Configure the sync

cd client/teams-sync
cp .env.example .env
$EDITOR .env   # paste AZURE_TENANT_ID and AZURE_CLIENT_ID

3. Install the package

From PyPI (recommended once a release is up there):

pip install evolutiondb-teams-sync

Or from source if you're working on the code:

pip install -e .

4. Log in once

python -m teams_sync.sync --auth

The CLI prints a Microsoft login URL and a short code. Open the URL, paste the code, sign in with your work account, approve the permissions. The refresh token lands in ~/.evosql/teams_token_cache.json (mode 0600).


Daily use

# One-shot, last 24 hours (uses the per-chat watermark on later runs):
python -m teams_sync.sync --once

# Daemon, polls every 10 minutes:
python -m teams_sync.sync --interval 600

# Verify auth + scopes without writing to the DB:
python -m teams_sync.sync --once --dry-run

--since 1h | 24h | 7d | 30m controls how far back the first run on a chat goes. After that, the per-chat watermark in EvolutionDB takes over, so reruns never re-ingest the same message.


Running in Docker

The repo's demo compose file ships a teams-sync service behind a profile so it doesn't start with the rest of the demo:

# First-run device-code login (runs once, cleans up after itself):
docker compose -f docker-compose.demo.yml --profile teams \
    run --rm teams-sync --auth

# Bring the daemon up:
docker compose -f docker-compose.demo.yml --profile teams up -d teams-sync

The token cache lives on a named volume (teams_sync_state), so container recreates don't force you to log in again.


How a synced message looks in memory

Each Teams message becomes one memory row in the mcp_mem store (or whatever TEAMS_MEMORY_STORE points to):

{
  "fact":         "Ahmet Yılmaz: Stagingde regression testi başarısız",
  "source":       "teams",
  "kind":         "chat",
  "chat_id":      "19:meeting_…",
  "chat_name":    "Backend standup grubu",
  "chat_type":    "group",
  "message_id":   "1715064862123",
  "sender":       "Ahmet Yılmaz",
  "sender_id":    "<aad-object-id>",
  "text":         "Stagingde regression testi başarısız",
  "created_at":   "2026-05-07T09:14:22Z",
  "modified_at":  "2026-05-07T09:14:22Z",
  "tags":         ["teams", "chat", "Backend standup grubu"]
}

Per-chat watermarks live alongside the messages, keyed teams_state_<chat_id>. The store wrapper hides them from message counters and they're filtered out by the MCP search_memory tool because their fact field is empty.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

evolutiondb_teams_sync-0.1.0.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

evolutiondb_teams_sync-0.1.0-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file evolutiondb_teams_sync-0.1.0.tar.gz.

File metadata

  • Download URL: evolutiondb_teams_sync-0.1.0.tar.gz
  • Upload date:
  • Size: 15.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for evolutiondb_teams_sync-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5de02cd681d79a138be3a9e095ec3526f170a90a70182cc3b2f99af579babee5
MD5 37553613001495aed497ac3ba578a750
BLAKE2b-256 45fe18ca4e942d8fecad09d871ad597b5d39030704e37f0ce9cea11d97b2b8d6

See more details on using hashes here.

File details

Details for the file evolutiondb_teams_sync-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for evolutiondb_teams_sync-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 efbb697c83e4e6b6c1d810bdd2a942c405f2de62ecbe2e418a0b956805d89a96
MD5 7ff8ce499d42665b5fc4bee8a9147617
BLAKE2b-256 e89d2d58bbbd4a7bcefca6ca55b8d2a51a45af0224189471f688a7cb2a3a40ed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page