Back to Home

Architecture

Overview

The Monta Partner API MCP Server is designed to expose Monta's charging infrastructure API through the Model Context Protocol (MCP). It provides a standardized interface for AI assistants and automation platforms to interact with charging networks.

MCP Primitives

The server implements all three core MCP primitives:

1. Tools (~185) - Dynamic Generation

Purpose: Execute API operations on the Monta platform

Generation Method: Dynamically generated from OpenAPI specification at server startup

How it works:

  1. Server fetches OpenAPI spec from https://docs.partner-api.monta.com/openapi/monta-partner-api-v1.yml (override with MONTA_OPENAPI_SPEC_URL)
  2. Parses all endpoints, methods, parameters, and schemas
  3. Creates one MCP tool per API endpoint
  4. Generates input schemas from OpenAPI parameters and request bodies
  5. Maps tool calls to HTTP requests via MontaClient

Examples:

Tool Naming Convention:

2. Resources (1) - Dynamic Generation

Purpose: Provide read-only contextual data to AI assistants

Generation Method: Dynamically exposed from loaded OpenAPI specification

Available Resources:

URI Name MimeType Description
openapi://spec Monta Partner API OpenAPI Specification application/x-yaml Complete OpenAPI spec with all endpoints, schemas, and documentation

Use Cases:

3. Prompts (4) - Static Templates

Purpose: Provide pre-built workflow templates for common tasks

Generation Method: Loaded from markdown files in prompts/ directory at server startup

File Format: Markdown with YAML frontmatter

---
name: prompt-name
description: What this prompt does
arguments:
  - name: argName
    description: Argument description
    required: true
---

# Prompt Content

Instructions and workflow steps...

Available Prompts:

Name Description Arguments
start-charging Guide to start a charging session chargePointId, chargeAuthId
monitor-charging Monitor active sessions and charge point status teamId
setup-webhooks Configure real-time event notifications webhookUrl
manage-infrastructure Manage teams, charge points, and vehicles operation

How Prompts Work:

  1. Files in prompts/ are parsed at server startup
  2. YAML frontmatter defines metadata and arguments
  3. Markdown content becomes the prompt template
  4. Arguments can be substituted using {{argumentName}} syntax
  5. AI assistants can list and retrieve prompts via MCP protocol

System Architecture

┌─────────────────────────────────────────────────────┐
│                  MCP Client                         │
│           (Claude, n8n, ChatGPT, etc.)             │
└───────────────────┬─────────────────────────────────┘
                    │ MCP Protocol
                    │ (HTTP/SSE/stdio)
┌───────────────────┴─────────────────────────────────┐
│              Monta MCP Server                       │
│                                                     │
│  ┌─────────────┐  ┌─────────────┐  ┌────────────┐ │
│  │   Tools     │  │ Resources   │  │  Prompts   │ │
│  │   (~185)    │  │     (1)     │  │    (4)     │ │
│  └──────┬──────┘  └──────┬──────┘  └──────┬─────┘ │
│         │                │                 │        │
│         │                │                 │        │
│  ┌──────┴────────────────┴─────────────────┴─────┐ │
│  │         OpenAPI Processor                      │ │
│  │  - Fetches OpenAPI spec                        │ │
│  │  - Generates tools dynamically                 │ │
│  │  - Exposes spec as resource                    │ │
│  │  - Loads prompt templates                      │ │
│  └────────────────────┬───────────────────────────┘ │
│                       │                             │
│  ┌────────────────────┴───────────────────────────┐ │
│  │         MontaClient (HTTP Client)              │ │
│  │  - OAuth token management                      │ │
│  │  - Request/response handling                   │ │
│  │  - Error handling and retries                  │ │
│  └────────────────────┬───────────────────────────┘ │
└───────────────────────┴─────────────────────────────┘
                        │
                        │ REST API
┌───────────────────────┴─────────────────────────────┐
│           Monta Partner API                         │
│       https://partner-api.monta.com                 │
└─────────────────────────────────────────────────────┘

Transport Layers

The server supports three transport protocols:

1. HTTP (Streamable HTTP)

2. SSE (Server-Sent Events)

3. stdio

Data Flow

Tool Execution Flow

1. Client Request
   ↓
2. MCP Protocol (tools/call)
   ↓
3. Tool Handler Lookup
   ↓
4. Argument Validation (Zod/JSON Schema)
   ↓
5. MontaClient Request
   ├─ OAuth Token Management
   ├─ HTTP Request Construction
   └─ API Call
   ↓
6. Response Processing
   ↓
7. MCP Protocol Response
   ↓
8. Client Receives Result

Resource Access Flow

1. Client Request (resources/read)
   ↓
2. Resource URI Lookup
   ↓
3. Resource Handler Execution
   ├─ openapi://spec → Return cached OpenAPI YAML
   └─ [Future resources...]
   ↓
4. MCP Protocol Response
   ↓
5. Client Receives Resource Content

Prompt Retrieval Flow

1. Client Request (prompts/get)
   ↓
2. Prompt Name Lookup
   ↓
3. Load Template from prompts/
   ↓
4. Argument Substitution
   ├─ Replace {{argName}} with values
   └─ Validate required arguments
   ↓
5. Return Prompt Messages
   ↓
6. Client Displays/Uses Prompt

Code Organization

src/
├── adapters/              # Transport layer implementations
│   ├── http.ts           # Streamable HTTP transport
│   ├── sse.ts            # Server-Sent Events transport
│   └── stdio.ts          # Standard I/O transport
├── client/               # API client layer
│   ├── monta-client.ts   # HTTP client with OAuth
│   └── oauth-handler.ts  # OAuth token management
├── utils/
│   └── openapi/          # OpenAPI processing utilities
│       ├── cache.ts      # OpenAPI spec caching
│       ├── tool-generator.ts      # Tools from OpenAPI
│       ├── resource-generator.ts  # Resources from OpenAPI
│       ├── prompt-generator.ts    # Prompts from files
│       ├── schema-processor.ts    # Schema conversion
│       └── types.ts      # TypeScript types
├── middleware/           # Express middleware
├── controllers/          # HTTP route handlers
└── routes/              # Express routes

prompts/                  # Prompt template files
├── start-charging.md
├── monitor-charging.md
├── setup-webhooks.md
└── manage-infrastructure.md

Server Initialization Sequence

async function createMCPServer(authConfig: any): Promise<Server> {
  // 1. Create server with capabilities
  const server = new Server({
    name: "monta-partner-api",
    version: "1.0.0",
  }, {
    capabilities: {
      tools: {},      // ~185 API endpoints
      resources: {},  // 1 OpenAPI spec
      prompts: {}     // 4 workflow templates
    },
  });

  // 2. Fetch OpenAPI spec (cached for 1 hour)
  const spec = await getOpenAPISpec();

  // 3. Create API client with auth
  const montaClient = new MontaClient(baseUrl, authConfig);

  // 4. Generate and setup TOOLS
  const { toolDescriptions, toolHandlers } = generateMCPTools(spec, montaClient);
  setupMCPHandlers(server, toolDescriptions, toolHandlers);
  console.log(`✓ Loaded ${toolDescriptions.size} tools`);

  // 5. Generate and setup RESOURCES
  const { resourceDescriptions, resourceHandlers } = generateMCPResources(spec);
  setupMCPResourceHandlers(server, resourceDescriptions, resourceHandlers);
  console.log(`✓ Loaded ${resourceDescriptions.size} resources`);

  // 6. Generate and setup PROMPTS
  const { promptDescriptions, promptHandlers } = generateMCPPrompts('./prompts');
  setupMCPPromptHandlers(server, promptDescriptions, promptHandlers);
  console.log(`✓ Loaded ${promptDescriptions.size} prompts`);

  return server;
}

Authentication

The server supports multiple authentication methods:

  1. OAuth Client Credentials (Recommended)

    • MONTA_CLIENT_ID + MONTA_CLIENT_SECRET
    • Automatic token acquisition and refresh
    • Tokens cached per session
  2. Bearer Token

    • MONTA_BEARER_TOKEN
    • Direct access token
    • No automatic refresh
  3. Request-level Auth (HTTP/SSE)

    • Authorization header (Bearer/Basic)
    • Custom headers (X-Monta-Auth, X-Monta-Client-Id/Secret)

Caching Strategy

OpenAPI Spec Cache

OAuth Token Cache

Error Handling

Tool Execution Errors

try {
  const result = await handler(args);
  return { content: [{ type: "text", text: JSON.stringify(result) }] };
} catch (error) {
  if (error.message?.includes('401')) {
    throw new Error('Authentication failed. Please check credentials.');
  }
  throw error; // Propagate to MCP client
}

Resource Access Errors

if (!resourceHandlers.has(uri)) {
  throw new Error(`Unknown resource: ${uri}`);
}

Prompt Errors

if (!promptHandlers.has(name)) {
  throw new Error(`Unknown prompt: ${name}`);
}

Extension Points

Adding New Resources

  1. Add resource definition in resource-generator.ts
  2. Implement handler function
  3. Register in generateMCPResources()

Adding New Prompts

  1. Create markdown file in prompts/
  2. Add YAML frontmatter with name, description, arguments
  3. Server automatically loads on next restart

Adding New Tools

Tools are automatically generated from OpenAPI spec. To add new tools:

  1. Add endpoint to Monta Partner API
  2. Update OpenAPI specification
  3. Server automatically discovers on next spec fetch

Performance Considerations

Security Considerations