graph-connector-agent
v0.1.0-beta.1
Published
MCP server that converts Microsoft Graph API endpoints into Power Platform–compatible Swagger 2.0 custom connector schemas.
Maintainers
Readme
Graph Connector Agent
Overview
- TypeScript/Node.js MCP server that converts Microsoft Graph API endpoints into Power Platform-compatible Swagger 2.0 custom connector schemas.
- The server never executes Graph API calls; it only fetches publicly available metadata and generates connector schema files.
- Supports multi-segment navigation paths (e.g.,
/deviceManagement/managedDevices) and OData bound actions. - Generates output in three formats: Swagger 2.0 JSON, Swagger 2.0 YAML, and OpenAPI 3.0 JSON.
- Designed for use via MCP chat, agent-to-agent invocation, and future HTTP/web UI transport.
Features & Tools
- List Operations (
graph.listOperations) - Given a Graph API endpoint path (e.g.,/users,/deviceManagement/managedDevices), returns all available HTTP operations (GET, POST, PATCH, DELETE) plus OData bound actions, with summaries, parameters, required scopes, and request/response hints. - Generate Connector (
graph.generateConnector) - Given a list of selectedoperationIds and an optionalformatparameter, generates connector files in the requested format(s). Supportsswagger-json(default),swagger-yaml,openapi-json, orall. Features include:- Auto-flattened schemas (no
allOf/oneOf/anyOf). x-ms-summary,x-ms-visibility,x-ms-url-encodingextensions.- Microsoft Entra ID OAuth2 security definition.
- Correct response codes: 204 for DELETEs and fire-and-forget POST actions, flat objects for single-entity GETs,
valuearray wrappers for collection GETs. - Typed body definitions: action parameters extracted from CSDL with proper types (
boolean,string,integer) andx-ms-summarydisplay labels. - Power Platform constraint validation (< 1 MB, <= 256 ops, <= 512 body schemas).
- Automatic multi-file splitting if limits are exceeded.
- Auto-flattened schemas (no
Output Formats
The agent produces connectors in three formats:
| Format | File Extension | Use Case |
|--------|---------------|----------|
| Swagger 2.0 JSON | .swagger.json | Power Platform import (native format) |
| Swagger 2.0 YAML | .swagger.yaml | Human-readable review and comparison |
| OpenAPI 3.0 JSON | .openapi.json | Modern tooling, validators, and API portals |
Architecture
Three-Layer Design (UI-Ready)
+-------------------------------------------+
| Wire Transport |
| * stdioHost.ts (primary) |
| * httpHost.ts (future - Express) |
+-------------------------------------------+
| Protocol Adapter |
| * mcpAdapter.ts (async JSON-RPC) |
+-------------------------------------------+
| Core Logic (transport-agnostic) |
| * graphMetadata.ts (CSDL fetch/cache) |
| * schemaNormalizer.ts (flatten/fix) |
| * connectorGenerator.ts (Swagger 2.0) |
| * tools/index.ts (registry/dispatch) |
+-------------------------------------------+Components
- Config loader + validator (
src/config/) - JSON config with Graph-specific settings. - Tool registry + async dispatch (
src/tools/) -graph.listOperationsandgraph.generateConnector. - Graph metadata provider (
src/tools/graphMetadata.ts) - CSDL fetch, file cache, navigation path resolution, bound action discovery,hidiCLI detection, pure-TS fallback. - Schema normalizer (
src/tools/schemaNormalizer.ts) - Flatten polymorphic schemas, downgrade to Swagger 2.0. - Connector generator (
src/tools/connectorGenerator.ts) - Assemble, enrich withx-ms-*extensions, validate Power Platform constraints, serialize Swagger 2.0 JSON. Handles response code correctness (204 for actions) and typed body definitions. - MCP transport adapter (
src/transport/mcpAdapter.ts) - Async JSON-RPC handler. - Stdio host (
src/transport/stdioHost.ts) - Line-delimited JSON-RPC over stdin/stdout. - HTTP host (
src/transport/httpHost.ts) - Express wrapper (deferred, requires optionalexpressdep). - Path policy checks (
src/policies/) - Read/write allow/deny validation. - Stderr-only logger (
src/logging/logger.ts) - Keeps stdout clean for protocol messages.
Workflow
Discover operations - Call
graph.listOperationswith an endpoint path:graph.listOperations({ endpoint: "/deviceManagement/managedDevices", version: "beta" })Returns CRUD operations (list, get, create, update, delete) plus bound actions (retire, wipe, sync, etc.) with typed parameter metadata.
Select operations - Choose which
operationIds to include in the connector.Generate connector - Call
graph.generateConnectorwith the selected IDs and optional format:graph.generateConnector({ operationIds: ["managedDevices.list", "managedDevices.get", "managedDevices.retire", "managedDevices.wipe"], connectorName: "Intune Managed Device Actions", version: "beta", format: "all" // or "swagger-json" (default), "swagger-yaml", "openapi-json" })Import - Use the generated
.swagger.jsonfile to create a custom connector in Power Platform. Use.openapi.jsonfor modern tooling or.swagger.yamlfor human review.
Configuration
- Configuration is stored in JSON files under
config/. - Key Graph-specific settings:
graph.defaultVersion-"v1.0"or"beta"(default:"v1.0").graph.csdlCacheTtlHours- How long to cache CSDL metadata (default:24).graph.csdlCachePath- Local cache directory (default:"./cache").graph.hidiCliPath- Path tohidiCLI (default:null= auto-detect on PATH).graph.autoFlatten- Auto-flatten unsupported schema constructs (default:true).graph.maxOperationsPerConnector- Max operations per connector file (default:256).graph.defaultAuth- Default OAuth2 settings (tenant ID, client ID, scopes).
Quick-start profiles
config/profiles/dev.session.config.json- Local development, session auth only.config/profiles/corporate.hybrid.config.json- Enterprise with OAuth and corporate boundary enforcement.- Start with a profile: set
MCP_CONFIG_PATHto the chosen file.
Admin path setup
- Set absolute paths in
paths.allowedReadRootsandpaths.allowedWriteRootsfor non-default locations. - Use
MCP_CONFIG_PATHenvironment variable to override default config file location.
Optional: hidi CLI (Recommended)
The hidi CLI from Microsoft provides the most complete CSDL-to-OpenAPI conversion, handling all OData constructs including functions, actions, and deep navigation paths.
Install:
dotnet tool install Microsoft.OpenApi.Hidi -gRequirements: .NET 8.0+ runtime.
When hidi is not found on PATH, the server falls back to a built-in pure-TypeScript XML parser that covers common Graph entities including multi-segment navigation paths and bound actions. This is sufficient for most custom connector use cases.
To specify a custom hidi path, set graph.hidiCliPath in your config file.
Optional: HTTP Transport (Express)
The express package is listed as an optional dependency. It is only needed if you want to run the HTTP/REST entry point for web UI integration.
Stdio-only install (skip Express):
npm install --omit=optionalFull install (includes Express for HTTP transport):
npm installStart HTTP server:
npm run start:httpThe HTTP entry point exposes:
POST /mcp- MCP JSON-RPC endpoint (same protocol as stdio).GET /api/graph/operations?endpoint=/users&version=v1.0- REST API for listing operations.POST /api/graph/connector- REST API for generating connector files.
If express is not installed, entry-http.ts logs a clear error message and exits gracefully.
Safety & Limitations
- No Graph API calls are executed - only publicly accessible CSDL metadata is fetched.
- Credentials and secrets must not be stored in config files.
- Generated connector files contain OAuth2 placeholders; real client secrets must never be embedded in the schema.
- Swagger 2.0 cannot represent
oneOf/anyOf- these are flattened with loss of type discrimination. - Very large resource areas may require multiple connector files due to Power Platform limits.
Development
Tech stack
- Node.js (LTS 18+), TypeScript (strict mode with
exactOptionalPropertyTypes). - Dependencies:
fast-xml-parser,zod,js-yaml. - Optional:
express(HTTP transport).
Local commands
npm run build # Compile TypeScript
npm test # Compile tests + run Node built-in test runner
npm start # Start stdio MCP server
npm run start:http # Start HTTP server (requires express)Test suite
- 52 tests across 6 suites, all passing:
graphMetadata.test.ts- CRUD operations, navigation resolution, bound actions, typed body properties.connectorGenerator.test.ts- Swagger 2.0 output, OAuth2, x-ms-* extensions, action 204 responses, flat GET responses, typed body definitions, auto-split, YAML output, OpenAPI 3.0 output, all-formats output, $ref rewriting.schemaNormalizer.test.ts- allOf/oneOf/anyOf flattening, nullable handling, discriminator removal.transport.test.ts- JSON-RPC adapter, error responses.stdioE2E.test.ts- End-to-end stdin/stdout request/response.
Project structure
src/
index.ts # Stdio entry point
entry-http.ts # HTTP entry point (deferred)
server.ts # Composition root - createServerCore()
config/ # Config loader + types
logging/ # Stderr logger
modes/ # Mode definitions
policies/ # Path policy checks
tools/ # Tool contracts, registry, dispatch
types.ts # Input/output interfaces (incl. RequestBodyProperty)
index.ts # Registry + invokeTool()
graphMetadata.ts # CSDL fetch + cache + navigation + actions
schemaNormalizer.ts # Flatten + Swagger 2.0 downgrade
connectorGenerator.ts # Assemble + enrich + validate + correct responses
openapi3Converter.ts # Swagger 2.0 → OpenAPI 3.0.3 converter
transport/ # MCP adapter, stdio host, HTTP host
config/ # JSON config files
profiles/ # Dev + corporate config profiles
tests/ # Automated tests (52 tests, 6 suites)MCP JSON-RPC Examples
tools/list
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }graph.listOperations
{
"jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": {
"name": "graph.listOperations",
"arguments": { "endpoint": "/deviceManagement/managedDevices", "version": "beta" }
}
}graph.generateConnector
{
"jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": {
"name": "graph.generateConnector",
"arguments": {
"version": "beta",
"operationIds": ["managedDevices.list", "managedDevices.get", "managedDevices.retire", "managedDevices.wipe"],
"connectorName": "Intune Managed Device Actions",
"format": "all"
}
}
}Common error responses
-32600- Invalid request envelope.-32601- Method not found.-32602- Invalid params fortools/call.
Roadmap
- Activate HTTP transport with Express for web UI integration.
- Add
graph.validateConnectortool for pre-import Power Platform validation. - Add interactive web dashboard for endpoint browsing and connector preview.
- Add progress streaming for long-running CSDL fetch/conversion operations.
- Generate return type schemas from CSDL entity type properties (typed response objects).
- Consider shared infrastructure package across MCP agents (post-v1).
