{
  "openapi": "3.1.0",
  "info": {
    "title": "Traveler.md agent API",
    "summary": "Permissioned access to a traveler's own portable travel memory, so an assistant can plan for who someone actually is.",
    "description": "**Memory that travels with you.** Traveler.md gives a traveler two plain-markdown documents they own. `traveler.md` is who they are as a traveler and it persists: style, pace, and budget; airline, seat, and hotel preferences; loyalty status; dietary and accessibility needs; dealbreakers; the trips they dream about. `trip.md` is one file per journey and it evolves, from a loose idea to a complete record of what was booked and what they loved.\n\nThe point is that it is portable. The traveler fills it in once and authorizes whichever assistants, agents, and travel services they choose, so nobody has to re-interview them and every connected tool gets better at the same time.\n\nAgents reach that memory through a Model Context Protocol server at `https://mcp.traveler.md/mcp` using the Streamable HTTP transport. Every call is authorized by the traveler through OAuth 2.1 with a least-privilege scope, is visible to them in an audit trail, and is revocable at any time. See `x-mcp-tools` for the tool inventory and the scope each tool requires.\n\nThere is no partner agreement and no API key to request. Dynamic client registration is open, so the traveler's own account and consent screen are the whole of the onboarding.\n\nThis document covers only endpoints that are live today. The standalone REST API for profiles and trips is pre-launch: request access from https://traveler.md/developers.",
    "version": "2026-08-24",
    "contact": {
      "name": "TravelAI partnerships",
      "email": "partnerships@traveler.md",
      "url": "https://traveler.md/developers"
    },
    "license": {
      "name": "Terms of service",
      "url": "https://traveler.md/terms"
    }
  },
  "externalDocs": {
    "description": "Traveler.md developer documentation",
    "url": "https://docs.traveler.md"
  },
  "servers": [
    {
      "url": "https://mcp.traveler.md",
      "description": "Traveler.md MCP server"
    }
  ],
  "security": [
    {
      "travelerOAuth": []
    }
  ],
  "paths": {
    "/mcp": {
      "post": {
        "operationId": "callMcpEndpoint",
        "summary": "Send a Model Context Protocol JSON-RPC request",
        "description": "The single MCP entry point, using the Streamable HTTP transport. Send `initialize` first, then `tools/list` to discover tools and `tools/call` to invoke one. Responses are `application/json` or, when the server streams, `text/event-stream`. An unauthenticated call answers 401 with a `WWW-Authenticate` header naming the protected-resource metadata document.",
        "tags": [
          "MCP"
        ],
        "security": [
          {
            "travelerOAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Mcp-Session-Id",
            "in": "header",
            "required": false,
            "description": "Session id returned by `initialize`. Send it on every later request in the session.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "MCP-Protocol-Version",
            "in": "header",
            "required": false,
            "description": "Negotiated MCP protocol version.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "A single JSON-RPC 2.0 request as defined by the Model Context Protocol. `method` is an MCP method such as `initialize`, `tools/list`, or `tools/call`.",
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "const": "2.0"
                  },
                  "id": {
                    "description": "Request id. Omit for a notification, which receives HTTP 202 and no body.",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      }
                    ]
                  },
                  "method": {
                    "type": "string",
                    "description": "MCP method name.",
                    "examples": [
                      "initialize",
                      "tools/list",
                      "tools/call",
                      "resources/list"
                    ]
                  },
                  "params": {
                    "type": "object",
                    "description": "Method parameters. For `tools/call`, `{ name, arguments }` where `name` is one of the tools listed in `x-mcp-tools`.",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "jsonrpc",
                  "method"
                ]
              },
              "examples": {
                "listTools": {
                  "summary": "Discover the available tools",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "tools/list"
                  }
                },
                "readProfile": {
                  "summary": "Read the traveler's profile",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/call",
                    "params": {
                      "name": "read_profile",
                      "arguments": {
                        "sections": [
                          "flight_preferences"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC result or error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "A JSON-RPC 2.0 response. Exactly one of `result` or `error`.",
                  "properties": {
                    "jsonrpc": {
                      "type": "string",
                      "const": "2.0"
                    },
                    "id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "integer"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "error": {
                      "type": "object",
                      "description": "JSON-RPC 2.0 error object.",
                      "properties": {
                        "code": {
                          "type": "integer",
                          "description": "JSON-RPC error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "data": {
                          "description": "Optional structured detail."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "jsonrpc",
                    "id"
                  ]
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-sent events, each `data:` line carrying one JSON-RPC message."
                }
              }
            }
          },
          "202": {
            "description": "Notification accepted. No body."
          },
          "401": {
            "description": "Missing, malformed, or expired bearer token. Carries `WWW-Authenticate: Bearer resource_metadata=\"…\"`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Transport-level error envelope returned before MCP dispatch.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "examples": [
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "RATE_LIMITED"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but lacks the scope this tool requires.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Transport-level error envelope returned before MCP dispatch.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "examples": [
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "RATE_LIMITED"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Transport-level error envelope returned before MCP dispatch.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "examples": [
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "RATE_LIMITED"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "operationId": "getProtectedResourceMetadata",
        "summary": "OAuth protected-resource metadata for the MCP server",
        "description": "RFC 9728 metadata. Names the authorization servers that issue tokens for the MCP endpoint and the full set of scopes it recognizes. Start discovery here.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Protected-resource metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "OAuth 2.0 Protected Resource Metadata (RFC 9728).",
                  "properties": {
                    "resource": {
                      "type": "string",
                      "format": "uri"
                    },
                    "authorization_servers": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      }
                    },
                    "bearer_methods_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "scopes_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "resource",
                    "authorization_servers"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-authorization-server": {
      "servers": [
        {
          "url": "https://connect.traveler.md",
          "description": "Traveler.md authorization server"
        }
      ],
      "get": {
        "operationId": "getAuthorizationServerMetadata",
        "summary": "OAuth authorization server metadata",
        "description": "RFC 8414 metadata for the Traveler.md authorization server, including the authorization, token, revocation, and dynamic-registration endpoints and the supported PKCE methods.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Authorization server metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "OAuth 2.0 Authorization Server Metadata (RFC 8414).",
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri"
                    },
                    "authorization_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "token_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "revocation_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "registration_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "jwks_uri": {
                      "type": "string",
                      "format": "uri"
                    },
                    "scopes_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "grant_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "code_challenge_methods_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "issuer",
                    "authorization_endpoint",
                    "token_endpoint"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/oauth/register": {
      "servers": [
        {
          "url": "https://connect.traveler.md",
          "description": "Traveler.md authorization server"
        }
      ],
      "post": {
        "operationId": "registerOAuthClient",
        "summary": "Register an OAuth client dynamically",
        "description": "RFC 7591 dynamic client registration. Open registration — no initial access token is required, so an agent can onboard itself without a support ticket.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_name": {
                    "type": "string"
                  },
                  "redirect_uris": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    }
                  },
                  "grant_types": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "token_endpoint_auth_method": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string",
                    "description": "Space-delimited scopes to request."
                  }
                },
                "required": [
                  "redirect_uris"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Client registered.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Dynamic client registration response (RFC 7591 §3.2.1).",
                  "properties": {
                    "client_id": {
                      "type": "string"
                    },
                    "client_secret": {
                      "type": "string"
                    },
                    "client_id_issued_at": {
                      "type": "integer"
                    },
                    "redirect_uris": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      }
                    },
                    "token_endpoint_auth_method": {
                      "type": "string"
                    },
                    "grant_types": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "client_id"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid registration request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Transport-level error envelope returned before MCP dispatch.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "examples": [
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "RATE_LIMITED"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/oauth/authorize": {
      "servers": [
        {
          "url": "https://connect.traveler.md",
          "description": "Traveler.md authorization server"
        }
      ],
      "get": {
        "operationId": "startOAuthAuthorization",
        "summary": "Start the authorization code flow",
        "description": "Redirects the traveler to Traveler.md to approve the requested scopes. PKCE with S256 is required.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "description": "Always `code`. Only the authorization code flow is supported.",
            "schema": {
              "type": "string",
              "const": "code"
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "description": "Client id issued by dynamic registration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "description": "One of the redirect URIs registered for this client.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": true,
            "description": "Space-delimited subset of the supported scopes.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": true,
            "description": "Opaque CSRF value returned unchanged on the redirect back.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "required": true,
            "description": "Base64url-encoded SHA-256 digest of the PKCE code verifier.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": true,
            "description": "Always `S256`. Plain PKCE challenges are rejected.",
            "schema": {
              "type": "string",
              "const": "S256"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the consent screen, then back to `redirect_uri` with `code` and `state`."
          },
          "400": {
            "description": "Invalid authorization request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Transport-level error envelope returned before MCP dispatch.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "examples": [
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "RATE_LIMITED"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/oauth/token": {
      "servers": [
        {
          "url": "https://connect.traveler.md",
          "description": "Traveler.md authorization server"
        }
      ],
      "post": {
        "operationId": "exchangeOAuthToken",
        "summary": "Exchange an authorization code or refresh token",
        "description": "Supports the `authorization_code` and `refresh_token` grants. The granted `scope` in the response may be narrower than the one requested.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "refresh_token"
                    ]
                  },
                  "code": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string",
                    "format": "uri"
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "code_verifier": {
                    "type": "string"
                  },
                  "refresh_token": {
                    "type": "string"
                  }
                },
                "required": [
                  "grant_type"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Access token issued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "OAuth 2.1 token endpoint response (RFC 6749 §5.1).",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "const": "Bearer"
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Lifetime in seconds."
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "string",
                      "description": "Space-delimited list of granted scopes."
                    }
                  },
                  "required": [
                    "access_token",
                    "token_type"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid grant.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Transport-level error envelope returned before MCP dispatch.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "examples": [
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "RATE_LIMITED"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/oauth/revoke": {
      "servers": [
        {
          "url": "https://connect.traveler.md",
          "description": "Traveler.md authorization server"
        }
      ],
      "post": {
        "operationId": "revokeOAuthToken",
        "summary": "Revoke an access or refresh token",
        "description": "RFC 7009 revocation. Answers 200 whether or not the token existed.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "token_type_hint": {
                    "type": "string",
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ]
                  }
                },
                "required": [
                  "token"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token revoked or already invalid."
          }
        }
      }
    },
    "/v1/oauth/jwks.json": {
      "servers": [
        {
          "url": "https://connect.traveler.md",
          "description": "Traveler.md authorization server"
        }
      ],
      "get": {
        "operationId": "getOAuthJwks",
        "summary": "Public signing keys",
        "description": "JSON Web Key Set used to verify issued access tokens.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "JSON Web Key Set (RFC 7517).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "keys"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "travelerOAuth": {
        "type": "oauth2",
        "description": "OAuth 2.1 authorization code flow with PKCE (S256) and open dynamic client registration. Request the narrowest set of scopes the task needs: the traveler sees and approves each one on the consent screen, and can revoke any of them later without losing the underlying files.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://connect.traveler.md/v1/oauth/authorize",
            "tokenUrl": "https://connect.traveler.md/v1/oauth/token",
            "refreshUrl": "https://connect.traveler.md/v1/oauth/token",
            "scopes": {
              "profile.read": "Read the traveler's traveler.md profile: how they travel, what they prefer, and what they will not accept.",
              "profile.create": "Start the traveler's traveler.md profile when they do not have one yet.",
              "profile.update": "Write approved preference updates back to the profile, so what is learned here reaches the traveler's next assistant.",
              "trip.list": "List the traveler's trips, dreamed of, planned, booked, in progress, or past.",
              "trip.read": "Read one trip.md in full: dates, status, bookings, and everything recorded about that journey.",
              "trip.create": "Open a new trip.md, including for an idea the traveler is only dreaming about.",
              "trip.update": "Update an existing trip.md as plans firm up, or archive it out of the active list."
            }
          }
        }
      }
    },
    "schemas": {
      "JsonRpcRequest": {
        "type": "object",
        "description": "A single JSON-RPC 2.0 request as defined by the Model Context Protocol. `method` is an MCP method such as `initialize`, `tools/list`, or `tools/call`.",
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "description": "Request id. Omit for a notification, which receives HTTP 202 and no body.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              }
            ]
          },
          "method": {
            "type": "string",
            "description": "MCP method name.",
            "examples": [
              "initialize",
              "tools/list",
              "tools/call",
              "resources/list"
            ]
          },
          "params": {
            "type": "object",
            "description": "Method parameters. For `tools/call`, `{ name, arguments }` where `name` is one of the tools listed in `x-mcp-tools`.",
            "additionalProperties": true
          }
        },
        "required": [
          "jsonrpc",
          "method"
        ]
      },
      "JsonRpcResponse": {
        "type": "object",
        "description": "A JSON-RPC 2.0 response. Exactly one of `result` or `error`.",
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "result": {
            "type": "object",
            "additionalProperties": true
          },
          "error": {
            "type": "object",
            "description": "JSON-RPC 2.0 error object.",
            "properties": {
              "code": {
                "type": "integer",
                "description": "JSON-RPC error code."
              },
              "message": {
                "type": "string"
              },
              "data": {
                "description": "Optional structured detail."
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id"
        ]
      },
      "JsonRpcError": {
        "type": "object",
        "description": "JSON-RPC 2.0 error object.",
        "properties": {
          "code": {
            "type": "integer",
            "description": "JSON-RPC error code."
          },
          "message": {
            "type": "string"
          },
          "data": {
            "description": "Optional structured detail."
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "ApiError": {
        "type": "object",
        "description": "Transport-level error envelope returned before MCP dispatch.",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "examples": [
                  "UNAUTHORIZED",
                  "FORBIDDEN",
                  "RATE_LIMITED"
                ]
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "ProtectedResourceMetadata": {
        "type": "object",
        "description": "OAuth 2.0 Protected Resource Metadata (RFC 9728).",
        "properties": {
          "resource": {
            "type": "string",
            "format": "uri"
          },
          "authorization_servers": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "bearer_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "resource",
          "authorization_servers"
        ]
      },
      "AuthorizationServerMetadata": {
        "type": "object",
        "description": "OAuth 2.0 Authorization Server Metadata (RFC 8414).",
        "properties": {
          "issuer": {
            "type": "string",
            "format": "uri"
          },
          "authorization_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "token_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "revocation_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "registration_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "jwks_uri": {
            "type": "string",
            "format": "uri"
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "grant_types_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "code_challenge_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "issuer",
          "authorization_endpoint",
          "token_endpoint"
        ]
      },
      "TokenResponse": {
        "type": "object",
        "description": "OAuth 2.1 token endpoint response (RFC 6749 §5.1).",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "const": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "description": "Lifetime in seconds."
          },
          "refresh_token": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "description": "Space-delimited list of granted scopes."
          }
        },
        "required": [
          "access_token",
          "token_type"
        ]
      },
      "ClientRegistrationResponse": {
        "type": "object",
        "description": "Dynamic client registration response (RFC 7591 §3.2.1).",
        "properties": {
          "client_id": {
            "type": "string"
          },
          "client_secret": {
            "type": "string"
          },
          "client_id_issued_at": {
            "type": "integer"
          },
          "redirect_uris": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "token_endpoint_auth_method": {
            "type": "string"
          },
          "grant_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "client_id"
        ]
      }
    }
  },
  "tags": [
    {
      "name": "MCP",
      "description": "Model Context Protocol endpoint."
    },
    {
      "name": "Discovery",
      "description": "Machine-readable metadata documents."
    },
    {
      "name": "OAuth",
      "description": "Authorization server endpoints."
    }
  ],
  "x-mcp-server": {
    "endpoint": "https://mcp.traveler.md/mcp",
    "transport": "Streamable HTTP",
    "protectedResourceMetadata": "https://mcp.traveler.md/.well-known/oauth-protected-resource",
    "authorizationServer": "https://connect.traveler.md",
    "documentation": "https://docs.traveler.md/mcp"
  },
  "x-mcp-tools": [
    {
      "name": "read_profile",
      "title": "Read traveler profile",
      "description": "Read the authenticated traveler's traveler.md profile. Call this before recommending, planning, booking, or shortlisting anything travel-related.",
      "requiredScope": "profile.read",
      "readOnly": true,
      "requiresUserConfirmation": false,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "create_profile",
      "title": "Create traveler profile",
      "description": "Create the traveler.md profile the first time a traveler describes how they travel. Fails if a profile already exists.",
      "requiredScope": "profile.create",
      "readOnly": false,
      "requiresUserConfirmation": false,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "update_profile",
      "title": "Update traveler profile",
      "description": "Record a lasting travel preference on the profile. Sections are replaced wholesale, so send the complete sentence list for each section you include.",
      "requiredScope": "profile.update",
      "readOnly": false,
      "requiresUserConfirmation": true,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "list_trips",
      "title": "List trips",
      "description": "Find the traveler's trips by status, date range, or substring, and get each trip_id. Paginated with an opaque cursor.",
      "requiredScope": "trip.list",
      "readOnly": true,
      "requiresUserConfirmation": false,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "read_trip",
      "title": "Read trip",
      "description": "Read one trip.md in full: envelope, sections, and the version_hash needed for a later update.",
      "requiredScope": "trip.read",
      "readOnly": true,
      "requiresUserConfirmation": false,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "create_trip",
      "title": "Create trip",
      "description": "Open a new trip, including a loosely held idea at status Dreaming. Supply an idempotency_key; a retry without one creates a second trip.",
      "requiredScope": "trip.create",
      "readOnly": false,
      "requiresUserConfirmation": false,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "update_trip",
      "title": "Update trip",
      "description": "Write decisions and bookings back onto a trip, or move its status along. Requires the last-known expected_version_hash.",
      "requiredScope": "trip.update",
      "readOnly": false,
      "requiresUserConfirmation": true,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    },
    {
      "name": "archive_trip",
      "title": "Archive trip",
      "description": "Remove a trip from the active list. Nothing is deleted, but only the traveler can restore it from their portal, so ask before calling.",
      "requiredScope": "trip.update",
      "readOnly": false,
      "requiresUserConfirmation": true,
      "inputSchemaSource": "https://docs.traveler.md/mcp/tools"
    }
  ]
}
