Skip to main content
Glama
mbe24

zaungast

by mbe24

zaungast

CI Docs npm License: Apache 2.0

zaungast (German: someone who watches over the fence without joining in) is a read-only, offline MCP server for Teams — search chats, read conversations, surface trending topics, and find people straight from the local on-disk cache, with no Graph API, no cloud, and no credentials, and token-economical output for coding agents (Claude Code, Claude Desktop, …).

The new Teams client stores your chats in a local on-disk database; zaungast reads a copy of it directly and serves it over MCP, so your agent can pull in Teams context — "what was decided about the release date", "catch me up on a channel I muted", "what's my team been discussing this week" — without you copy-pasting, and without any cloud API.

  • Local & offline — reads the on-disk Teams cache. No MS Graph API, no network calls.

  • No credentials — nothing to log in to, no tokens, no permissions to grant.

  • Read-only & safe — the Teams files are only ever read/copied, never written, locked, or modified. It cannot corrupt your Teams data.

  • Token-economical — every tool returns compact, shaped output, never bulk dumps.

  • Zero-config — auto-discovers the local Teams database; just register and go.

⚠️ Windows & macOS (new Teams / WebView2), Node.js ≥ 22.5. Both use the same Chromium/WebView2 store, so the reader is identical; the local database is auto-discovered on each, or point TEAMS_LEVELDB_DIR at it manually — see requirements. Not affiliated with or endorsed by Microsoft. It reads your own local data on your own machine.

Installation

npx -y zaungast fetches and runs the server, so registering it in your MCP client is the whole install. No environment variables are needed in the common case — the local Teams database is auto-discovered.

Claude Code

Normal case — the Teams database is auto-discovered, so no variables are needed:

claude mcp add zaungast -- npx -y zaungast

Add --scope user to make it available in every project. Verify with claude mcp list (expect zaungast … ✓ Connected), then open a new session.

Only if auto-discovery fails or you have multiple profiles, set TEAMS_LEVELDB_DIR explicitly (the -e flag goes before the --) — see finding the Teams database folder:

claude mcp add zaungast \
  -e TEAMS_LEVELDB_DIR="C:\Users\me\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\EBWebView\WV2Profile_tfw\IndexedDB\https_teams.microsoft.com_0.indexeddb.leveldb" \
  -- npx -y zaungast

Codex

Add to ~/.codex/config.toml (or run codex mcp add zaungast -- npx -y zaungast):

[mcp_servers.zaungast]
command = "npx"
args = ["-y", "zaungast"]
# The Teams database is auto-discovered, so no path is needed. To set or override it,
# delete the "#" below and point it at your …indexeddb.leveldb folder:
# env = { TEAMS_LEVELDB_DIR = "/full/path/to/https_teams.microsoft.com_0.indexeddb.leveldb" }

Claude Desktop / other clients

Add to your client's MCP config (claude_desktop_config.json, .mcp.json, …):

{
  "mcpServers": {
    "zaungast": { "command": "npx", "args": ["-y", "zaungast"] }
  }
}

If you want to set or override a variable, use this form instead:

{
  "mcpServers": {
    "zaungast": {
      "command": "npx",
      "args": ["-y", "zaungast"],
      "env": {
        "TEAMS_LEVELDB_DIR": "/full/path/to/https_teams.microsoft.com_0.indexeddb.leveldb"
      }
    }
  }
}

TEAMS_LEVELDB_DIR is optional — the database is auto-discovered. Set it only if discovery fails or to pin a specific profile. From-source setup and other clients are covered in the installation docs.

Related MCP server: Teams Messenger MCP App

Tools

Tool

What it does

list_conversations

Your Teams sidebar — newest conversations, or filter by kind/participant/title/time.

read_conversation

Browse one conversation's messages in story order (window / date-range / page back).

read_thread

Read one channel reply-chain in full (root + all replies).

get_message

One message in full — complete untruncated body + reactions, by conversation + m:<id>.

search

Full-text search + filters (from, in, kind, mentions_me, has-attachment, date).

list_events

Calendar meetings & appointments (forward window by default); metadata-only, join-URLs never exposed.

list_calls

Call history — 1:1/group calls with direction, duration, missed, and recording pointers.

rank_topics

Rank distinctive/trending topics over a window, vs your baseline, with an example each.

find_person

Resolve a name/nickname to a canonical person + handle, with contact stats.

describe_schema

Recovery tool: propose a field mapping when a Teams update changes the DB layout.

Full reference: tools documentation.

Environment variables

All optional — zaungast works with no configuration. Pass them via your MCP client's env block (as above).

Var

Default

Notes

TEAMS_LEVELDB_DIR

auto-discovered

Absolute path to the …indexeddb.leveldb folder (examples below). Set only if auto-discovery fails, or to pin one profile when you have several.

ZAUNGAST_INCREMENTAL

copy-reuse

Refresh mode: copy-reuse (faster) or reparse (simpler).

ZAUNGAST_DB_DIR

unset

Read a static copy of the database directly (offline analysis); skips discovery and live refresh.

ZAUNGAST_ENGINE

js

Ingest engine: js (built-in, zero-dep), native (require the optional libzaungast-native accelerator; errors if unavailable), or auto (native when available, else JS). See Configuration → Native engine.

TEAMS_LEVELDB_DIR points at the folder ending in .indexeddb.leveldb (the one holding CURRENT, MANIFEST-*, *.ldb/*.log) — not its parent IndexedDB directory:

# Windows
C:\Users\<you>\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\EBWebView\<profile>\IndexedDB\https_teams.microsoft.com_0.indexeddb.leveldb

# macOS
/Users/<you>/Library/Containers/com.microsoft.teams2/Data/Library/Application Support/Microsoft/MSTeams/EBWebView/<profile>/IndexedDB/https_teams.microsoft.com_0.indexeddb.leveldb

<profile> is usually WV2Profile_tfw. Use the full absolute path in JSON configs (e.g. Claude Desktop) — environment placeholders like ~ or %LOCALAPPDATA% aren't expanded there.

Privacy & safety

  • Stays local — no network calls; reads data already on your machine and serves it to your local agent over stdio.

  • Cannot harm Teams — no code path writes to, locks, or memory-maps the Teams directory; only read-and-copy.

  • Images/files are URL-only — chat images live in Teams' cloud behind auth; zaungast notes that an attachment exists but never fetches it and never handles credentials.

More in the privacy & safety docs.

Documentation

Full documentation — tools reference, how it works, configuration, privacy, troubleshooting, and development — lives at https://zaungast.readthedocs.io/.

License

Apache 2.0 © Mikael Beyene. Not affiliated with or endorsed by Microsoft. "Microsoft Teams" is a trademark of Microsoft Corporation; this project only reads your own local data.

Available Tools

6 tools
describe_schemaDescribe / recover schemaA

Inspect the raw Teams IndexedDB stores and PROPOSE a field mapping. Use when tools report the schema is unrecognized (after a Teams update), or to inspect the DB structure. Proposes only — applies nothing; a human verifies the proposal and saves it as a new schema version.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNomax stores to list (default 20)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but description fully covers behavioral traits: it 'inspects' (read-only) and 'proposes only — applies nothing', so no destructive action. Clear about its safe, non-modifying nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with clear front-loading of purpose. Efficient but could be slightly more concise (e.g., parentheses). Still very well structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has one optional parameter and no output schema. Description explains purpose, usage, and behavior adequately. Lacks mention of output format but sufficient for its simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter 'limit' is fully described in the schema (100% coverage). The description adds no additional semantic info beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it inspects raw IndexedDB stores and proposes a field mapping. Distinct from sibling tools which deal with people, conversations, messages, search, and topics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when to use: when schema is unrecognized after a Teams update or to inspect DB structure. Also clarifies it only proposes, not applies, and requires human verification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_personFind a personA

Resolve a name/nickname fragment to a person's canonical name and stable p:handle, with message count and last-contact time. Use when a name is ambiguous or unrecognized, or when you need contact stats or a p:handle. For ordinary filtering, just pass a name substring directly to search/read_messages 'from'/'participant' — don't call this first. Omit query to scan the roster (most-talked-to first).

ParametersJSON Schema
NameRequiredDescriptionDefault
nNodefault 8
queryNoname substring, or a p:handle to expand; omit to scan the roster

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description discloses output fields (canonical name, p:handle, message count, last-contact time) and the scanning behavior ('most-talked-to first' when query omitted). It does not mention any destructive actions, which is appropriate. A slight improvement would be to confirm the tool is read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences: purpose, usage guidelines, and extra behavior. No redundancy. Efficiently front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Without annotations or output schema, the description covers input/output behavior but fails to explain the 'n' parameter. Since 'n' defaults to 8 and caps at 25, its role (number of results?) is not fully clarified. This gap reduces completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and descriptions in schema are decent. The tool description adds value by explaining the behavior of omitting query and the ordering. However, the 'n' parameter is not mentioned in the description, which could be overlooked.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool resolves name fragments to canonical names and p:handles, with contact stats. It distinguishes from siblings by explicitly advising when to use search/read_messages instead.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use (ambiguous name, need contact stats) and when not to (ordinary filtering, use search/read_messages). Provides alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_conversationsList conversationsA

Your Teams sidebar: the newest N conversations (default), or filter by kind/participant/title/time. Note: this reads the LOCAL Teams cache — history is the synced slice on this device, not the full server archive.

ParametersJSON Schema
NameRequiredDescriptionDefault
nNohow many (default 12)
kindNo
queryNomatch conversation title or participant
sinceNoISO date or relative like -7d/-24h
participantNodisplay-name substring of a participant
include_emptyNoinclude 0-message conversations (team roots); off by default

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description warns that it reads the local Teams cache, not the full server archive, which is a critical behavioral trait. With no annotations provided, this disclosure adds value. It does not mention any destructive actions, which is consistent with a read operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences cover purpose, filters, and a critical caveat. Every sentence is meaningful and efficient, front-loading the main function.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description lacks details about the return format or fields, which would help with no output schema. The caveat adds context, but overall completeness is moderate for a tool with 6 parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 83%, so baseline is 3. The description lists filter options but does not add significant detail beyond the schema. It groups parameters but does not clarify formats or defaults beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists conversations with default newest N and filtering by kind/participant/title/time. The verb 'list' and resource 'conversations' are specific, and the tool is distinct from siblings like search or read_messages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for browsing conversations with default and filter options. However, it does not explicitly state when not to use it or compare to alternatives, though sibling tools suggest different purposes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_messagesRead a conversationA

Read one conversation's messages in STORY ORDER (oldest→newest). Target by handle (c:xxxx) or title/participant substring. Page back with the returned older: cursor, or center on a message with around:. Note: this reads the LOCAL Teams cache — history is the synced slice on this device, not the full server archive.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNodefault 40
sinceNo
untilNo
aroundNoa message id (the m:… value from a search hit) to center a window on
cursorNothe older:… value from a previous result, to page back
reactionsNo"full" lists every reactor by name (default shows a capped summary)
conversationYesconversation handle (c:xxxx) or title/participant substring

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses critical behavior: it reads the local Teams cache only, not the full server archive, and explains the story order and pagination mechanisms. This provides complete transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences: first states purpose and order, second explains targeting and pagination, third notes the cache limitation. No unnecessary words, well-organized for quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 7 parameters and no output schema, the description covers key behavioral aspects: targeting, pagination, ordering, and cache limitation. It could mention the limit default (in schema) or time filtering, but is sufficiently complete for a read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 71% (some parameters lack descriptions like 'since' and 'until'). The description adds value beyond the schema by explaining targeting by handle/substring, pagination with cursor, and centering with around. It compensates for missing schema details but doesn't explicitly cover all parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Read' and the resource 'one conversation's messages'. It specifies the story order (oldest→newest) and how to target by handle or substring, distinguishing it from siblings like list_conversations or search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains how to use the tool: target by handle or substring, page back with cursor, center with around. It implies usage for reading a full conversation in order, but lacks explicit comparison to siblings like search or when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

top_topicsTrending topicsA

Distinctive/trending topics over a window (vs your baseline), overall or scoped to a person/conversation. Returns each topic with an exemplar message. Note: this reads the LOCAL Teams cache — history is the synced slice on this device, not the full server archive.

ParametersJSON Schema
NameRequiredDescriptionDefault
nNodefault 8
scopeNo"conversation:<c:handle or title>" or "person:<name or p:handle>"
sinceNoarbitrary window start (ISO or -7d); overrides window
untilNoarbitrary window end (ISO or -1d)
windowNodefault 7d; ignored if since/until given
excludeNowords, or c:/p: handles, to exclude
include_botsNoinclude bot/app senders (excluded by default)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description adds important context by disclosing that it reads the local Teams cache and not the full server archive. However, it does not mention other behavioral traits like whether results are sorted or if pagination is supported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences plus a note, all essential. It is front-loaded with the core purpose and scoping, then adds a critical limitation. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and moderate complexity (7 parameters, none required), the description adequately explains purpose, scoping, and the local cache limitation. It could be improved by mentioning the exemplar message structure but is sufficient for agent selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the description adds limited meaning beyond the schema. It mentions 'window' and 'scope' conceptually but does not elaborate on format or edge cases for the parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns distinctive/trending topics over a window, with scoping to overall, person, or conversation. It distinguishes from sibling tools like read_messages or search by focusing on trending analysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for trending topics and mentions scoping, but lacks explicit guidance on when to use this tool vs alternatives like search or list_conversations. No exclusions or prerequisites are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.2.0
    • First observeddescribe_schema
    • First observedfind_person
    • First observedlist_conversations
    • First observedread_messages
    • First observedsearch
    • First observedtop_topics

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clear and distinct purpose: schema inspection, person resolution, conversation listing, message reading, full-text search, and topic extraction. No overlap in functionality.

Naming Consistency5/5

All tool names use consistent snake_case and follow a verb_noun pattern (describe_schema, find_person, list_conversations, read_messages, top_topics), with 'search' as a minor deviation but still common and predictable.

Tool Count5/5

6 tools is well-scoped for a Teams data access server, covering essential read and analysis operations without being overwhelming or sparse.

Completeness4/5

The tool set covers reading and analyzing local cache data comprehensively (schema, people, conversations, messages, search, topics). Minor gaps include lack of write operations and detailed conversation metadata retrieval, but this aligns with the stated read-only purpose.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that bridges Microsoft Teams and MCP-compatible clients, enabling chat integration, message handling, and advanced search capabilities without REST API endpoints.
    1
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that bridges Microsoft Teams with MCP-compatible clients (LLMs, agentic frameworks, CLI), enabling chat integration, message search, and event streaming without traditional REST API endpoints.
    -
  • A
    license
    A
    quality
    D
    maintenance
    A self-hosted, read-only Slack MCP server that runs locally and provides read-only access to Slack channels, messages, and users via the Slack Web API, with no third-party intermediary.
    7
    MIT
  • A
    license
    C
    quality
    A
    maintenance
    Local-first, read-only MCP server for searching and retrieving cited evidence from archived Telegram chats, including transcripts and media metadata.
    9
    2
    MIT