Postmanコレクション(v2.0またはv2.1)を完全なOpenAPI 3.0仕様ファイルに変換します。コレクション全体とオプションの環境ファイルを読み込み、APIの経路、HTTPメソッド、パラメータ、リクエスト本体、レスポンス本体、ヘッダー(通信時の付加情報)、およびレスポンスコード(応答ステータス)を抽出します。 次のような場合に使用: ユーザーがPostmanコレクションからOAS(OpenAPI仕様)ファイルを生成・作成・導出したい場合。「postman to openapi」「postmanコレクションをOASに変換」「postmanからスペックを生成」「postmanからopenapi作成」といった表現や、既存のOASファイルがない状態でPostmanコレクションをOpenAPI仕様に変換するリクエストに反応します。
Convert a Postman collection (v2.0 or v2.1) into a complete OpenAPI 3.0 specification file. Reads the full collection and optional environment file to extract paths, methods, parameters, request bodies, response bodies, headers, and response codes. Use when the user wants to generate, create, or derive an OAS file from a Postman collection. Triggers on phrases like "convert postman to openapi", "postman collection to OAS", "generate spec from postman", "create openapi from postman", or any request to turn a Postman collection into an OpenAPI spec without an existing OAS file.
Convert a Postman collection into a complete, valid OpenAPI 3.0 specification
file (openapi.json). No existing OAS file is required as input.
Ask the user for the required inputs, then execute Steps 1–8.
Call AskUserQuestion:
Please provide the following inputs:
1. Postman collection file path (JSON, v2.0 or v2.1)
2. Postman environment file path (optional, JSON — skip if none)
3. Output file path for the generated OpenAPI spec (default: openapi.json in the collection's directory)
["Provide paths one by one", "Provide all paths at once", "Cancel"]
After collecting inputs:
"I'll read the Postman collection and generate a complete OAS 3.0 spec at
<output path>. This may take a moment."
Read the full contents of the Postman collection file. Confirm it is valid
Postman format by checking for info.schema containing postman-collection.
Identify the schema version:
v2.1.0v2.0.0Both versions are handled identically in subsequent steps.
Extract top-level metadata:
info.name → candidate for info.title in the OASinfo.description → candidate for info.description in the OASinfo.version → candidate for info.version in the OAS (fall back to "1.0.0")variable[] → collection-level variables (key/value pairs used as defaults)If an environment file path was provided, read it and parse its values array
into a flat map: { key: value }. These environment values take precedence
over collection-level variables when resolving {{variableName}} placeholders.
Environment values are also a preferred source of concrete examples in the
generated OAS when they map to request or response fields (for example:
userId, picture_id, token, baseUrl).
Build a merged variable map:
variable[] entriesvalues[] entries (same key wins from environment)Build an example-value map from the same merged variables and use it when
filling parameter and schema example fields.
Postman collections nest requests inside item arrays. Folders are item
entries that themselves contain an item array (no request property).
Requests are leaf item entries with a request property.
Recursively walk the entire item tree:
item (array): it is a folder — recurse into it, tracking
the folder name(s) as a breadcrumb for tag assignmentrequest: it is a leaf request — extract itTrack folder breadcrumbs: the top-level folder name becomes the OAS tag.
For each leaf request, extract:
item.request.url.raw (or item.request.url if it is a string){{variableName}} placeholders using the merged variable mapitem.request.url.path[] — join with /, prefix with /item.request.url.host[] — join with . to form the hostnameitem.request.url.protocol (default https)item.request.url.port if presentitem.request.method — normalize to uppercase: GET, POST, PUT, DELETE,
PATCH, HEAD, OPTIONS
item.request.url.variable[] → { key, value } — these are concrete values
for {variableName} placeholders in the path segments.
Identify parameterized path segments:
{{...}} or :name or {name} style is a path parameterurl.variable keys to determine the canonical OAS parameter name{paramName}item.request.url.query[] → { key, value, description, disabled }
disabled: true{{variableName}} in values using the variable mapitem.request.header[] → { key, value, description, disabled }
disabled: trueContent-Type and Accept (these map to OAS content / produces){{variableName}} in valuesAuthorization headers only to infer security schemes — do not emit
them as explicit header parametersitem.request.body:
mode: raw and options.raw.language: json → parse raw string as JSON;
if parse fails, treat as a raw string schemamode: raw and language is xml, text, html → record content type as
text/xml or text/plain; do not attempt to parse the body furthermode: formdata → collect { key, value, type } pairs (type is text or file)mode: urlencoded → collect { key, value } pairsmode: graphql → record as application/json with a GraphQL body shapemode: file → record as multipart/form-data with a binary file fieldmode: none → omit requestBody entirelySkip bodies that contain obvious attack payloads:
SELECT, UNION, DROP, INSERT, UPDATE, DELETE, --$ne, $gt, $lt, $where, $regex<!DOCTYPE, ENTITY, CDATA../, ..\Skip attack-oriented requests entirely (do not emit them into paths):
Attacks, Security Tests, Exploits, Abuse, Negative TestsSQL Injection, NoSQL Injection, XSS, XXE, Path Traversal,
Log4Shell, Password Leakage, Privilege Escalation, BOLA, BFLA,
Un-authenticated Access, Invalid JSON, HTTP Verb Tampering../)When in doubt, prefer excluding security test/demo requests from the OAS contract and note the exclusion in the conversion summary.
item.response[] — each saved response in Postman:
status → HTTP status code (integer)name → human-readable label for the response descriptionheader[] → response headers { key, value }body → response body string; if parseable as JSON, parse it_postman_previewlanguage → json, html, text, xmlIf a request has no saved responses, the operation gets no responses entries
other than a placeholder default (see Step 7.5 — Response rules).
Walk every request's Authorization header and auth block:
auth block (item.request.auth)type: bearer → Bearer JWT auth → securityScheme type http, scheme bearer, bearerFormat: JWTtype: basic → Basic auth → securityScheme type http, scheme basictype: apikey → API key → check in field: header, query, or cookietype: oauth2 → OAuth2; extract authUrl, accessTokenUrl, scope where availabletype: noauth → explicitly public — no securityauthIf the collection root has an auth block, it applies as the default to all
requests unless overridden per-request.
Authorization header value patternsBearer {{token}} or Bearer <anything> → bearer JWTBasic {{credentials}} or Basic <base64> → basic authApiKey <value> → API key in headerDeduplicate: if the same auth pattern appears across multiple requests, define
it once in components.securitySchemes with a canonical name:
BearerAuth, BasicAuth, ApiKeyAuth, ApiKeyQuery, OAuth2Track which requests use which scheme. A request with type: noauth gets
"security": [] in its operation.
From the resolved URLs of all requests:
protocol://host:port combinationsservers[0].urllocalhost and a production domain):
servers[]description to each: "Local development", "Production", etc.{{baseUrl}} or similar variables, emit a
server variable:"servers": [{
"url": "{baseUrl}",
"variables": {
"baseUrl": { "default": "<resolved value from environment>" }
}
}]
http://localhost if no base URL can be determinedStrip the base URL from each request's path before building paths entries.
For each unique request body (grouped by path + method):
Analyze the parsed JSON object and infer a JSON Schema:
type: objectproperties entrytype from the value:
string → type: string; check for ISO date patterns → add format: date-timenumber with no decimal → type: integernumber with decimal → type: numberboolean → type: booleannull → nullable: true on the property (OAS 3.0 style)type: array; infer items schema from the first elementtype: object; recurserequired if its value is non-null and non-empty
(heuristic: present and non-null in the example → likely required)example directly on each property schema using the Postman valueexampleproperties entry with type: stringtype: file get type: string, format: binaryapplication/x-www-form-urlencodedApply the same JSON-to-schema inference for response bodies.
After inferring all schemas, look for structurally identical or near-identical schemas across different operations:
components/schemas entry/users/{userId} → User/vehicles/{vehicleId} → Vehicle/auth/login request body → LoginRequest; response → LoginResponse$ref: "#/components/schemas/Foo" wherever a schema is reusedFor each unique combination of (normalized path, method) from the flattened request list:
Multiple Postman requests with the same path and method (e.g. a success case and an error case saved as separate requests) should be merged into one OAS operation. Merge their saved responses and pick the most representative request body example.
Every {paramName} segment in the normalized path must appear in parameters:
{
"name": "paramName",
"in": "path",
"required": true,
"description": "<from Postman path variable description if present>",
"schema": {
"type": "string",
"example": "<concrete value from Postman url.variable>"
}
}
Infer type from the example value (numeric string that is always digits →
type: integer; UUID pattern → type: string, format: uuid).
Prefer environment-derived values for path parameter examples when available.
{
"name": "paramName",
"in": "query",
"required": false,
"description": "<from Postman query param description if present>",
"schema": {
"type": "string",
"example": "<value from Postman>"
}
}
Mark required: true only if the parameter appears in every saved request
variant for this operation and has a non-empty value.
When query values come from {{variableName}}, use the resolved environment
value as the query parameter example.
Only emit non-auth, non-standard request headers as in: header parameters.
Omit: Content-Type, Accept, Authorization, Host, User-Agent,
Content-Length, Connection.
For each saved response, extract non-standard response headers and add them
to the response headers map:
"headers": {
"X-Rate-Limit-Remaining": {
"description": "",
"schema": { "type": "integer" }
}
}
Omit standard HTTP response headers: Content-Type, Content-Length,
Transfer-Encoding, Connection, Date, Server.
Build the complete OpenAPI 3.0 document:
openapi"openapi": "3.0.3"
info"info": {
"title": "<collection name>",
"description": "<collection description, or empty string>",
"version": "<collection version or '1.0.0'>"
}
serversAs derived in Step 4.
tagsOne tag per top-level Postman folder. If the collection has no folders,
derive tags from the first path segment of each route (e.g. /users/* → Users).
"tags": [
{ "name": "Users", "description": "" },
{ "name": "Auth", "description": "" }
]
pathsFor each (normalized path, method) operation:
"/path/{param}": {
"get": {
"operationId": "<camelCase unique id>",
"summary": "<request name from Postman, cleaned up>",
"description": "<request description from Postman if present>",
"tags": ["<folder breadcrumb or inferred tag>"],
"parameters": [...],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/FooRequest" }
}
}
},
"responses": {
"200": {
"description": "<Postman response name or 'Success'>",
"headers": { ... },
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Foo" }
}
}
}
},
"security": [{ "BearerAuth": [] }]
}
}
operationId rules:
getUserById, "Create Vehicle" → createVehicle)<method><FirstPathSegmentPascalCase> if name is genericResponse rules:
item.response[].code)default entry:"default": { "description": "Unexpected error" }
content; one with an empty
body omits content entirely (e.g. 204 or empty text/plain responses).Security rules:
auth block, apply that scheme globally in
the OAS root security fieldtype: noauth → "security": []securitysecurity and
apply per-operation onlycomponentscomponents.schemasAll inferred and deduplicated schemas from Step 5. Order alphabetically.
components.securitySchemesAll auth schemes from Step 3:
"securitySchemes": {
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
},
"BasicAuth": {
"type": "http",
"scheme": "basic"
},
"ApiKeyHeader": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key"
}
}
Root key order: openapi, info, servers, tags, paths, components
Output location:
openapi.json in the same directory as the Postman collection fileFormat: JSON, 2-space indentation.
Before writing, run a self-review checklist:
$ref target exists in components{param} in a path has a matching in: path parameter with required: trueoperationId is unique across the documentdescription field/requestBody is only on POST, PUT, PATCH, OPTIONS operations
(never on GET, DELETE, HEAD)in: path parameter has required: trueFix any violations found, then write the file.
After writing the file, output a summary table:
Postman → OpenAPI Conversion Complete
Output file: <path to openapi.json>
OAS version: 3.0.3
Servers: <N server URLs>
Tags: <list>
Paths: <N unique paths>
Operations: <N total operations>
Schemas: <N component schemas>
Security: <scheme names, or "None detected">
Requests processed:
Total requests in collection: <N>
Operations generated: <N>
Requests merged (same path+method): <N>
Requests skipped (attack payloads): <N>
Requests skipped (attack/demo operations): <N>
Notes:
- <any ambiguities, assumptions, or items that need manual review>
- <any operations where response bodies could not be inferred>
- <any path parameters that could not be confirmed — mark as TODO>
{{variableName}} placeholders{{variableName}} occurrences in URLs, headers, and body values
using the merged variable map before any processingexample fields for path/query/header parameters and body schemas whenever
the placeholder maps to that field{{baseUrl}} in the URL path → strip from the path; emit as a server variable
or use the resolved value as the server URLauth block, requests in that folder inherit it unless
they override with their own auth blockoperationId candidate, append a numeric
suffix: getUser, getUser2, getUser3POST /graphql operation with application/json request
body containing query (string) and variables (object) propertiesrequestBody.contentnullable: true for nullable fields (OAS 3.0 style, not type: ["string", "null"])$ref everywhere a schema appears more than once$schema, $id, or other JSON Schema draft-07+ keywordsstring, number, integer,
boolean, array, objectoperationId — required for 42Crunch audit and scan toolingformat where applicable: date-time, date, uuid, email, uri,
binary, byte, int32, int64, float, double, password原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。