https://github.com/chihebnabil/openapi-graft
https://github.com/chihebnabil/openapi-graft
fern openapi sdk stainless
Last synced: 29 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/chihebnabil/openapi-graft
- Owner: chihebnabil
- License: mit
- Created: 2026-05-20T00:54:05.000Z (about 1 month ago)
- Default Branch: master
- Last Pushed: 2026-05-20T00:56:26.000Z (about 1 month ago)
- Last Synced: 2026-05-20T03:52:00.226Z (about 1 month ago)
- Topics: fern, openapi, sdk, stainless
- Language: TypeScript
- Homepage:
- Size: 197 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# openapi-graft
OpenAPI SDK generator with AST-level 3-way merge for preserved custom code, plus MCP server scaffolding.
## Features
- **Multi-language SDK generation**: TypeScript, Python, Go, Java, Rust
- **AST-level 3-way merge**: Preserves custom code across regenerations using `@graft` annotations
- **MCP server scaffolding**: Generate Model Context Protocol servers from the same OpenAPI spec
- **CI-native**: Runs as a CLI tool, no cloud dependency
- **Validation**: Compiles merged output before writing to disk, fails CI if custom code breaks
## Quick Start
```bash
# Install globally
npm install -g openapi-graft
# Or use with npx
npx openapi-graft init
npx openapi-graft generate
```
## How It Works
Graft uses annotated regions for code preservation across regenerations:
| Layer | Function |
|-------|----------|
| Parser | Tree-sitter based - TypeScript, Python, Go, Java, Rust |
| Base | Previous clean generation (stored in `.graft/base/`) |
| Ours | Current working SDK with custom code |
| Theirs | New generation from updated OpenAPI spec |
| Merge Engine | Identifies `@graft(preserve)` annotated blocks, merges them into new generated classes |
| Validator | Compiles the merged output before writing - fails CI if custom code broke the new interface |
## Configuration
Create a `graft.yml` in your project root:
```yaml
spec: ./openapi.json
sdks:
- language: typescript
output: ./sdks/ts
package: "@yourcompany/sdk"
preserve:
- ./sdks/ts/src/custom/**/*.ts # auto-annotated on first run
- language: python
output: ./sdks/python
package: "yourcompany-sdk"
- language: go
output: ./sdks/go
package: "github.com/yourcompany/sdk"
mcp:
enabled: true
output: ./mcp-server
```
## Preserving Custom Code
Use `@graft` annotations to mark code that should survive regeneration:
### TypeScript
```typescript
// @graft(preserve) id="custom-validation"
async validateCustom(request: Request): Promise {
// Your custom implementation
// This survives SDK regeneration
}
```
### Python
```python
# @graft(preserve) id="custom-validation"
async def validate_custom(self, request):
# Your custom implementation
# This survives SDK regeneration
pass
```
### Go
```go
// @graft(preserve) id="custom-handler"
func (api *API) CustomHandler(ctx context.Context, req Request) (*Response, error) {
// Custom implementation survives regeneration
}
```
### Java
```java
// @graft(preserve) id="custom-handler"
public Object customHandler(String param) throws SDKException {
// Custom implementation survives regeneration
}
```
### Rust
```rust
/// @graft(preserve) id="custom-handler"
pub async fn custom_handler(&self, param: String) -> GraftResult {
// Custom implementation survives regeneration
Ok(Value::Null)
}
```
## CLI Commands
```bash
# Initialize a new graft.yml
graft init
# Generate all SDKs
graft generate
# Generate MCP server
graft mcp
# Perform manual 3-way merge
graft merge --base ./base --ours ./ours --theirs ./theirs --language typescript --output ./merged
# Show status
graft status
```
## Why Graft?
| Feature | OpenAPI Generator | Fern | Graft |
|---------|------------------|------|-------|
| Custom code survives regen | ❌ Overwritten | ⚠️ .fernignore (manual) | ✅ AST merge with annotations |
| MCP server from same spec | ❌ No | ❌ No | ✅ Built-in |
| Self-hosted / air-gapped | ✅ Yes | ⚠️ Docker only | ✅ CLI-native, no cloud |
| Idiomatic output quality | ❌ Generic | ✅ High | ✅ Template-based |
## License
MIT