{
  "openapi": "3.1.0",
  "info": {
    "title": "MoveMate MCP API",
    "version": "1.2.0",
    "summary": "Remote Model Context Protocol server for the MoveMate gym workout tracker.",
    "description": "MoveMate is a remote MCP server, not a resource-oriented REST API.\n\nClients authenticate with OAuth 2.1 (authorization code + PKCE S256, dynamic client registration supported), then speak JSON-RPC 2.0 over Streamable HTTP at POST /mcp.\n\nAfter `initialize`, call `tools/list` for live schemas and `tools/call` to invoke a tool. Every tool acts on the connected user’s own MoveMate account only.\n\nChatGPT plugin: https://chatgpt.com/plugins/plugin_asdk_app_6a7b250ad83c8191a519b763350af4e9 (install guide: https://movemate.app/connect/chatgpt) · Claude: https://claude.ai/directory/movemate-gym-workout-tracker · Overview: https://movemate.app/ai",
    "termsOfService": "https://movemate.app/terms-of-use",
    "contact": {
      "name": "MoveMate",
      "email": "support@movemate.app",
      "url": "https://movemate.app"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://movemate.app/terms-of-use"
    }
  },
  "externalDocs": {
    "description": "Integration overview and setup guides",
    "url": "https://movemate.app/ai"
  },
  "servers": [
    {
      "url": "https://api.movemate.app",
      "description": "Production MCP host"
    }
  ],
  "tags": [
    {
      "name": "MCP",
      "description": "Streamable HTTP JSON-RPC transport"
    },
    {
      "name": "OAuth",
      "description": "RFC 8414 / RFC 9728 discovery, used by MCP clients before the first authenticated call."
    },
    {
      "name": "Health",
      "description": "Unauthenticated liveness"
    }
  ],
  "security": [
    {
      "oauth2": [
        "profile:read",
        "stats:read",
        "library:read",
        "workouts:write"
      ]
    }
  ],
  "paths": {
    "/mcp": {
      "post": {
        "tags": [
          "MCP"
        ],
        "operationId": "mcpJsonRpc",
        "summary": "MCP Streamable HTTP endpoint",
        "description": "JSON-RPC 2.0 over Streamable HTTP. Requires a Bearer access token from the OAuth flow. Clients must send `Accept: application/json, text/event-stream`.",
        "security": [
          {
            "oauth2": [
              "profile:read",
              "stats:read",
              "library:read",
              "workouts:write"
            ]
          },
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              },
              "examples": {
                "toolsList": {
                  "summary": "tools/list",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "tools/list",
                    "params": {}
                  }
                },
                "toolsCall": {
                  "summary": "tools/call get_training_stats",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/call",
                    "params": {
                      "name": "get_training_stats",
                      "arguments": {
                        "period": "last_30d"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC success or error envelope, or a text/event-stream for streamed results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer token. Follow WWW-Authenticate to the protected-resource metadata.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "Bearer challenge pointing at https://api.movemate.app/.well-known/oauth-protected-resource"
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "operationId": "getProtectedResourceMetadata",
        "summary": "OAuth protected resource metadata (RFC 9728)",
        "security": [],
        "responses": {
          "200": {
            "description": "Protected resource metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-authorization-server": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "operationId": "getAuthorizationServerMetadata",
        "summary": "OAuth authorization server metadata (RFC 8414)",
        "security": [],
        "responses": {
          "200": {
            "description": "Authorization server metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/_health": {
      "get": {
        "tags": [
          "Health"
        ],
        "operationId": "getHealth",
        "summary": "API liveness",
        "security": [],
        "responses": {
          "204": {
            "description": "Healthy"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.1 authorization code with PKCE S256. Dynamic client registration (RFC 7591) at /oauth/register.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.movemate.app/oauth/authorize",
            "tokenUrl": "https://api.movemate.app/oauth/token",
            "refreshUrl": "https://api.movemate.app/oauth/token",
            "scopes": {
              "profile:read": "Read the connected user’s profile and body stats",
              "stats:read": "Read training history, stats, progression, personal records and planned workouts",
              "library:read": "Read the exercise library and workouts, including the user’s own",
              "workouts:write": "Save, edit, schedule, reschedule and cancel workouts, add custom exercises, and log finished workouts"
            }
          }
        }
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Access token from the token endpoint, sent as `Authorization: Bearer <token>`."
      }
    },
    "schemas": {
      "JsonRpcRequest": {
        "type": "object",
        "required": [
          "jsonrpc",
          "method"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              }
            ]
          },
          "method": {
            "type": "string",
            "enum": [
              "initialize",
              "tools/list",
              "tools/call",
              "ping",
              "notifications/initialized"
            ]
          },
          "params": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "required": [
          "jsonrpc"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "result": {
            "type": "object",
            "additionalProperties": true
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              },
              "data": {}
            }
          }
        }
      },
      "ToolCallParams": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "get_profile",
              "get_body_profile",
              "search_exercises",
              "list_workouts",
              "get_workout",
              "get_workout_details",
              "get_training_stats",
              "get_recent_workouts",
              "get_exercise_progression",
              "get_personal_records",
              "list_planned_workouts",
              "create_custom_exercise",
              "create_custom_workout",
              "update_custom_workout",
              "create_planned_workout",
              "update_planned_workout",
              "delete_planned_workout",
              "log_completed_workouts"
            ]
          },
          "arguments": {
            "type": "object",
            "additionalProperties": true,
            "description": "See tools/list for each tool’s input schema."
          }
        }
      }
    }
  },
  "x-mcp-endpoint": "https://api.movemate.app/mcp",
  "x-mcp-transport": "streamable-http",
  "x-pkce": "S256",
  "x-chatgpt-plugin": {
    "name": "MoveMate: Gym Workout Tracker",
    "url": "https://chatgpt.com/plugins/plugin_asdk_app_6a7b250ad83c8191a519b763350af4e9",
    "installGuide": "https://movemate.app/connect/chatgpt"
  },
  "x-mcp-tools": [
    {
      "name": "get_profile",
      "summary": "Display name, timezone, and training frequency — lightweight context used implicitly.",
      "access": "read",
      "scope": "profile:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_body_profile",
      "summary": "Height, weight, age, gender, fitness level, activity level, goals, and equipment.",
      "access": "read",
      "scope": "profile:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "search_exercises",
      "summary": "MoveMate’s exercise library, including your own custom exercises.",
      "access": "read",
      "scope": "library:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "list_workouts",
      "summary": "MoveMate’s workout catalog, including your own custom workouts.",
      "access": "read",
      "scope": "library:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_workout",
      "summary": "A specific MoveMate workout by ID, displayed as a workout card.",
      "access": "read",
      "scope": "library:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_workout_details",
      "summary": "The full contents of a workout — every exercise, set, target and superset — read before any change, so nothing gets lost.",
      "access": "read",
      "scope": "library:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_training_stats",
      "summary": "Totals, volume, weekday frequency, and streak over a rolling period.",
      "access": "read",
      "scope": "stats:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_recent_workouts",
      "summary": "Recent completed workouts set by set — including plan vs. actual, skipped sets, reps, weight, duration, and distance.",
      "access": "read",
      "scope": "stats:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_exercise_progression",
      "summary": "Per-exercise progress over time — bodyweight work by total reps, with weighted and unweighted sessions kept in separate series.",
      "access": "read",
      "scope": "stats:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "get_personal_records",
      "summary": "Your best set per exercise, by estimated one-rep max.",
      "access": "read",
      "scope": "stats:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "list_planned_workouts",
      "summary": "What’s coming up, so the model can avoid double-booking.",
      "access": "read",
      "scope": "stats:read",
      "readOnlyHint": true,
      "destructiveHint": false
    },
    {
      "name": "create_custom_exercise",
      "summary": "Adds a new exercise to your own library when the built-in one doesn't have what you're after — matches muscle group and equipment by name automatically.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": false
    },
    {
      "name": "create_custom_workout",
      "summary": "Saves a new workout to My workouts without putting it on the calendar — always asks before saving.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": false
    },
    {
      "name": "update_custom_workout",
      "summary": "Edits one of your saved workouts — add or swap an exercise, rename it. Sessions scheduled from it change too.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": true
    },
    {
      "name": "create_planned_workout",
      "summary": "Schedules a workout on a chosen date — a new one, one of your saved workouts, or one from the MoveMate library — always asks before scheduling.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": false
    },
    {
      "name": "update_planned_workout",
      "summary": "Reschedules a planned workout, renames it, or replaces its exercise list — only for workouts that haven't happened yet.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": true
    },
    {
      "name": "delete_planned_workout",
      "summary": "Cancels a planned workout and takes it off your schedule — your saved workout stays in My workouts.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": true
    },
    {
      "name": "log_completed_workouts",
      "summary": "Adds workouts you've already done to your history — from the last two weeks, or older ones from your notes if you're new to MoveMate. Not a live tracker: set-by-set logging stays in the app.",
      "access": "write",
      "scope": "workouts:write",
      "readOnlyHint": false,
      "destructiveHint": false
    }
  ]
}