microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/update-sample-to-blazor

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/samples/McpServer/State.cs

58lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Collections.Concurrent;
5
6namespace McpServer;
7
8public static class AskStatus
9{
10 public const string Pending = "pending";
11 public const string Answered = "answered";
12}
13
14public static class ApprovalStatus
15{
16 public const string Pending = "pending";
17 public const string Approved = "approved";
18 public const string Rejected = "rejected";
19}
20
21// Immutable so readers always see a consistent (Status, Reply) snapshot — no locks,
22// no Volatile, no torn state. Transitions go through ConcurrentDictionary.TryUpdate
23// in State.PendingAsks: build a new record, swap atomically against the old one.
24public sealed record PendingAsk(string UserId, string Status = AskStatus.Pending, string? Reply = null);
25
26/// <summary>
27/// In-memory state shared between the Teams bot handlers and the MCP tools.
28/// A server restart clears everything — pending asks and approvals in flight will be lost.
29/// </summary>
30public sealed class State
31{
32 /// <summary>User AAD object id -> personal conversationId. Populated on first incoming 1:1 message.</summary>
33 public ConcurrentDictionary<string, string> Conversations { get; } = new();
34
35 /// <summary>requestId -> PendingAsk.</summary>
36 public ConcurrentDictionary<string, PendingAsk> PendingAsks { get; } = new();
37
38 /// <summary>approvalId -> approval status. Values: "pending", "approved", "rejected".</summary>
39 public ConcurrentDictionary<string, string> Approvals { get; } = new();
40
41 /// <summary>
42 /// requestId -> TCS completed when the user replies (or the ask is superseded).
43 /// Lets <c>wait_for_reply</c> return sub-millisecond after the answer lands instead of polling.
44 /// </summary>
45 public ConcurrentDictionary<string, TaskCompletionSource<PendingAsk>> ReplyWaiters { get; } = new();
46
47 /// <summary>
48 /// approvalId -> TCS completed with the final status when the user clicks Approve/Reject.
49 /// Lets <c>wait_for_approval</c> return sub-millisecond after the decision lands instead of polling.
50 /// </summary>
51 public ConcurrentDictionary<string, TaskCompletionSource<string>> ApprovalWaiters { get; } = new();
52
53 /// <summary>
54 /// Service URL used by proactive sends and <c>conversations.create</c>. Updated from
55 /// the first incoming activity; falls back to the default Teams endpoint until then.
56 /// </summary>
57 public Uri ServiceUrl { get; set; } = new Uri("https://smba.trafficmanager.net/teams/");
58}
59