npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@joshluedeman/mcp-yammer-engage

v0.1.1

Published

MCP server that gives MCP-compatible assistants controlled read/write access to Viva Engage (Yammer) under the signed-in user's delegated identity.

Downloads

213

Readme

mcp-yammer-engage

CI

A local TypeScript MCP server that gives MCP-compatible assistants controlled read/write access to Viva Engage / Yammer under the signed-in user's delegated Microsoft identity.

Status: v0.1.0 — all 5 phases complete. Auth, read tools, safe writes, community-management helpers, and gated moderation are implemented and tested. See CHANGELOG.md for details. Phase 0.5 spike script (scripts/spike.ts) must be run against a real tenant to confirm the exact Yammer scope set required for your tenant.

What you can do (once complete)

  • Authauth_login, auth_status, auth_clear_tokens. Device-code flow returns the verification URL and user code as structured tool data so the assistant can relay it.
  • Read — list networks, communities, and recent posts you can already see. Read full conversation threads. Search messages. Read your feed.
  • Write — post and reply with a preview → confirmation-token → commit flow so nothing leaves your machine without explicit approval.
  • Helpersengage_find_unanswered_questions, engage_get_community_health, engage_summarize_recent_activity. The server returns structured data; the assistant writes any prose.
  • Moderation (gated)engage_like_message, engage_unlike_message, engage_delete_message. Delete requires a reason and an updatedAt-bound confirmation token so an edit between preview and commit invalidates the token. 403/404 maps to UNSUPPORTED_CAPABILITY.

Tool inventory

| Phase | Tools | |---|---| | Auth | auth_login, auth_status, auth_clear_tokens | | Capability | engage_get_capabilities | | Read | engage_get_networks, engage_list_communities, engage_get_community, engage_get_community_messages, engage_get_thread, engage_search_messages, engage_get_feed | | Write | engage_post_message, engage_reply_to_thread | | Helpers | engage_find_unanswered_questions, engage_get_community_health, engage_summarize_recent_activity | | Moderation | engage_like_message, engage_unlike_message, engage_delete_message |

Important limitation: home network only

Microsoft's Yammer REST and Graph APIs only expose your home network — the primary organization tied to your sign-in. External networks (Engage communities hosted by other tenants) are not accessible via API and are explicitly out of scope.

Prerequisites

  • Node.js ≥ 18.17
  • A Microsoft work/school account with Viva Engage access
  • An MCP-compatible assistant (Github Copilot, Claude Desktop, etc.)

Azure App Registration (one-time, ~10 minutes)

You register your own Entra ID public-client app. Nobody else can use it; your tokens stay on your machine.

Microsoft-internal users: the corp tenant requires a Service Tree ID to create a new App Registration. If you don't have one and just want to try the server, see § Reusing an existing Microsoft public client ID below — you can skip this section entirely.

  1. Sign in to portal.azure.com with your work/school account.
  2. App registrations → New registration:
    • Name: mcp-yammer-engage (or anything).
    • Supported account types: Accounts in this organizational directory only (single tenant) is usually correct.
    • Redirect URI: Platform = Public client/native (mobile & desktop), URI = http://localhost.
  3. Click Register, then on the overview page copy:
    • Application (client) ID → goes in AZURE_CLIENT_ID
    • Directory (tenant) ID → goes in AZURE_TENANT_ID
  4. API permissions → Add a permission → APIs my organization uses (or All APIs) → search for YammerDelegated permissions → check at minimum:
    • user_impersonation
    • Plus, if your tenant requires them (Phase 0.5 spike will tell us):
      • Community.Read.All
      • EngagementConversation.ReadWrite.All
      • Storyline.ReadWrite.All
  5. Click Add permissions. If your tenant requires admin consent, submit an approval request — the assistant will surface a PERMISSION_DENIED error with consent guidance on first auth.

Reusing an existing Microsoft public client ID

If you can't (or don't want to) create your own App Registration — typical for Microsoft-internal users without a Service Tree ID — you can point MSAL at one of Microsoft's existing public-client apps. Your tokens are still issued to you; you just borrow someone else's client manifest.

| App | Client ID | |---|---| | Microsoft Azure CLI | 04b07795-8ddb-461a-bbee-02f9e1bf7b46 | | Microsoft Azure PowerShell | 1950a258-227b-4e31-a9cf-717495945fc8 | | Microsoft Graph PowerShell | 14d82eec-204b-4c2f-b7e8-296a70dab67e |

Set those in your .env (or MCP client env block):

AZURE_CLIENT_ID=04b07795-8ddb-461a-bbee-02f9e1bf7b46
AZURE_TENANT_ID=<your-tenant-guid>   # or "organizations"

Caveats:

  • Whether https://api.yammer.com/user_impersonation is exposed by any given Microsoft public client depends on its current manifest. The Phase 0.5 spike (npm run spike) is the fastest way to find out — it will either acquire a Yammer token or fail with a consent/scope error you can act on.
  • You cannot edit the redirect URIs or requested permissions on a client you don't own. If a needed Yammer scope (e.g. Community.Read.All) isn't already granted on that app, this path won't work and you'll need a real App Registration via Service Tree (Option B) or a dev tenant (Option C).
  • Audit logs in your tenant will attribute the activity to the public client (e.g. "Microsoft Azure CLI"), not to a named app. That's fine for personal use, less fine if you want clean attribution.

If the public-client path doesn't work for your tenant, fall back to the App Registration steps above.

Install

The fastest path — no clone, no build, just run via npx (requires Node 20+):

npx -y @joshluedeman/mcp-yammer-engage

That's the same command you'd put into your MCP client's command field (see § Add to your MCP client below).

Or if you'd rather work from source:

git clone https://github.com/JoshLuedeman/engage-mcp.git
cd engage-mcp
npm install
npm run build

Configure (optional, ~10 seconds)

The server boots with zero configuration — by default it uses the Microsoft Azure CLI public client id and lets MSAL resolve your tenant from whichever account you sign in with. You can stop here and just run it.

If you want to lock in specific values (e.g. for clean tenant attribution in audit logs), either:

npm run setup     # interactive: detects your tenant from
                  # dsregcmd / az CLI, writes .env (gitignored)

or copy .env.example to .env and fill in the values by hand. See § Reusing an existing Microsoft public client ID for the trade-offs of the default client id.

Run

This server speaks MCP over stdio. You normally do not launch it directly — instead, configure your MCP client to start it. A direct run is mostly useful for the MCP Inspector.

npm start

Auth flow (device-code, recommended)

On first call to any tool that needs network access, the server will return a tool result containing a device code and verification URL. Open the URL, enter the code, sign in. The token is cached locally (encrypted) so subsequent runs are silent until refresh fails.

To clear cached tokens: call the auth_clear_tokens tool, or delete the cache directory printed by auth_status.

Add to your MCP client

GitHub Copilot CLI

Copilot CLI manages MCP servers via the interactive /mcp command — you don't hand-edit a config file. Inside a Copilot CLI session:

/mcp

Choose Add server, then provide:

  • Name: viva-engage (or anything you'll remember)
  • Type: stdio
  • Command: npx -y @joshluedeman/mcp-yammer-engage (or, if running from source: node C:\path\to\engage-mcp\dist\server.js)
  • Env: leave empty (defaults to Azure CLI public client + MSAL multi-tenant resolution — see § "Reusing an existing Microsoft public client ID"). If you want clean attribution, add AZURE_CLIENT_ID and AZURE_TENANT_ID here.

Verify it loaded with /env (look for the server name under "MCP servers"), then try one of the read tools, e.g.: "List my Engage communities." The first call triggers device-code login — open the URL it prints, paste the code, sign in. After that, calls are silent until the cached token expires.

Claude Desktop, Cursor, and other config-file clients

Add this to your client's MCP config (typically claude_desktop_config.json or equivalent — check your client's docs for the exact path):

{
  "mcpServers": {
    "viva-engage": {
      "command": "npx",
      "args": ["-y", "@joshluedeman/mcp-yammer-engage"]
    }
  }
}

Or, if you'd rather pin to a local clone:

{
  "mcpServers": {
    "viva-engage": {
      "command": "node",
      "args": [
        "C:\\Users\\<you>\\path\\to\\engage-mcp\\dist\\server.js"
      ]
    }
  }
}

The env block is optional — the server runs with zero config. Add AZURE_CLIENT_ID / AZURE_TENANT_ID there if you want non-default values without a .env file.

On Windows, if npx resolution is flaky from your MCP client, prefer the explicit node-and-path form above.

Security model (short version)

  • Delegated identity only. No shared service account, no embedded secret. The server only sees what you can already see.
  • Tokens are stored encrypted (AES-256-GCM) under your user's local cache directory, with the key in a sibling file (mode 0600). Protects against casual file inspection; does not protect against a local-user attacker on the same machine.
  • Every write tool requires a two-step preview → confirmation token → commit flow. The token binds the exact payload, target, and account, and is single-use with a short TTL.
  • Destructive operations (delete) additionally require a reason string and the exact message id, and the confirmation token is bound to the fetched message's updatedAt so an edit-in-flight invalidates it.
  • All write attempts are recorded in a local append-only audit log (audit.log, JSON Lines) — bodies hashed, never logged in full.

License

MIT — see LICENSE.

When to use Engage tools (vs. other MCP servers)

  • Reach for engage-mcp when the question is about Viva Engage communities, posts, threads, feeds, or activity — not when the question is about Outlook mail, Teams chats, SharePoint documents, or other Microsoft 365 surfaces (use the M365/Graph MCP for those).
  • For unanswered-question scans across a community, prefer engage_find_unanswered_questions; for cross-community pulse checks prefer engage_summarize_recent_activity (it's the one with bounded concurrency and partial-result tolerance).
  • The server never generates prose — it returns structured data and lets your assistant compose. If you want a written digest, ask the assistant to summarize the data it received back from engage_summarize_recent_activity or engage_get_community_health.

Manual smoke checklist

See scripts/manual-smoke.md for the end-to-end checklist to run against a real tenant after upgrading or making infrastructure changes.