agentleFS
canyonlabzcanyonlabz/perfpilot-hub/.cursor/skills/msteams-notification/SKILL.md

msteams-notification

Skill5 starsChanged 6 months agoMITView on GitHub

Orchestrate MS Teams notifications for performance testing — send start-test, stop-test, and test-results notifications to configured channels and chats using templates, @mentions, and auto-populated context from test artifacts. Use when the user mentions Teams notification, notify the team, send Teams message, start/stop test notification, test results notification, or MS Teams alert.

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 9 are distinctive, and 10 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 10

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If id is provided → used directly (no search)

    line 147
  2. Very specific:

    If only email → auto-resolved via teams_search_people

    line 148
  3. Distinctive:

    If search returns 0 or multiple matches → message is NOT sent, warning returned

    line 149
  4. Distinctive:

    Follow these steps exactly, in order.

    line 167
  5. Distinctive:

    Ask the user for the following values.

    line 173
  6. Very specific:

    If the user is in a performance-testing-workflow conversation, the test_run_id, test_name, environment, and other values are likely already …

    line 196
  7. Very specific:

    If the user says "notify the team that the test is done", infer notification_type as stop-test and check context for test_run_id.

    line 198
  8. Very specific:

    If the user provides a test_run_id but no explicit variable values, rely on auto-population from artifacts.

    line 200
  9. Distinctive:

    Do not proceed until authentication is confirmed.

    line 217
  10. Very specific:

    If test_run_id is provided, check the notification log for the previous start-test:

    line 254
  11. Very specific:

    If test_run_id is provided, the tool auto-loads variables from artifacts (load_context_variables).

    line 274
  12. Distinctive:

    If the user specified additional people to @mention:

    line 301
  13. Distinctive:

    If user gave emails → add directly to the mentions array

    line 303
  14. Distinctive:

    If user gave names → search first:

    line 304
  15. Very specific:

    If no dynamic mentions are needed and the config already has the correct list, leave the mentions parameter empty — the tool merges config …

    line 324
  16. Distinctive:

    Important: Only pass parameters that have values.

    line 343
  17. Very specific:

    If test_run_id was provided, confirm that the notification was logged to artifacts/{test_run_id}/notifications/notification_log.json.

    line 352
  18. Very specific:

    Auth expired mid-send: Run teams_login(), then retry the send once.

    line 364
  19. Distinctive:

    Ask the user to verify the email or provide an alternative.

    line 366

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

MS Teams Notification Skill

When to Use This Skill

  • User wants to notify a Teams channel or chat about a performance test
  • User mentions "send a Teams notification", "notify the team", or "alert stakeholders"
  • User wants to send a start-test, stop-test, or test-results notification
  • User is in the performance-testing-workflow and wants to notify before/after a test
  • User asks to @mention people in a Teams notification

What This Skill Does

  1. Ensures MS Teams authentication is active
  2. Collects notification parameters from the user
  3. Resolves the target channel/chat (config name or raw ID)
  4. Populates template variables from user input and test artifacts
  5. Resolves @mentions (config-driven + dynamic) to Azure AD object IDs
  6. Sends the notification via teams_send_message

Prerequisites

  • The msteams-mcp server must be running and connected
  • The user must have authenticated via teams_login (check with teams_status first)
  • For artifact-based variables (test_run_id), the relevant BlazeMeter/Datadog/Report artifacts must already exist in artifacts/{test_run_id}/

Related Rules

  • mcp-error-handling.mdc — MCP tool error handling (retry policy, reporting format)
  • skill-execution-rules.mdc — Follow steps in order, collect inputs first

Reference

MS Teams MCP Tools Used

ToolPurpose
teams_statusVerify authentication is active before sending
teams_loginAuthenticate if session is expired
teams_send_messageSend the notification (with template, target, mentions)
teams_search_peopleResolve person name to email when user gives a name

Notification Types and Templates

TypeTemplateWhen to Use
Start testnotification-start-test.mdBefore launching a load test
Stop testnotification-stop-test.mdAfter a test completes
Test resultsnotification-test-results.mdAfter analysis and reporting are done

Templates fall back to default-{name} if no custom version exists.

Template Placeholders

Placeholders use {{VARIABLE_NAME}} syntax. Unmatched placeholders are silently removed.

Common (all templates):

PlaceholderSourceRequired
{{TEST_NAME}}User inputYes
{{ENVIRONMENT}}User inputYes
{{TEST_RUN_ID}}User input or test_run_id paramYes
{{MESSAGE}}The message param or user's free-textNo

Start-test specific:

PlaceholderSource
{{START_TIME}}User input or auto from artifacts
{{DURATION}}User input (planned duration)
{{VIRTUAL_USERS}}User input

Stop-test specific:

PlaceholderSource
{{START_TIME}}Auto from notification log or artifacts
{{END_TIME}}Auto from artifacts or current time
{{DURATION}}Auto-calculated or user input
{{VIRTUAL_USERS}}Auto from notification log or user input
{{STATUS}}User input (e.g., "Completed", "Aborted")

Test-results specific:

PlaceholderSource
{{AVG_RESPONSE_TIME}}BlazeMeter aggregate report
{{P90_RESPONSE_TIME}}BlazeMeter aggregate report
{{P95_RESPONSE_TIME}}BlazeMeter aggregate report
{{MAX_RESPONSE_TIME}}BlazeMeter aggregate report
{{ERROR_RATE}}BlazeMeter aggregate report
{{THROUGHPUT}}BlazeMeter aggregate report
{{BLAZEMETER_REPORT_LINK}}artifacts/{id}/blazemeter/public_report.json
{{CONFLUENCE_REPORT_LINK}}artifacts/{id}/reports/report_metadata_{id}.json

Config-Driven Targets and Mentions

Targets and standing mention lists are defined in the msteams-mcp config file under teams.notification_targets. The tool auto-resolves named targets to conversation IDs and merges config-level mentions with any dynamic mentions.

Example config structure:

notification_targets:
  channels:
    qa-perf-results:
      conversation_id: "19:abc@thread.tacv2"
      description: "QA Performance Testing"
      template: "notification-test-results.md"
      mentions:
        - "homer.simpson@company.com"
        - "marge.simpson@company.com"
  chats:
    default_chat:
      conversation_id: "19:def@thread.v2"
      description: "Internal Performance Team"

Mention Resolution

The mentions parameter accepts a JSON array. Each entry needs email and/or id:

[
  {"email": "john.doe@company.com"},
  {"email": "jane.doe@company.com", "displayName": "Jane Doe (US)"},
  {"id": "5769135d-...", "displayName": "Known User"}
]

Resolution rules:

  • If id is provided → used directly (no search)
  • If only email → auto-resolved via teams_search_people
  • If search returns 0 or multiple matches → message is NOT sent, warning returned
  • Config mentions + dynamic mentions are merged and deduplicated by email

Integration with Performance Testing Workflow

This skill can be invoked at three points in the performance-testing-workflow:

  1. Before Step 2 (BlazeMeter) — Send start-test notification
  2. After Step 2 (BlazeMeter) — Send stop-test notification
  3. After Step 5 or 6 (PerfReport/Confluence) — Send test-results notification

The test_run_id parameter auto-loads context from artifacts, so most placeholders are populated automatically after the relevant workflow steps complete.


Execution

Follow these steps exactly, in order.


Collect Inputs

Ask the user for the following values. Do not proceed until required values are collected.

REQUIRED:
  notification_type = [start-test | stop-test | test-results]
  target            = [named target from config, e.g. "qa-perf-results",
                       or raw conversation ID]

REQUIRED (if no test_run_id for auto-population):
  test_name         = [e.g., "Shopping Cart 150-User Load Test (QA)"]
  environment       = [e.g., "QA", "UAT", "PROD"]

CONDITIONAL:
  test_run_id       = [e.g., "7654321" — auto-populates variables from artifacts]

OPTIONAL:
  subject           = [bold title line above message in channels]
  message           = [free-text appended to the template as {{MESSAGE}}]
  mentions          = [additional people to @mention beyond config defaults]
  variables         = [explicit key-value overrides for any placeholder]

Inferring values from conversation context:

  • If the user is in a performance-testing-workflow conversation, the test_run_id, test_name, environment, and other values are likely already known. Use them.
  • If the user says "notify the team that the test is done", infer notification_type as stop-test and check context for test_run_id.
  • If the user provides a test_run_id but no explicit variable values, rely on auto-population from artifacts.

Step 1 — Check Authentication

teams_status()

Inspect the response. If the session is expired or missing:

teams_login()

Do not proceed until authentication is confirmed.


Step 2 — Determine Template

Based on notification_type:

TypeTemplate filename
start-testnotification-start-test.md
stop-testnotification-stop-test.md
test-resultsnotification-test-results.md

The tool's layered resolution handles fallback to default-{name} automatically.


Step 3 — Build Variables

Construct the variables JSON object from collected inputs.

For start-test:

{
  "TEST_NAME": "{test_name}",
  "ENVIRONMENT": "{environment}",
  "TEST_RUN_ID": "{test_run_id}",
  "START_TIME": "{start_time or current time}",
  "DURATION": "{planned_duration}",
  "VIRTUAL_USERS": "{virtual_users}"
}

For stop-test:

If test_run_id is provided, check the notification log for the previous start-test:

  • Read artifacts/{test_run_id}/notifications/notification_log.json
  • Find the most recent notification-start-test entry
  • Extract TEST_NAME, ENVIRONMENT, START_TIME, VIRTUAL_USERS from it
{
  "TEST_NAME": "{from log or user}",
  "ENVIRONMENT": "{from log or user}",
  "TEST_RUN_ID": "{test_run_id}",
  "START_TIME": "{from log}",
  "END_TIME": "{end_time or current time}",
  "DURATION": "{calculated or user}",
  "VIRTUAL_USERS": "{from log or user}",
  "STATUS": "{status — e.g., Completed, Aborted}"
}

For test-results:

If test_run_id is provided, the tool auto-loads variables from artifacts (load_context_variables). You only need to pass explicit overrides and any values the tool cannot auto-detect:

{
  "TEST_NAME": "{test_name}",
  "ENVIRONMENT": "{environment}",
  "VIRTUAL_USERS": "{virtual_users}",
  "AVG_RESPONSE_TIME": "{from aggregate report}",
  "P90_RESPONSE_TIME": "{from aggregate report}",
  "P95_RESPONSE_TIME": "{from aggregate report}",
  "MAX_RESPONSE_TIME": "{from aggregate report}",
  "ERROR_RATE": "{from aggregate report}",
  "THROUGHPUT": "{from aggregate report}"
}

For metrics from the BlazeMeter aggregate report, read artifacts/{test_run_id}/blazemeter/aggregate_performance_report.csv and extract the TOTAL row values. The tool auto-loads BLAZEMETER_REPORT_LINK and CONFLUENCE_REPORT_LINK from their respective JSON files when test_run_id is set.


Step 4 — Build Mentions List

If the user specified additional people to @mention:

  1. If user gave emails → add directly to the mentions array
  2. If user gave names → search first:
teams_search_people(query="{person_name}")

Review the results. If exactly one match, use their email. If multiple matches, present the options to the user and ask them to confirm which person to tag.

Combine with any config-level mentions (handled automatically by the tool).

Format the final mentions parameter:

[
  {"email": "person1@company.com"},
  {"email": "person2@company.com", "displayName": "Person Two (US)"}
]

If no dynamic mentions are needed and the config already has the correct list, leave the mentions parameter empty — the tool merges config mentions automatically.


Step 5 — Send Notification

teams_send_message(
  target      = "{target}",
  template    = "{template_filename}",
  variables   = '{...JSON string...}',
  test_run_id = "{test_run_id}",
  subject     = "{subject}",
  message     = "{message}",
  mentions    = '[...JSON string...]'
)

Important: Only pass parameters that have values. Omit empty optional parameters.


Step 6 — Verify and Report

Check the response:

  • Success ("status": "sent") — Report the message ID and target to the user. If test_run_id was provided, confirm that the notification was logged to artifacts/{test_run_id}/notifications/notification_log.json.
  • Mention resolution failure ("INVALID_INPUT" with mention warnings) — Report which emails failed. Ask the user to verify the email addresses or provide object IDs directly. Do NOT retry automatically.
  • Auth failure — Run teams_login() and retry once.
  • Other errors — Report the full error and ask the user for next steps.

Error Handling

  • Auth expired mid-send: Run teams_login(), then retry the send once.
  • Mention not found: Report the warning. Do NOT send the message without the mention. Ask the user to verify the email or provide an alternative.
  • Ambiguous mention: Present the multiple matches to the user. Ask them to pick the correct person or provide the specific id.
  • Template not found: Report the missing template name. Suggest checking the templates/ directory or using a default template.
  • No conversation_id resolved: The target name doesn't match any config entry and isn't a valid raw ID. Ask the user to verify the target name or provide a conversation ID. Suggest using teams_list_channels or teams_find_channel to discover the correct ID.

Examples

Start-Test Notification (Simple)

User: "Notify the perf channel that we're starting the 50-user load test on QA"

teams_send_message(
  target    = "perf-channel",
  template  = "notification-start-test.md",
  variables = '{"TEST_NAME": "50-User Load Test", "ENVIRONMENT": "QA", "VIRTUAL_USERS": "50"}',
  subject   = "50-User Load Test — Starting"
)

Test-Results Notification (With test_run_id)

User: "Send the test results to the QA channel for run 7654321"

teams_send_message(
  target      = "qa-perf-results",
  template    = "notification-test-results.md",
  test_run_id = "7654321",
  variables   = '{"TEST_NAME": "Shopping Cart 150-User Load Test (QA)", "ENVIRONMENT": "QA", "VIRTUAL_USERS": "150"}',
  subject     = "Shopping Cart 150-User Load Test — Results"
)

The tool auto-loads BLAZEMETER_REPORT_LINK, CONFLUENCE_REPORT_LINK, and other context variables from artifacts/7654321/.

Dynamic @mention

User: "Send the results to the default chat and tag lisa.simpson@company.com"

teams_send_message(
  target      = "default_chat",
  template    = "notification-test-results.md",
  test_run_id = "7654321",
  mentions    = '[{"email": "lisa.simpson@company.com"}]'
)

Config mentions for default_chat are merged automatically.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.