Skip to main content
Glama
day0ops

mcp-graph-me-tool

by day0ops

mcp-graph-me-tool

A minimal Streamable HTTP MCP server exposing one tool, graph_me, which calls Microsoft Graph's GET /me with the caller's bearer token and returns the signed-in user's profile.

It's the backend half of a Microsoft Entra ID On-Behalf-Of (OBO) token exchange demo: a gateway (e.g. agentgateway) sits in front of this server, validates the caller's Entra token, exchanges it for a Graph-scoped token via Entra's own token endpoint, and forwards the request here with the exchanged token substituted for Authorization. This server does not perform any exchange or validation itself - it only relays whatever bearer token it's handed to Graph.

What it does

sequenceDiagram
    participant Client as MCP Client
    participant AGW as Gateway (OBO exchange)
    participant Tool as mcp-graph-me-tool
    participant Graph as Microsoft Graph

    Client->>AGW: tools/call graph_me + user's Entra token
    AGW->>AGW: exchange for a Graph-scoped token
    AGW->>Tool: tools/call graph_me + exchanged token
    Tool->>Graph: GET /v1.0/me + exchanged token
    Graph-->>Tool: profile
    Tool-->>AGW: tool result
    AGW-->>Client: tool result
  • graph_me - no arguments. Reads the Authorization header off the incoming HTTP request and calls https://graph.microsoft.com/v1.0/me with it. Returns the profile JSON on success, or {"error": "Graph API returned <status>", "detail": "<Graph's own error body>"} on failure (including when no Authorization header is present at all).

  • GET /healthz - plain 200 ok liveness/readiness check.

Each HTTP request gets a fresh McpServer instance built from that request's own Authorization header (see buildServer() in server.js) - there is no session or connection state held between requests.

Running locally

npm install
npm start
# listening on :8080 (override with PORT)
curl localhost:8080/healthz
# ok

Development

npm test   # node --check server.js (syntax check)

Wiring into agentgateway

Deploy this image behind a plain EnterpriseAgentgatewayBackend/HTTPRoute pointing at port 8080, protocol: StreamableHTTP, path: /mcp, then apply an oauthTokenExchange policy (grantType: JwtBearer) on that route to perform the Entra OBO exchange before requests reach this server. See docs.solo.io's Entra OBO guide for the full walkthrough.

License

Apache License 2.0 - see LICENSE.