{
  "openapi": "3.1.0",
  "info": {
    "title": "Umesh Malik developer resources",
    "summary": "MCP JSON-RPC API and discovery files for umesh-malik.com",
    "description": "Public, unauthenticated surface for Umesh Malik's portfolio and technical blog. The live API is POST /mcp and POST /api/v1/mcp (Model Context Protocol, Streamable HTTP, JSON-RPC 2.0). There are no webhooks, no write endpoints, and no OAuth tokens to mint. URL-path versioning: the current REST prefix is https://umesh-malik.com/api/v1. The live MCP JSON-RPC endpoint is POST https://umesh-malik.com/mcp (also POST https://umesh-malik.com/api/v1/mcp). Breaking changes ship as /api/v2; v1 keeps working. Deprecated operations send RFC 8594 Sunset and RFC 9745 Deprecation headers at least 90 days before removal. No operation is deprecated today. Pin /api/v1 or send API-Version: 1. Human docs: https://umesh-malik.com/developers.",
    "version": "1.0.0",
    "contact": {
      "name": "Umesh Malik",
      "email": "ask@umesh-malik.com",
      "url": "https://umesh-malik.com"
    },
    "license": {
      "name": "Content license: see /terms",
      "url": "https://umesh-malik.com/terms"
    }
  },
  "x-deprecation-policy": {
    "strategy": "url-path",
    "current": "https://umesh-malik.com/api/v1",
    "header": "API-Version",
    "sunset": "RFC 8594 Sunset + RFC 9745 Deprecation, minimum 90 days",
    "deprecated": []
  },
  "externalDocs": {
    "description": "Umesh Malik developer resources",
    "url": "https://umesh-malik.com/developers"
  },
  "servers": [
    {
      "url": "https://umesh-malik.com/api/v1",
      "description": "Umesh Malik REST API v1 (current). Pin this prefix."
    },
    {
      "url": "https://umesh-malik.com",
      "description": "Canonical origin. POST /mcp aliases POST /api/v1/mcp."
    }
  ],
  "tags": [
    {
      "name": "mcp",
      "description": "Live MCP JSON-RPC endpoint (Worker-metered)."
    },
    {
      "name": "v1",
      "description": "REST v1 catalog and versioned MCP alias."
    },
    {
      "name": "discovery",
      "description": "Prerendered machine-readable indexes."
    }
  ],
  "paths": {
    "/mcp": {
      "post": {
        "tags": [
          "mcp"
        ],
        "operationId": "mcpJsonRpc",
        "summary": "Call the Umesh Malik MCP server",
        "description": "JSON-RPC 2.0 over the MCP Streamable HTTP transport. Protocol 2025-06-18. Tools: search_posts, get_post, list_topics, get_profile. No session id is issued or required.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "const": "2.0"
                  },
                  "id": {
                    "description": "Request id. Omit for notifications."
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "initialize",
                      "ping",
                      "tools/list",
                      "tools/call"
                    ],
                    "description": "MCP JSON-RPC method."
                  },
                  "params": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              },
              "examples": {
                "initialize": {
                  "summary": "initialize",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "initialize",
                    "params": {}
                  }
                },
                "toolsList": {
                  "summary": "tools/list",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "tools/list",
                    "params": {}
                  }
                },
                "searchPosts": {
                  "summary": "search_posts",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "tools/call",
                    "params": {
                      "name": "search_posts",
                      "arguments": {
                        "query": "mcp",
                        "limit": 5
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC result or JSON-RPC error object.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "jsonrpc",
                        "result"
                      ],
                      "properties": {
                        "jsonrpc": {
                          "type": "string",
                          "const": "2.0"
                        },
                        "id": {},
                        "result": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "jsonrpc",
                        "error"
                      ],
                      "properties": {
                        "jsonrpc": {
                          "type": "string",
                          "const": "2.0"
                        },
                        "id": {
                          "description": "JSON-RPC id from the request, or null for parse errors."
                        },
                        "error": {
                          "type": "object",
                          "required": [
                            "code",
                            "message"
                          ],
                          "properties": {
                            "code": {
                              "type": "integer",
                              "description": "JSON-RPC error code."
                            },
                            "message": {
                              "type": "string"
                            },
                            "data": {
                              "type": "object",
                              "properties": {
                                "hint": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Notification acknowledged (no JSON-RPC response body)."
          },
          "400": {
            "description": "HTTP-level parse failure (body is not JSON).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jsonrpc",
                    "error"
                  ],
                  "properties": {
                    "jsonrpc": {
                      "type": "string",
                      "const": "2.0"
                    },
                    "id": {
                      "description": "JSON-RPC id from the request, or null for parse errors."
                    },
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "integer",
                          "description": "JSON-RPC error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "hint": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method. POST only. RFC 9457 JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "mcp"
        ],
        "operationId": "mcpGetNotAllowed",
        "summary": "GET is not supported on /mcp",
        "description": "This server is stateless and does not open an SSE stream. GET returns 405 with a JSON error envelope.",
        "responses": {
          "405": {
            "description": "Method not allowed.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "example": "POST, OPTIONS"
                }
              },
              "API-Version": {
                "schema": {
                  "type": "string",
                  "example": "1"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "https://umesh-malik.com/developers#method-not-allowed",
                  "title": "Method Not Allowed",
                  "status": 405,
                  "detail": "GET is not supported on /mcp. This endpoint is JSON-RPC 2.0 over HTTP POST.",
                  "code": "method_not_allowed",
                  "message": "GET is not supported on /mcp. This endpoint is JSON-RPC 2.0 over HTTP POST.",
                  "hint": "POST a JSON-RPC body to https://umesh-malik.com/mcp or https://umesh-malik.com/api/v1/mcp, or read https://umesh-malik.com/openapi.json."
                }
              }
            }
          }
        }
      },
      "options": {
        "tags": [
          "mcp"
        ],
        "operationId": "mcpCorsPreflight",
        "summary": "CORS preflight",
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "discovery"
        ],
        "operationId": "getOpenApi",
        "summary": "This OpenAPI document",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 specification.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": [
          "discovery"
        ],
        "operationId": "getLlmsTxt",
        "summary": "LLM-readable site index",
        "responses": {
          "200": {
            "description": "Plain-text Markdown index.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/404.json": {
      "get": {
        "tags": [
          "discovery"
        ],
        "operationId": "getNotFoundEnvelope",
        "summary": "Example JSON 404 envelope",
        "description": "Canonical example of a JSON error body. Missing paths still return HTTP 404; this file is the documented envelope, served as 200 at /404.json so agents can read the schema without synthesizing a miss. Unknown /api/* paths return the same envelope as HTTP 404 with Content-Type application/problem+json.",
        "responses": {
          "200": {
            "description": "Error envelope example.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api": {
      "get": {
        "tags": [
          "v1"
        ],
        "operationId": "getApiIndex",
        "summary": "REST version index",
        "description": "Lists current and historical REST prefixes. Pin /api/v1.",
        "responses": {
          "200": {
            "description": "Version index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1": {
      "get": {
        "tags": [
          "v1"
        ],
        "operationId": "getApiV1Catalog",
        "summary": "Umesh Malik REST API v1 catalog",
        "description": "Current versioned prefix. Breaking changes ship as /api/v2. Deprecated operations send Sunset/Deprecation headers at least 90 days before removal; none are deprecated today.",
        "responses": {
          "200": {
            "description": "v1 catalog.",
            "headers": {
              "API-Version": {
                "schema": {
                  "type": "string",
                  "example": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/openapi.json": {
      "get": {
        "tags": [
          "v1"
        ],
        "operationId": "getOpenApiV1",
        "summary": "OpenAPI 3.1 at the versioned prefix",
        "responses": {
          "200": {
            "description": "Same document as /openapi.json.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp": {
      "post": {
        "tags": [
          "v1",
          "mcp"
        ],
        "operationId": "mcpJsonRpcV1",
        "summary": "Versioned alias of POST /mcp",
        "description": "Same JSON-RPC handler as POST /mcp. Prefer this prefix when pinning a REST version.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC result or JSON-RPC error object."
          },
          "405": {
            "description": "Wrong HTTP method.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "v1",
          "mcp"
        ],
        "operationId": "mcpV1GetNotAllowed",
        "summary": "GET is not supported on /api/v1/mcp",
        "responses": {
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "ApiVersion": {
        "name": "API-Version",
        "in": "header",
        "required": false,
        "description": "Major REST version. Current: 1. Pin /api/v1 in the URL; this header echoes the same major.",
        "schema": {
          "type": "string",
          "enum": [
            "1"
          ],
          "default": "1"
        }
      }
    },
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code",
          "message",
          "hint"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "Absolute URL of the error code documentation on /developers."
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "detail": {
            "type": "string",
            "description": "RFC 9457 problem detail. Same text as message."
          },
          "code": {
            "type": "string",
            "description": "Stable machine code (snake_case). Branch on this, not on the message."
          },
          "message": {
            "type": "string",
            "description": "Alias of detail for clients that look for message."
          },
          "hint": {
            "type": "string",
            "description": "Where to look next (docs URL, valid method, or discovery file)."
          },
          "instance": {
            "type": "string",
            "description": "RFC 9457 instance — the request path that failed, when known."
          }
        }
      },
      "JsonRpcError": {
        "type": "object",
        "required": [
          "jsonrpc",
          "error"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "description": "JSON-RPC id from the request, or null for parse errors."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "integer",
                "description": "JSON-RPC error code."
              },
              "message": {
                "type": "string"
              },
              "data": {
                "type": "object",
                "properties": {
                  "hint": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
