Skip to main content
Glama

graph-request

Execute Microsoft Graph API requests to access Microsoft 365 services. Target specific accounts without switching and use any Graph endpoint with query parameters.

Instructions

Execute a raw Microsoft Graph API request. Supports any Graph API endpoint. Can target specific account without switching.

Documentation:

  • Graph API Reference: https://learn.microsoft.com/en-us/graph/api/overview

  • Common endpoints: /me, /users, /groups, /me/messages, /me/calendar/events, /me/drive

  • OData query params: $select, $filter, $top, $orderby, $expand, $count, $search

  • Permissions reference: https://learn.microsoft.com/en-us/graph/permissions-reference

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
endpointYesThe Graph API endpoint path (e.g., "/me", "/users", "/me/messages")
methodNoHTTP methodGET
bodyNoRequest body for POST/PUT/PATCH requests (JSON object)
queryParamsNoQuery parameters (e.g., {"$select": "displayName", "$top": "10"})
headersNoAdditional headers to include
apiVersionNoGraph API versionv1.0
accountIdNoTarget a specific account by ID without switching. Use list-accounts to see available IDs.

Implementation Reference

  • Handler function for the 'graph-request' MCP tool. Prepares the request by handling account-specific tokens, building the path with query parameters and API version, sets up options, and calls graphClient.graphRequest to execute the Microsoft Graph API call.
    async ({ endpoint, method, body, queryParams, headers, apiVersion, accountId }) => { try { // Get token for specific account if requested let accessToken: string | undefined; if (accountId) { const token = await authManager.getTokenForAccount(accountId); if (!token) { return { content: [ { type: 'text', text: JSON.stringify({ error: `Failed to get token for account: ${accountId}. Use list-accounts to see available accounts.`, }), }, ], isError: true, }; } accessToken = token; } // Build the full path with query params let path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`; // Use beta API if requested if (apiVersion === 'beta') { path = path.replace(/^\//, '/beta/').replace('/beta//', '/beta/'); } if (queryParams && Object.keys(queryParams).length > 0) { const params = new URLSearchParams(queryParams).toString(); path = `${path}${path.includes('?') ? '&' : '?'}${params}`; } const options: any = { method: method || 'GET', headers: headers || {}, }; if (body && ['POST', 'PUT', 'PATCH'].includes(method || 'GET')) { options.body = typeof body === 'string' ? body : JSON.stringify(body); } // Add access token if targeting specific account if (accessToken) { options.accessToken = accessToken; } const result = await graphClient.graphRequest(path, options); return result; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ error: `Graph API request failed: ${(error as Error).message}`, }), }, ], isError: true, }; } }
  • Zod input schema defining parameters for the graph-request tool including endpoint, HTTP method, request body, query parameters, custom headers, API version, and optional account ID.
    { endpoint: z.string().describe('The Graph API endpoint path (e.g., "/me", "/users", "/me/messages")'), method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).default('GET').describe('HTTP method'), body: z.any().optional().describe('Request body for POST/PUT/PATCH requests (JSON object)'), queryParams: z.record(z.string()).optional().describe('Query parameters (e.g., {"$select": "displayName", "$top": "10"})'), headers: z.record(z.string()).optional().describe('Additional headers to include'), apiVersion: z.enum(['v1.0', 'beta']).default('v1.0').describe('Graph API version'), accountId: z.string().optional().describe('Target a specific account by ID without switching. Use list-accounts to see available IDs.'), },
  • Registration of the 'graph-request' tool using server.tool() within the registerAuthTools function, conditional on graphClient being provided.
    server.tool( 'graph-request', `Execute a raw Microsoft Graph API request. Supports any Graph API endpoint. Can target specific account without switching. Documentation: - Graph API Reference: https://learn.microsoft.com/en-us/graph/api/overview - Common endpoints: /me, /users, /groups, /me/messages, /me/calendar/events, /me/drive - OData query params: $select, $filter, $top, $orderby, $expand, $count, $search - Permissions reference: https://learn.microsoft.com/en-us/graph/permissions-reference`, { endpoint: z.string().describe('The Graph API endpoint path (e.g., "/me", "/users", "/me/messages")'), method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).default('GET').describe('HTTP method'), body: z.any().optional().describe('Request body for POST/PUT/PATCH requests (JSON object)'), queryParams: z.record(z.string()).optional().describe('Query parameters (e.g., {"$select": "displayName", "$top": "10"})'), headers: z.record(z.string()).optional().describe('Additional headers to include'), apiVersion: z.enum(['v1.0', 'beta']).default('v1.0').describe('Graph API version'), accountId: z.string().optional().describe('Target a specific account by ID without switching. Use list-accounts to see available IDs.'), }, async ({ endpoint, method, body, queryParams, headers, apiVersion, accountId }) => { try { // Get token for specific account if requested let accessToken: string | undefined; if (accountId) { const token = await authManager.getTokenForAccount(accountId); if (!token) { return { content: [ { type: 'text', text: JSON.stringify({ error: `Failed to get token for account: ${accountId}. Use list-accounts to see available accounts.`, }), }, ], isError: true, }; } accessToken = token; } // Build the full path with query params let path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`; // Use beta API if requested if (apiVersion === 'beta') { path = path.replace(/^\//, '/beta/').replace('/beta//', '/beta/'); } if (queryParams && Object.keys(queryParams).length > 0) { const params = new URLSearchParams(queryParams).toString(); path = `${path}${path.includes('?') ? '&' : '?'}${params}`; } const options: any = { method: method || 'GET', headers: headers || {}, }; if (body && ['POST', 'PUT', 'PATCH'].includes(method || 'GET')) { options.body = typeof body === 'string' ? body : JSON.stringify(body); } // Add access token if targeting specific account if (accessToken) { options.accessToken = accessToken; } const result = await graphClient.graphRequest(path, options); return result; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ error: `Graph API request failed: ${(error as Error).message}`, }), }, ], isError: true, }; } } );
  • Core helper method in GraphClient class that executes the actual Graph API HTTP request, handles OAuth token management and refresh, formats MCP-compliant responses, and manages errors.
    async graphRequest(endpoint: string, options: GraphRequestOptions = {}): Promise<McpResponse> { try { logger.info(`Calling ${endpoint} with options: ${JSON.stringify(options)}`); // Use new OAuth-aware request method const result = await this.makeRequest(endpoint, options); return this.formatJsonResponse(result, options.rawResponse, options.excludeResponse); } catch (error) { logger.error(`Error in Graph API request: ${error}`); return { content: [{ type: 'text', text: JSON.stringify({ error: (error as Error).message }) }], isError: true, }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ForITLLC/forit-microsoft-graph'

If you have feedback or need assistance with the MCP directory API, please join our Discord server