{"id":34683905,"url":"https://github.com/erraggy/oastools","last_synced_at":"2026-02-20T08:05:29.825Z","repository":{"id":323393126,"uuid":"1092622350","full_name":"erraggy/oastools","owner":"erraggy","description":"OpenAPI Specification (OAS) tools for validating, parsing, fixing, converting, diffing, joining, and building specs; as well as generating client/servers/types from specs.","archived":false,"fork":false,"pushed_at":"2026-02-16T06:46:40.000Z","size":7380,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-16T06:52:51.052Z","etag":null,"topics":["api","cli","go","golang","mcp","mcp-server","openapi","openapi-overlay","openapi-specification","openapi2","openapi3","openapi31","overlay","swagger"],"latest_commit_sha":null,"homepage":"https://erraggy.github.io/oastools/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erraggy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-09T01:05:20.000Z","updated_at":"2026-02-16T06:42:16.000Z","dependencies_parsed_at":"2026-01-04T13:04:43.541Z","dependency_job_id":null,"html_url":"https://github.com/erraggy/oastools","commit_stats":null,"previous_names":["erraggy/oastools"],"tags_count":114,"template":false,"template_full_name":null,"purl":"pkg:github/erraggy/oastools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erraggy%2Foastools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erraggy%2Foastools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erraggy%2Foastools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erraggy%2Foastools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erraggy","download_url":"https://codeload.github.com/erraggy/oastools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erraggy%2Foastools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29645170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T05:21:04.652Z","status":"ssl_error","status_checked_at":"2026-02-20T05:21:04.238Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","cli","go","golang","mcp","mcp-server","openapi","openapi-overlay","openapi-specification","openapi2","openapi3","openapi31","overlay","swagger"],"created_at":"2025-12-24T21:38:10.922Z","updated_at":"2026-02-20T08:05:29.806Z","avatar_url":"https://github.com/erraggy.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/img/banner.svg\" alt=\"oastools - for validating, parsing, fixing, converting, diffing, joining, and building specs\" width=\"100%\"\u003e\n\u003c/p\u003e\n\nA complete, self-contained OpenAPI toolkit for Go with minimal dependencies.\n\n[![CI: Go](https://github.com/erraggy/oastools/actions/workflows/go.yml/badge.svg)](https://github.com/erraggy/oastools/actions/workflows/go.yml)\n[![CI: golangci-lint](https://github.com/erraggy/oastools/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/erraggy/oastools/actions/workflows/golangci-lint.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/erraggy/oastools)](https://goreportcard.com/report/github.com/erraggy/oastools)\n[![codecov](https://codecov.io/gh/erraggy/oastools/graph/badge.svg?token=T8768QXQAX)](https://codecov.io/gh/erraggy/oastools)\n[![Go Reference](https://pkg.go.dev/badge/github.com/erraggy/oastools.svg)](https://pkg.go.dev/github.com/erraggy/oastools)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Try it Online](https://img.shields.io/badge/Try_it-Online-blue)](https://oastools.robnrob.com)\n\n**Parse, validate, fix, convert, diff, join, generate, and build OpenAPI specs (2.0-3.2.0) with zero runtime dependencies beyond YAML for parsing, x/tools for generating, and x/text for title casing.**\n\n## Highlights\n\n- **Minimal Dependencies** - Only [`go.yaml.in/yaml`](https://pkg.go.dev/go.yaml.in/yaml/v4), [`golang.org/x/tools`](https://pkg.go.dev/golang.org/x/tools), and [`golang.org/x/text`](https://pkg.go.dev/golang.org/x/text) at runtime\n- **Battle-Tested** - 7,500+ tests\u003csup\u003e†\u003c/sup\u003e against 10 production APIs (Discord, Stripe, GitHub, MS Graph 34MB)\n- **Complete Toolset** - 12 packages covering the full OpenAPI lifecycle\n- **Performance Optimized** - 340+ benchmarks\u003csup\u003e†\u003c/sup\u003e; pre-parsed workflows 11-150x faster\n- **Type-Safe Cloning** - Generated `DeepCopy()` methods preserve types across OAS versions (no JSON marshal hacks)\n- **Enterprise Ready** - Structured errors with `errors.Is()`/`errors.As()`, pluggable logging, configurable resource limits\n- **Well Documented** - Every package has godoc, runnable examples, and [deep dive guides](#deep-dive-guides) for advanced usage\n- **Semantic Deduplication** - Automatically consolidate structurally identical schemas, reducing document size\n- **Optimized Memory Usage** — sync.Pool reduces GC pressure up to 36% fewer allocations in marshal operations\n- **Deterministic Output** — Order-preserving marshal for reproducible JSON/YAML output\n\n\u003csup\u003e†\u003c/sup\u003e Test count includes table-driven subtests. Benchmark count includes parameterized sub-benchmarks. Run `make count-tests` and `make count-benchmarks` to verify.\n\n## Package Ecosystem\n\n| Package | Description | Try |\n|---------|-------------|:---:|\n| [parser](https://pkg.go.dev/github.com/erraggy/oastools/parser) | Parse \u0026 analyze OAS files from files, URLs, or readers | |\n| [validator](https://pkg.go.dev/github.com/erraggy/oastools/validator) | Validate specs with structural \u0026 semantic checks | [🌐](https://oastools.robnrob.com/validate) |\n| [fixer](https://pkg.go.dev/github.com/erraggy/oastools/fixer) | Auto-fix common validation errors | [🌐](https://oastools.robnrob.com/fix) |\n| [httpvalidator](https://pkg.go.dev/github.com/erraggy/oastools/httpvalidator) | Validate HTTP requests/responses against OAS at runtime | |\n| [converter](https://pkg.go.dev/github.com/erraggy/oastools/converter) | Convert between OAS 2.0 and 3.x | [🌐](https://oastools.robnrob.com/convert) |\n| [joiner](https://pkg.go.dev/github.com/erraggy/oastools/joiner) | Merge multiple OAS documents with schema deduplication and operation-aware renaming | [🌐](https://oastools.robnrob.com/join) |\n| [overlay](https://pkg.go.dev/github.com/erraggy/oastools/overlay) | Apply OpenAPI Overlay v1.0.0 with JSONPath targeting | [🌐](https://oastools.robnrob.com/overlay) |\n| [differ](https://pkg.go.dev/github.com/erraggy/oastools/differ) | Detect breaking changes between versions | [🌐](https://oastools.robnrob.com/diff) |\n| [generator](https://pkg.go.dev/github.com/erraggy/oastools/generator) | Generate Go client/server code with security support | |\n| [builder](https://pkg.go.dev/github.com/erraggy/oastools/builder) | Programmatically construct OAS documents with deduplication | |\n| [walker](https://pkg.go.dev/github.com/erraggy/oastools/walker) | Traverse OAS documents with typed handlers and flow control | |\n| [oaserrors](https://pkg.go.dev/github.com/erraggy/oastools/oaserrors) | Structured error types for programmatic handling | |\n\nAll packages include comprehensive documentation with runnable examples. See individual package pages on [pkg.go.dev](https://pkg.go.dev/github.com/erraggy/oastools) for API details.\n\n## Deep Dive Guides\n\nFor comprehensive examples and advanced usage patterns:\n\n| Package | Deep Dive |\n|---------|-----------|\n| builder | [Programmatic API Construction](builder/deep_dive.md) |\n| converter | [Version Conversion](converter/deep_dive.md) |\n| differ | [Breaking Change Detection](differ/deep_dive.md) |\n| fixer | [Automatic Fixes](fixer/deep_dive.md) |\n| generator | [Code Generation (Client/Server/Types)](generator/deep_dive.md) |\n| httpvalidator | [HTTP Request/Response Validation](httpvalidator/deep_dive.md) |\n| joiner | [Multi-Document Merging](joiner/deep_dive.md) |\n| overlay | [Overlay Transformations](overlay/deep_dive.md) |\n| parser | [Parsing \u0026 Reference Resolution](parser/deep_dive.md) |\n| validator | [Specification Validation](validator/deep_dive.md) |\n| walker | [Document Traversal](walker/deep_dive.md) |\n\n## Examples\n\nThe [`examples/`](examples/) directory contains complete, runnable examples demonstrating the full oastools ecosystem.\n\n| Category | Examples | Time |\n|----------|----------|------|\n| **Getting Started** | [quickstart](examples/quickstart/), [validation-pipeline](examples/validation-pipeline/) | 2-5 min |\n| **Workflows** | [validate-and-fix](examples/workflows/validate-and-fix/), [version-conversion](examples/workflows/version-conversion/), [multi-api-merge](examples/workflows/multi-api-merge/), [breaking-change-detection](examples/workflows/breaking-change-detection/), [overlay-transformations](examples/workflows/overlay-transformations/), [http-validation](examples/workflows/http-validation/) | 3-5 min each |\n| **Programmatic API** | [builder](examples/programmatic-api/builder/) with ServerBuilder | 5 min |\n| **Code Generation** | [petstore](examples/petstore/) (stdlib \u0026 chi router variants) | 10 min |\n\nEach example is a standalone Go module with its own README, covering all 12 public packages in the ecosystem. See [`examples/README.md`](examples/README.md) for the full feature matrix.\n\n## Installation\n\n### CLI Tool\n\n```bash\n# Homebrew (macOS and Linux)\nbrew tap erraggy/oastools \u0026\u0026 brew install oastools\n\n# Go install\ngo install github.com/erraggy/oastools/cmd/oastools@latest\n```\n\nPre-built binaries for macOS, Linux, and Windows are available on the [Releases](https://github.com/erraggy/oastools/releases/latest) page.\n\n### Go Library\n\n```bash\ngo get github.com/erraggy/oastools@latest\n```\n\nRequires Go 1.24 or higher.\n\n## Try it Online\n\nNo installation required! Use oastools directly in your browser:\n\n🌐 **[oastools.robnrob.com](https://oastools.robnrob.com)** — Validate, convert, diff, fix, join, and apply overlays without installing anything.\n\n## Quick Start\n\n### CLI\n\n```bash\n# Validate a spec (from file or URL)\noastools validate openapi.yaml\noastools validate https://example.com/api/openapi.yaml\n\n# Convert between versions\noastools convert -t 3.0.3 swagger.yaml -o openapi.yaml\n\n# Compare specs and detect breaking changes\noastools diff --breaking api-v1.yaml api-v2.yaml\n\n# Fix common validation errors\noastools fix api.yaml -o fixed.yaml\n\n# Generate Go client/server code\noastools generate --client --server -o ./generated -p api openapi.yaml\n\n# Generate client with full OAuth2 support\noastools generate --client --oauth2-flows --readme -o ./client -p api openapi.yaml\n\n# Generate server with router, validation middleware, and request binding\noastools generate --server --server-all -o ./server -p api openapi.yaml\n\n# Merge multiple specs\noastools join -o merged.yaml base.yaml extensions.yaml\n\n# Apply overlays for environment-specific customizations\noastools overlay apply -s openapi.yaml -o production-api.yaml production.yaml\n\n# Preview overlay changes without applying\noastools overlay apply --dry-run -s openapi.yaml production.yaml\n\n# Validate an overlay document\noastools overlay validate changes.yaml\n\n# Query spec structure\noastools walk operations api.yaml\noastools walk schemas --name Pet --detail api.yaml\noastools walk responses --status '4xx' -q --format json api.yaml | jq\n\n# Pipeline support\ncat swagger.yaml | oastools convert -q -t 3.0.3 - \u003e openapi.yaml\noastools validate --format json openapi.yaml | jq '.valid'\n```\n\n### Library\n\n```go\nimport (\n    \"github.com/erraggy/oastools/parser\"\n    \"github.com/erraggy/oastools/validator\"\n    \"github.com/erraggy/oastools/httpvalidator\"\n    \"github.com/erraggy/oastools/differ\"\n    \"github.com/erraggy/oastools/overlay\"\n    \"github.com/erraggy/oastools/generator\"\n    \"github.com/erraggy/oastools/builder\"\n)\n\n// Parse\nresult, _ := parser.ParseWithOptions(parser.WithFilePath(\"api.yaml\"))\n\n// Validate specification\nvResult, _ := validator.ValidateWithOptions(validator.WithFilePath(\"api.yaml\"))\n\n// Validate HTTP request/response at runtime\nhvResult, _ := httpvalidator.ValidateRequestWithOptions(\n    req,\n    httpvalidator.WithFilePath(\"api.yaml\"),\n    httpvalidator.WithStrictMode(true),\n)\n\n// Diff\ndResult, _ := differ.DiffWithOptions(\n    differ.WithSourceFilePath(\"v1.yaml\"),\n    differ.WithTargetFilePath(\"v2.yaml\"),\n)\n\n// Overlay with dry-run preview\noResult, _ := overlay.DryRunWithOptions(\n    overlay.WithSpecFilePath(\"api.yaml\"),\n    overlay.WithOverlayFilePath(\"changes.yaml\"),\n)\n\n// Generate Go client code\ngResult, _ := generator.GenerateWithOptions(\n    generator.WithFilePath(\"api.yaml\"),\n    generator.WithPackageName(\"api\"),\n    generator.WithClient(true),\n)\n\n// Build a spec programmatically\nspec := builder.New(parser.OASVersion300).\n    SetTitle(\"My API\").\n    SetVersion(\"1.0.0\").\n    AddServer(\"https://api.example.com\", \"Production\")\ndoc, _ := spec.BuildOAS3()\n```\n\nFor complete API documentation and examples, see [pkg.go.dev](https://pkg.go.dev/github.com/erraggy/oastools) or the [Developer Guide](docs/developer-guide.md).\n\n## Why oastools?\n\n### Minimal Dependencies\n\n```\ngithub.com/erraggy/oastools\n├── go.yaml.in/yaml/v4  (YAML parsing)\n└── golang.org/x/tools  (Code generation - imports analysis)\n```\n\nUnlike many OpenAPI tools that pull in dozens of transitive dependencies, oastools is designed to be self-contained. The `stretchr/testify` dependency is test-only and not included in your production builds.\n\n### Battle-Tested Quality\n\nThe entire toolchain is validated against a corpus of 10 real-world production APIs:\n\n| Domain          | APIs                                    |\n|-----------------|-----------------------------------------|\n| FinTech         | Stripe, Plaid                           |\n| Developer Tools | GitHub, DigitalOcean                    |\n| Communications  | Discord (OAS 3.1)                       |\n| Enterprise      | Microsoft Graph (34MB, 18k+ operations) |\n| Location        | Google Maps                             |\n| Public          | US National Weather Service             |\n| Reference       | Petstore (OAS 2.0)                      |\n| Productivity    | Asana                                   |\n\nThis corpus spans OAS 2.0 through 3.1, JSON and YAML formats, and document sizes from 20KB to 34MB.\n\n### Performance\n\nPre-parsed workflows eliminate redundant parsing when processing multiple operations:\n\n| Method             | Speedup      |\n|--------------------|--------------|\n| `ValidateParsed()` | 31x faster   |\n| `ConvertParsed()`  | ~50x faster  |\n| `JoinParsed()`     | 150x faster  |\n| `DiffParsed()`     | 81x faster   |\n| `FixParsed()`      | ~60x faster  |\n| `ApplyParsed()`    | ~11x faster  |\n\nJSON marshaling is optimized for 25-32% better performance with 29-37% fewer allocations. See [benchmarks.md](benchmarks.md) for detailed analysis.\n\n### Type-Safe Document Cloning\n\nAll parser types include generated `DeepCopy()` methods for safe document mutation. Unlike JSON marshal/unmarshal approaches used by other tools, oastools provides:\n\n- **Type preservation** - Polymorphic fields maintain their actual types (e.g., `Schema.Type` as `string` vs `[]string` for OAS 3.1)\n- **Version-aware copying** - Handles OAS version differences correctly (`ExclusiveMinimum` as bool in 3.0 vs number in 3.1)\n- **Extension preservation** - All `x-*` extension fields are deep copied\n- **Performance** - Direct struct copying without serialization overhead\n\n```go\n// Safe mutation without affecting the original\ncopy := result.OAS3Document.DeepCopy()\ncopy.Info.Title = \"Modified API\"\n```\n\nAll OAS types also provide `Equals()` methods for structural comparison.\n\n### Enterprise-Grade Error Handling\n\nThe `oaserrors` package provides structured error types that work with Go's standard `errors.Is()` and `errors.As()`:\n\n```go\nimport (\n    \"errors\"\n    \"github.com/erraggy/oastools/oaserrors\"\n    \"github.com/erraggy/oastools/parser\"\n)\n\nresult, err := parser.ParseWithOptions(parser.WithFilePath(\"api.yaml\"))\nif err != nil {\n    // Check error category with errors.Is()\n    if errors.Is(err, oaserrors.ErrPathTraversal) {\n        log.Fatal(\"Security: path traversal attempt blocked\")\n    }\n\n    // Extract details with errors.As()\n    var refErr *oaserrors.ReferenceError\n    if errors.As(err, \u0026refErr) {\n        log.Printf(\"Failed to resolve: %s (type: %s)\", refErr.Ref, refErr.RefType)\n    }\n}\n```\n\nError types include `ParseError`, `ReferenceError`, `ValidationError`, `ResourceLimitError`, `ConversionError`, and `ConfigError`.\n\n### Configurable Resource Limits\n\nProtect against resource exhaustion with configurable limits:\n\n```go\nresult, err := parser.ParseWithOptions(\n    parser.WithFilePath(\"api.yaml\"),\n    parser.WithMaxRefDepth(50),           // Max $ref nesting (default: 100)\n    parser.WithMaxCachedDocuments(200),   // Max cached external docs (default: 100)\n    parser.WithMaxFileSize(20*1024*1024), // Max file size in bytes (default: 10MB)\n)\n```\n\n### HTTP Client Configuration\n\nFor advanced scenarios like custom timeouts, proxies, or authentication:\n\n```go\n// Custom timeout for slow networks\nclient := \u0026http.Client{Timeout: 120 * time.Second}\nresult, _ := parser.ParseWithOptions(\n    parser.WithFilePath(\"https://api.example.com/openapi.yaml\"),\n    parser.WithHTTPClient(client),\n)\n\n// Corporate proxy\nproxyURL, _ := url.Parse(\"http://proxy.corp:8080\")\nclient := \u0026http.Client{\n    Transport: \u0026http.Transport{Proxy: http.ProxyURL(proxyURL)},\n}\nresult, _ := parser.ParseWithOptions(\n    parser.WithFilePath(\"https://internal-api.corp/spec.yaml\"),\n    parser.WithHTTPClient(client),\n)\n```\n\nWhen a custom client is provided, `InsecureSkipVerify` is ignored—configure TLS on your client's transport instead.\n\n## Supported OpenAPI Versions\n\n| Version       | Specification                                     |\n|---------------|---------------------------------------------------|\n| 2.0 (Swagger) | [spec](https://spec.openapis.org/oas/v2.0.html)   |\n| 3.0.0 - 3.0.4 | [spec](https://spec.openapis.org/oas/v3.0.4.html) |\n| 3.1.0 - 3.1.2 | [spec](https://spec.openapis.org/oas/v3.1.2.html) |\n| 3.2.0         | [spec](https://spec.openapis.org/oas/v3.2.0.html) |\n\n**Features:**\n- Automatic format detection and preservation (JSON/YAML)\n- External reference resolution (local files; HTTP with opt-in flag)\n- JSON Pointer array index support (`#/paths/~1users/get/parameters/0`)\n- Full JSON Schema Draft 2020-12 compliance for OAS 3.1+ (including `unevaluatedProperties`, `unevaluatedItems`, content keywords)\n- Path traversal protection for security\n\n## Documentation\n\n📄 **[White Paper](https://erraggy.github.io/oastools/whitepaper/)** - Comprehensive technical exploration of oastools architecture and design\n\n📚 **[Developer Guide](docs/developer-guide.md)** - Complete library usage with examples for all 12 public packages\n\n📖 **[CLI Reference](docs/cli-reference.md)** - Full command documentation with all flags, options, and output formats\n\n| Resource                                                     | Description                             |\n|--------------------------------------------------------------|-----------------------------------------|\n| [pkg.go.dev](https://pkg.go.dev/github.com/erraggy/oastools) | API reference with runnable examples    |\n| [Breaking Changes Guide](docs/breaking-changes.md)           | Understanding breaking change detection |\n| [Benchmarks](benchmarks.md)                                  | Detailed performance analysis           |\n\n## Development\n\n```bash\nmake check  # Run all quality checks (tidy, fmt, lint, test)\nmake test   # Run tests with coverage\nmake build  # Build CLI binary\n```\n\n### Documentation\n\n```bash\nmake docs-serve  # Preview docs locally at http://127.0.0.1:8000/oastools/\nmake docs-build  # Build static site to site/\n```\n\nThe documentation site is automatically deployed to [GitHub Pages](https://erraggy.github.io/oastools/) on every push to `main`.\n\nSee [WORKFLOW.md](https://github.com/erraggy/oastools/blob/main/WORKFLOW.md) for the complete development process.\n\n## Contributing\n\n1. Fork and create a feature branch\n2. Run `make check` before committing\n3. Follow [conventional commits](https://conventionalcommits.org) (e.g., `feat(parser): add feature`)\n4. Submit a PR with testing checklist\n\nSee [WORKFLOW.md](https://github.com/erraggy/oastools/blob/main/WORKFLOW.md) for guidelines and [AGENTS.md](https://github.com/erraggy/oastools/blob/main/AGENTS.md) for AI agent setup.\n\n## License\n\nMIT\n\n_All code generated by Claude Code using claude-4-5-sonnet/opus with minor edits and full control by [@erraggy](https://github.com/erraggy)_\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferraggy%2Foastools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferraggy%2Foastools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferraggy%2Foastools/lists"}