All skills
github avatar

/msgraph-sdk

@8bd33a9 official
by githubgithub/awesome-copilot40k stars
5,040

Integrate Microsoft Graph SDK into any project — .NET, TypeScript/JavaScript, or Python. Covers auth patterns (client credentials, OBO, managed identity), SDK setup, calling Graph APIs, batching, delta queries, change notifications, throttling, and permission scopes. Use when accessing Microsoft 365 data (users, mail, calendar, Teams, files, SharePoint) from any application type.

Use this Skill: https://skilld.dev/gh/github/awesome-copilot/msgraph-sdk

This session only. Nothing lands on disk.

referencestypescript.md

≈1.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Microsoft Graph SDK for TypeScript / JavaScript

Use this reference when the target project uses TypeScript or JavaScript (Node.js or browser).

Authoritative sources

Packages

npm install @microsoft/microsoft-graph-client @azure/identity
npm install -D @microsoft/microsoft-graph-types   # TypeScript type definitions

For Node.js environments, also install the fetch polyfill:

npm install node-fetch

Client setup

Managed Identity (Azure-hosted apps — preferred)

import { Client } from "@microsoft/microsoft-graph-client";
import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials/index.js";
import { DefaultAzureCredential } from "@azure/identity";

const credential = new DefaultAzureCredential();
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
  scopes: ["https://graph.microsoft.com/.default"],
});

const graphClient = Client.initWithMiddleware({ authProvider });

Client credentials (app-only / daemon)

import { ClientSecretCredential } from "@azure/identity";

const credential = new ClientSecretCredential(
  process.env.AZURE_TENANT_ID!,
  process.env.AZURE_CLIENT_ID!,
  process.env.AZURE_CLIENT_SECRET!
);

const authProvider = new TokenCredentialAuthenticationProvider(credential, {
  scopes: ["https://graph.microsoft.com/.default"],
});

const graphClient = Client.initWithMiddleware({ authProvider });

On-Behalf-Of (OBO) — agent / API acting as the signed-in user

import { OnBehalfOfCredential } from "@azure/identity";

// incomingToken is the bearer token received from the caller (e.g. from req.headers.authorization)
const credential = new OnBehalfOfCredential({
  tenantId: process.env.AZURE_TENANT_ID!,
  clientId: process.env.AZURE_CLIENT_ID!,
  clientSecret: process.env.AZURE_CLIENT_SECRET!,
  userAssertionToken: incomingToken,
});

const authProvider = new TokenCredentialAuthenticationProvider(credential, {
  scopes: ["https://graph.microsoft.com/.default"],
});

const graphClient = Client.initWithMiddleware({ authProvider });

For OBO, create a new client per request (credential is user-scoped, not singleton-safe).

Interactive (local dev / CLI — Node.js)

Use InteractiveBrowserCredential when a browser is available. Use DeviceCodeCredential for headless environments (SSH, CI-adjacent, WSL):

import { InteractiveBrowserCredential, DeviceCodeCredential } from "@azure/identity";

// Opens a browser tab — requires redirect URI http://localhost in app registration
const credential = new InteractiveBrowserCredential({
  tenantId: process.env.AZURE_TENANT_ID!,
  clientId: process.env.AZURE_CLIENT_ID!,
});

// Prints a device code to the terminal — works in any environment
const credential = new DeviceCodeCredential({
  tenantId: process.env.AZURE_TENANT_ID!,
  clientId: process.env.AZURE_CLIENT_ID!,
  userPromptCallback: (info) => console.log(info.message),
});

Both require the app registration platform to be "Mobile and desktop applications". Neither uses a client secret.

Common call patterns

Get a resource with field selection

import { User } from "@microsoft/microsoft-graph-types";

const user: User = await graphClient
  .api("/me")
  .select("displayName,mail,jobTitle")
  .get();

List with filter, select, and ordering

const result = await graphClient
  .api("/me/messages")
  .filter("isRead eq false")
  .select("subject,from,receivedDateTime")
  .top(25)
  .orderby("receivedDateTime desc")
  .get();

Pagination with PageIterator

import { PageIterator } from "@microsoft/microsoft-graph-client";
import { Message } from "@microsoft/microsoft-graph-types";

const firstPage = await graphClient.api("/me/messages").top(25).get();

const allMessages: Message[] = [];

const pageIterator = new PageIterator(
  graphClient,
  firstPage,
  (message: Message) => {
    allMessages.push(message);
    return true; // return false to stop early
  }
);

await pageIterator.iterate();

Send an email

await graphClient.api("/me/sendMail").post({
  message: {
    subject: "Hello from Graph",
    body: { contentType: "Text", content: "Test message" },
    toRecipients: [{ emailAddress: { address: "user@contoso.com" } }],
  },
});

Post a Teams channel message

await graphClient.api(`/teams/${teamId}/channels/${channelId}/messages`).post({
  body: { contentType: "html", content: "<b>Hello from Graph!</b>" },
});

Upload a file to OneDrive (small files ≤ 4 MB)

const content = Buffer.from("file contents");
await graphClient
  .api(`/me/drive/root:/${fileName}:/content`)
  .putStream(content);

For files > 4 MB, use an upload session (createUploadSession).

Batch requests

const batchRequestBody = {
  requests: [
    { id: "1", method: "GET", url: "/me" },
    { id: "2", method: "GET", url: "/me/messages?$top=5&$select=subject" },
  ],
};

const batchResponse = await graphClient.api("/$batch").post(batchRequestBody);

const meResponse = batchResponse.responses.find((r: any) => r.id === "1");
const messagesResponse = batchResponse.responses.find((r: any) => r.id === "2");

Delta queries

// First sync
let response = await graphClient.api("/users/delta").get();
const users: any[] = [];

while (response["@odata.nextLink"]) {
  users.push(...response.value);
  response = await graphClient.api(response["@odata.nextLink"]).get();
}
users.push(...response.value);

const deltaLink: string = response["@odata.deltaLink"];
// Store deltaLink durably for next sync run

// Next sync — only changes
const changesResponse = await graphClient.api(deltaLink).get();

Throttling / retry middleware

The SDK includes retry middleware by default. For explicit configuration:

import {
  Client,
  RetryHandlerOptions,
  RetryHandler,
  MiddlewareFactory,
} from "@microsoft/microsoft-graph-client";

const retryOptions = new RetryHandlerOptions({ maxRetries: 5 });
const middleware = MiddlewareFactory.getDefaultMiddlewareChain(authProvider);

const graphClient = Client.initWithMiddleware({ middleware });

Always honour the Retry-After header value — do not use fixed backoff when Graph specifies a wait time.

TypeScript-specific guidance

  • Import types from @microsoft/microsoft-graph-types for full IntelliSense on Graph resources.
  • The .api() chain returns any — cast to the appropriate type from @microsoft/microsoft-graph-types.
  • For ESM projects, use the /index.js path suffix on deep imports (e.g., azureTokenCredentials/index.js).
  • Use async/await consistently — all Graph calls return Promises.
  • Singleton the graphClient in application-level code (e.g., Express app init); for OBO flows, construct per-request.
  • In Node.js 18+, fetch is available natively — no polyfill needed.
// Type-safe response example
import { MessageCollectionResponse } from "@microsoft/microsoft-graph-types";

const response: MessageCollectionResponse = await graphClient
  .api("/me/messages")
  .select("subject,from")
  .get();

const messages = response.value ?? [];

Source: SKILL.md on GitHub

No alerts3mo3 checks · Risk SAFE
  • Gen Agent Trust Hub3mo

    This skill provides safe and authoritative guidance for integrating the Microsoft Graph SDK into .NET, Python, and TypeScript projects. It strictly follows security best practices, including the use of Managed Identities, environment variables for secret management, and enforcing the principle of least privilege for API permissions. All external resources and packages originate from official Microsoft repositories and well-known registries.

  • Socket3mo

    No alerts

  • Snyk3mo

    Risk: LOW · No issues

Signed by skilld at 8bd33a9. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 5 months ago
  • TypeScript
  • Python
  • microsoft-graph
  • msgraph-sdk
  • microsoft-365
  • authentication
  • dotnet
  • api-integration
  • pagination
  • throttling

README badge

README badge for github/awesome-copilot/msgraph-sdk

Integrates Microsoft Graph SDK for .NET, TypeScript/JavaScript, or Python to access Microsoft 365 data (users, mail, calendar, Teams, files, SharePoint). Covers authentication patterns (client credentials, on-behalf-of, managed identity), pagination, batching, delta queries, change notifications, throttling, and permission scopes.

Generated from the current SKILL.md.

Does this skill support all three languages — .NET, TypeScript, and Python?
Yes. The skill includes language-specific reference workflows for .NET, TypeScript/JavaScript, and Python. Follow the matching reference file based on your project's file types.
Which authentication flow should I use for a background service?
Use client credentials (app-only) for background services or daemons with no user context. The skill includes a decision tree to match your scenario to the correct auth pattern.
How do I handle pagination when fetching large collections from Graph?
Always check for `@odata.nextLink` in responses and use the SDK's `PageIterator` helper to walk pages automatically. Never assume all items arrive in one request.
What should I do if I receive HTTP 429 (throttling) responses?
Read the `Retry-After` header for the exact wait time, and enable the SDK's built-in retry middleware to handle 429s automatically. Avoid parallel fan-out patterns; use batching or queuing instead.
Does this skill cover change notifications and webhooks?
Yes. The skill covers subscription creation, validation handshakes, renewal before expiration, and lifecycle notifications for handling missed events.

Generated from the current SKILL.md. These answers refresh after source changes.