本文へ移動
cccskills
無料GitHub で公開

teams

Microsoft Teams access from MeshWeaver — what the shipped Teams integration actually is (a bot people message; it reads and sends NOTHING on a user's behalf), and what reading or sending a user's teams, channels and chats needs — the delegated Graph scopes on the Executive Assistant consent link, the tools on the EA plugin, the consent rules, and the TENANT wall that makes "can you see the client's team?" a different question from "can you see my teams?". Use when someone asks whether an agent can see, read, summarise or post to Teams, when adding Teams scopes or tools, or when a Teams-related answer from an agent has to be checked against what is wired.

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaverスター 12(GitHub 12 + cccskills 0)
連携ツールMicrosoft Teams

実行スコア 未検証

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

/teams — reading and sending Teams on a user's behalf

Measured 2026-09-09 by asking the Executive Assistant on the control instance "can you see my Teams channels, in particular the enterprise client's team?": it answered no, and it was right — then. Since Mail 1.5/1.6 (read, 2026-09-09/10) and Mail 1.7 (post, 2026-09-10) the EA reads a user's own-tenant teams, channels and chats, and posts to them where the deployment sets Teams:AgentSend=Send. This skill records what exists, what the ask needs, and the one wall that no scope can climb.

What exists: a bot, not a reader

MeshWeaver.Teams (MeshWeaver.Plugins, src/MeshWeaver.Teams/) is the Bot Framework channel documented in Doc/AI/TeamsBot: a person messages the bot in Teams, TeamsInboundProcessor finds-or-creates one agent thread per conversation, TeamsReplySender posts the agent's reply back. Its outbound credential is an app-only connector token for api.botframework.com — it can answer in a conversation the bot is part of and nothing else. On the control instance it is inert (Teams:Enabled=false, zero TeamsConversation nodes).

The Executive Assistant (src/MeshWeaver.Mail.MicrosoftGraph/ExecutiveAssistantPlugin.cs) has mail, calendar and Teams tools. Its credential is the delegated one minted by the EA consent link, and that credential is the seam everything below hangs on.

The seam: the EA consent link IS a delegated Graph token

{BaseUrl}/auth/ea/connect sends the user through Microsoft's authorize endpoint with the scope string in EaGraphAuth.Scopes — this repo, memex/Memex.Portal.Shared/Authentication/EaGraphAuth.cs:

Mail.ReadWrite Mail.Send Calendars.ReadWrite
Team.ReadBasic.All Channel.ReadBasic.All ChannelMessage.Read.All Chat.Read
ChannelMessage.Send ChatMessage.Send offline_access

🚨 Widening that string invalidates every stored grant. Entra refuses to redeem a refresh token for scopes the user never consented to (400 invalid_grant), and the consent controller's fast path bounces a user whose credential node exists straight back — so on 2026-09-10 the read scopes landed, the reconnect link "just brought me in", and every Teams call kept failing. EaGraphAuth.Classify now compares the credential's stored Scopes with the constant and reports a mismatch as NotConnected, which hands the user the link AND makes /auth/ea/connect run the dialog. Do not add a scope without that classification in place; ?force=true on the connect link is the manual escape hatch for a portal that predates it.

Add Teams scopes to that string and every user reconnects once; from then on the same GraphServiceClient the plugin already builds reaches /me/joinedTeams, /teams/{id}/channels, /teams/{id}/channels/{id}/messages, /me/chats, /chats/{id}/messages — as the user. Nothing app-only, no new secret, no new token store. That is the whole point of routing it through the EA.

Read

Scope (delegated)Lets the EAAdmin consent
Team.ReadBasic.Alllist the user's teamsuser-consentable
Channel.ReadBasic.Alllist a team's channelsuser-consentable
ChannelMessage.Read.Allread channel messagesadmin consent required
Chat.Readlist and read the user's chatsuser-consentable

Send

Scope (delegated)Lets the EAAdmin consent
ChannelMessage.Sendpost to a channel as the useruser-consentable
ChatMessage.Sendpost in a chat as the useruser-consentable

Re-verify the consent column against the Graph permissions reference before adding a scope — a tenant's consent policy can make any of them admin-only. The Entra sign-in app registration must list the same delegated permissions, or the authorize call fails before the user sees a screen.

🚨 Teams has no draft state. Mail is DraftOnly by design (Email:AgentSend, the human presses Send); a Teams post is immediate and irreversible. The gate is the same shape: Teams:AgentSend defaults to Off, in which PostChannelMessage / ReplyToChannelMessage / SendChatMessage are never handed to the model (and refuse by name when reached directly); Send hands them over, with no per-message confirmation — the boundary Email:AgentSend=Send has too. The scopes are consented regardless of the mode, so flipping the mode later costs nobody a reconnect. The public instance runs Teams__AgentSend: "Send" (its deployment values); the control instance does not.

The three pieces (built 2026-09-09/10)

  1. This repo: the scopes in EaGraphAuth.Scopes plus the stale-grant classification above; the delegated permissions on the app registration (Roland's Entra tenant for the Systemorph portals) are optional under dynamic consent except the admin-restricted ChannelMessage.Read.All.
  2. Plugins repo: the tools on ExecutiveAssistantPlugin — read: ListTeams, ListChannels, ReadChannelMessages, ListChats, ReadChat (every mode); post: PostChannelMessage, ReplyToChannelMessage, SendChatMessage (Teams:AgentSend=Send only). 🚨 A tool exists for the model only when CreateTools() LISTS it — Mail 1.5 shipped the read methods without listing them and the EA answered "not in my toolset" (Plugins#1611).
  3. Plugins repo: src/MeshWeaver.AI/Data/Agent/ExecutiveAssistant.md names the surface, or the agent keeps answering "I have no Teams tool" from its instructions.

🚨 The wall: a client's team lives in the client's tenant

A delegated token is minted by the user's home tenant. A team the user reaches as a guest (B2B) lives in the resource tenant, and Graph does not cross that line on a home-tenant token: /me/joinedTeams does not list guest teams, and the channel endpoints answer 403/404 for them — measured and documented by others (Q&A, Tech Community). So the scopes above make the EA see Systemorph's teams. A client's team (e.g. Globex/Team) needs one of:

  • A token for the client's tenant. Run the same consent flow against login.microsoftonline.com/<tenant-id> (the app registration must be multi-tenant), store the resulting refresh token per (user, tenant), and route calls for that team through it. ChannelMessage.Read.All then needs the client's admin to consent to the Memex app in their tenant — a conversation with the client's IT owner and their security lead, not a setting on our side.
  • The bot, installed in their team. The existing MeshWeaver.Teams bot with resource-specific consent (ChannelMessage.Read.Group) in its manifest, added to the client's team by a team owner. Messages are then PUSHED to /api/teams/messages as they happen; nothing is enumerated. Needs Teams:Enabled on the receiving portal and the client's app-upload policy to allow it.
  • Their export. Ask for a channel export; ingest it as content. No integration at all.

Do not promise "I'll read the client's channel" until one of these exists; the honest answer today is the Graph-visible substitute — the mailbox — which the EA already gives.

Checking what an agent says about Teams

The EA's answer is only as good as its tool list. Before trusting a "no Teams access" or a "connected" claim: get @Agent/ExecutiveAssistant/data/ for the plugins, then read ExecutiveAssistantPlugin.cs for the tools actually exposed, then EaGraphAuth.Scopes for what the token can carry. All three moved independently in the past; the doc Doc/AI/TeamsBot describes the bot only.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

async

無料

Forwarding AccessContext through async/reactive boundaries, and the no-async rule on the actor-model mesh. Use when writing or reviewing any hub-reachable / Blazor-view / agent-round / IIoPool code that creates, reads, or updates a mesh node, OR when a write "silently does nothing" / "Access denied" appears after a .Subscribe / IIoPool / Observable.Create hop. The async/await/ToTask/.Wait/.Result/.GetAwaiter/FirstAsync family and lost AccessContext are the two ways async boundaries cause wedges and storms. Grounded in AsynchronousCalls.md, SyncedMeshNodeQueries.md, AccessContextPropagation.md.

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaver122026年10月29日 更新

ci

無料

What CI proves, what it cannot prove, and how to write a gate that cannot pass on no evidence. Use when authoring or changing a GitHub Actions workflow, adding a required check, wiring a satellite repo CI, or reasoning about whether a green run actually covers your change. Covers the absolute no-skip-trapdoor rule (a gate must never carry continue-on-error on its input step nor an if that asks whether a secret is set — GitHub paints a skipped job the same colour as a passed one), the reusable workflow_call jobs satellite repos must call instead of hand-rolling, why runs on main are deliberately never cancelled, and the large body of in-mesh C# that no dotnet build or test ever type-checks.

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaver122026年10月29日 更新

debug

無料

Debug a deadlock / hang / timeout in the mesh — a test that times out, a hub handler whose response never arrives, a GetRemoteStream / GetMeshNodeStream / GetQuery that never emits, an agent round or per-instance-hub activation that parks forever. Use whenever something times out and you need to find WHERE the message flow breaks down. The timeout is the symptom, never the bug — raising it just hangs longer. Grounded in DebuggingMessageFlow.md.

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaver122026年10月29日 更新

Remove / reset a user (and their partition) on a running MeshWeaver portal (AKS). Use when you need to kick out a user — e.g. a throwaway test account — so they re-onboard from scratch. The normal delete API REFUSES a user's home ("user partition root … cannot be deleted"), so deletion is a Postgres-schema drop, not an MCP call. Covers where a user's data actually lives (per-user PG schemas named by BOTH id AND email, e.g. `rbuergi` + `rbuergi@systemorph.com`), how to reach PG (the connection string is inline in the portal's `ConnectionStrings__memex` env — NOT the `POSTGRES_PASSWORD` secret), the substring-match footgun (`buergi` also matches admin `rbuergi`), the in-memory resurrection gotcha (a recycle re-saves the node — a portal restart is what actually clears it), and the half-onboarded case where the user has NO schema at all (in-memory only → restart is the whole fix).

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaver122026年10月29日 更新

deploy

無料

Deploy MeshWeaver — the two routes (shared AKS cluster, and Azure Container Apps via the Aspire test/prod modes) and the traps that make a deploy look done when it is not. Use when rolling a code change onto a portal, standing up or patching an environment, or verifying that what is running is what you built. FIRST RULE (maintainer, 2026-09-08): on AKS an operation is a Hosting/InstanceAction on the control instance (Roll, Restart, Suspend, Audit, Reconcile, …) executed by the in-cluster operator — az aks command invoke / kubectl are break-glass, never the procedure. Also covers the bootstrap build-image / set-image / restart sequence the operator runs for you, why an env deploy.sh is first-time setup and not a code-update path, why the database migration is a run-once Job that a helm upgrade runs — never a Deployment to roll — and the DbVersionGate that makes a portal refuse to serve ahead of its schema.

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaver122026年10月29日 更新

gui

無料

Build or review ANY MeshWeaver UI — layout areas, editable views, forms, tables, content editing, side-panel composers — by wiring the framework's EXISTING data-binding pieces, NEVER hand-rolling. The one rule is ALWAYS DATA-BIND, especially editable views: the backend layout area declares WHAT to render (a UiControl tree + node PATHS), and every value read / write-back happens on the GUI side through the per-node IMeshNodeStreamCache. Hand-woven binding — replicating a node into a /data/{id} copy + a save subscription, emitting HTML strings, hand-built selects/checkboxes, .Take(1) on a live stream, async/await/QueryAsync in a layout area — is the bug class behind "awaiting first data" / "renders empty" / a stuck editable view. Use when writing or reviewing a layout area, control, editor, form, table, or any data-bound view. Grounded in src/MeshWeaver.Layout/DataBinding/, Doc/GUI/DataBinding.md + Editor.md, the Edit extension (EditorExtensions.cs), and the node-bound editor controls.

日本語の概要は準備中です。原文の説明を表示しています。

Systemorph/MeshWeaver122026年10月29日 更新

Systemorph のスキルをすべて見る

このスキルの問題を報告する