diff --git a/.mcp.json b/.mcp.json
new file mode 100644
index 0000000000..c71d4c907b
--- /dev/null
+++ b/.mcp.json
@@ -0,0 +1,15 @@
+{
+  "mcpServers": {
+    "ocamllsp": {
+      "type": "stdio",
+      "command": "mcp-language-server",
+      "args": [
+        "--workspace",
+        "/Users/shulhi/Dev/rescript/rescript-compiler",
+        "--lsp",
+        "ocamllsp"
+      ],
+      "env": {}
+    }
+  }
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4433e20ec..a16a527114 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,7 @@
 - Don't produce duplicate type definitions for recursive types on hover. https://github.com/rescript-lang/rescript/pull/7524
 - Prop punning when types don't match results in I/O error: _none_: No such file or directory. https://github.com/rescript-lang/rescript/pull/7533
 - Fix partial application with user-defined function types. https://github.com/rescript-lang/rescript/pull/7548
+- Fix doc comment before variant throwing syntax error. https://github.com/rescript-lang/rescript/pull/7535
 
 #### :nail_care: Polish
 
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000000..937ed9585d
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,139 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Project Overview
+
+This is the ReScript compiler repository - a robustly typed language that compiles to efficient and human-readable JavaScript. ReScript is built using OCaml and includes a complete toolchain with compiler, build system, syntax parser, and standard library.
+
+## Build Commands
+
+### Basic Development
+```bash
+# Build compiler and copy executables
+make
+
+# Build in watch mode 
+make watch
+
+# Build everything including standard library
+make lib
+
+# Build artifacts and update artifact list
+make artifacts
+```
+
+### Testing
+```bash
+# Run all tests
+make test
+
+# Run specific test types
+make test-syntax           # Syntax parser tests
+make test-syntax-roundtrip # Roundtrip syntax tests  
+make test-gentype         # GenType tests
+make test-analysis        # Analysis tests
+make test-tools           # Tools tests
+make test-rewatch         # Rewatch tests
+
+# Run single file test
+./cli/bsc.js myTestFile.res
+
+# View parse/typed trees for debugging
+./cli/bsc.js -dparsetree myTestFile.res
+./cli/bsc.js -dtypedtree myTestFile.res
+```
+
+### Code Quality
+```bash
+# Format code
+make format
+
+# Check formatting
+make checkformat
+
+# Lint with Biome
+npm run check
+npm run check:all
+
+# TypeScript type checking  
+npm run typecheck
+```
+
+### Clean Operations
+```bash
+make clean      # Clean OCaml build artifacts
+make clean-all  # Clean everything including Rust/gentype
+```
+
+## Compiler Architecture
+
+The ReScript compiler follows this high-level pipeline:
+
+```
+ReScript Source (.res)
+  ↓ (ReScript Parser - compiler/syntax/)
+Surface Syntax Tree  
+  ↓ (Frontend transformations - compiler/frontend/)
+Surface Syntax Tree
+  ↓ (OCaml Type Checker - compiler/ml/)
+Typedtree
+  ↓ (Lambda compilation - compiler/core/lam_*)
+Lambda IR
+  ↓ (JS compilation - compiler/core/js_*)  
+JS IR
+  ↓ (JS output - compiler/core/js_dump*)
+JavaScript Code
+```
+
+### Key Directories
+
+- **`compiler/syntax/`** - ReScript syntax parser (MIT licensed, separate from main LGPL)
+- **`compiler/frontend/`** - AST transformations, external FFI processing, built-in attributes
+- **`compiler/ml/`** - OCaml compiler infrastructure (type checker, typedtree, etc.)
+- **`compiler/core/`** - Core compilation:
+  - `lam_*` files: Lambda IR compilation and optimization passes
+  - `js_*` files: JavaScript IR and code generation
+- **`compiler/ext/`** - Extended utilities and data structures
+- **`compiler/bsb/`** - Build system implementation
+- **`compiler/gentype/`** - TypeScript generation
+- **`runtime/`** - ReScript standard library (written in ReScript)
+- **`lib/`** - Compiled JavaScript output of standard library
+- **`analysis/`** - Language server and tooling support
+
+### Build System Components
+
+- **`compiler/bsb_exe/`** - Main ReScript build tool entry point
+- **`compiler/bsc/`** - Compiler binary entry point  
+- **`rewatch/`** - File watcher (written in Rust)
+- **`ninja/`** - Vendored Ninja build system
+
+## Development Setup Notes
+
+- Uses OCaml 5.3.0+ with opam for compiler development
+- Uses dune as build system with specific profiles (dev, release, browser)
+- Node.js 20+ required for JavaScript tooling
+- Rust toolchain needed for rewatch file watcher
+- Python ≤3.11 required for building ninja
+
+## Coding Conventions
+
+- **OCaml code**: snake_case (e.g., `to_string`)
+- **ReScript code**: camelCase (e.g., `toString`)
+- Use DCO sign-off for all commits: `Signed-Off-By: Your Name <email>`
+
+## Testing Strategy
+
+- **Mocha tests** (`tests/tests/`) - Runtime library unit tests
+- **Build system tests** (`tests/build_tests/`) - Integration tests  
+- **OUnit tests** (`tests/ounit_tests/`) - Compiler unit tests
+- **Expectation tests** - Plain `.res` files that check compilation output
+- Always include appropriate tests with new features/changes
+
+## Performance Notes
+
+The compiler is designed for fast feedback loops and scales to large codebases. When making changes:
+- Avoid introducing meaningless symbols
+- Maintain readable JavaScript output
+- Consider compilation speed impact
+- Use appropriate optimization passes in the Lambda and JS IRs
\ No newline at end of file
diff --git a/Example.res b/Example.res
new file mode 100644
index 0000000000..b05091f28a
--- /dev/null
+++ b/Example.res
@@ -0,0 +1,10 @@
+type x =
+  /** first group */
+  | A
+  | B
+  | C
+
+  /** second group */
+  | D
+  | E
+  | F
diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml
index ef4782192d..63ca9878c1 100644
--- a/compiler/syntax/src/res_core.ml
+++ b/compiler/syntax/src/res_core.ml
@@ -4886,12 +4886,35 @@ and parse_constr_decl_args p =
  *  | constr-name const-args
  *  | attrs constr-name const-args *)
 and parse_type_constructor_declaration_with_bar p =
-  match p.Parser.token with
-  | Bar ->
+  let is_constructor_with_bar p =
+    Parser.lookahead p (fun state ->
+        match state.Parser.token with
+        | DocComment _ -> (
+          Parser.next state;
+          match state.token with
+          | Bar -> true
+          | _ -> false)
+        | Bar -> true
+        | _ -> false)
+  in
+  if is_constructor_with_bar p then (
+    let doc_comment_attrs =
+      match p.Parser.token with
+      | DocComment (loc, s) ->
+        Parser.next p;
+        [doc_comment_to_attribute loc s]
+      | _ -> []
+    in
     let start_pos = p.Parser.start_pos in
     Parser.next p;
-    Some (parse_type_constructor_declaration ~start_pos p)
-  | _ -> None
+    let constr = parse_type_constructor_declaration ~start_pos p in
+    Some
+      {
+        constr with
+        Parsetree.pcd_attributes =
+          doc_comment_attrs @ constr.Parsetree.pcd_attributes;
+      })
+  else None
 
 and parse_type_constructor_declaration ~start_pos p =
   Parser.leave_breadcrumb p Grammar.ConstructorDeclaration;
@@ -4920,9 +4943,17 @@ and parse_type_constructor_declarations ?first p =
   let first_constr_decl =
     match first with
     | None ->
+      let doc_comment_attrs =
+        match p.Parser.token with
+        | DocComment (loc, s) ->
+          Parser.next p;
+          [doc_comment_to_attribute loc s]
+        | _ -> []
+      in
       let start_pos = p.Parser.start_pos in
       ignore (Parser.optional p Token.Bar);
-      parse_type_constructor_declaration ~start_pos p
+      let constr = parse_type_constructor_declaration ~start_pos p in
+      {constr with pcd_attributes = doc_comment_attrs @ constr.pcd_attributes}
     | Some first_constr_decl -> first_constr_decl
   in
   first_constr_decl
@@ -4948,7 +4979,7 @@ and parse_type_representation ?current_type_name_path ?inline_types_context p =
   in
   let kind =
     match p.Parser.token with
-    | Bar | Uident _ ->
+    | Bar | Uident _ | DocComment _ ->
       Parsetree.Ptype_variant (parse_type_constructor_declarations p)
     | Lbrace ->
       Parsetree.Ptype_record
@@ -5501,7 +5532,7 @@ and parse_type_equation_and_representation ?current_type_name_path
       parse_record_or_object_decl ?current_type_name_path ?inline_types_context
         p
     | Private -> parse_private_eq_or_repr p
-    | Bar | DotDot ->
+    | Bar | DotDot | DocComment _ ->
       let priv, kind = parse_type_representation p in
       (None, priv, kind)
     | _ -> (
diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml
index 4d00515e30..7e2c76a32b 100644
--- a/compiler/syntax/src/res_printer.ml
+++ b/compiler/syntax/src/res_printer.ml
@@ -340,7 +340,8 @@ let print_list ~get_loc ~nodes ~print ?(force_break = false) t =
     in
     Doc.breakable_group ~force_break docs
 
-let print_listi ~get_loc ~nodes ~print ?(force_break = false) t =
+let print_listi ~get_loc ~nodes ~print ?(ignore_empty_lines = false)
+    ?(force_break = false) t =
   let rec loop i (prev_loc : Location.t) acc nodes =
     match nodes with
     | [] -> (prev_loc, Doc.concat (List.rev acc))
@@ -352,8 +353,10 @@ let print_listi ~get_loc ~nodes ~print ?(force_break = false) t =
         | Some comment -> (Comment.loc comment).loc_start
       in
       let sep =
-        if start_pos.pos_lnum - prev_loc.loc_end.pos_lnum > 1 then
-          Doc.concat [Doc.hard_line; Doc.hard_line]
+        if
+          start_pos.pos_lnum - prev_loc.loc_end.pos_lnum > 1
+          && not ignore_empty_lines
+        then Doc.concat [Doc.hard_line; Doc.hard_line]
         else Doc.line
       in
       let doc = print_comments (print node t i) t loc in
@@ -1542,7 +1545,7 @@ and print_constructor_declarations ~state ~private_flag
       ~print:(fun cd cmt_tbl i ->
         let doc = print_constructor_declaration2 ~state i cd cmt_tbl in
         print_comments doc cmt_tbl cd.Parsetree.pcd_loc)
-      ~force_break cmt_tbl
+      ~force_break cmt_tbl ~ignore_empty_lines:true
   in
   Doc.breakable_group ~force_break
     (Doc.indent (Doc.concat [Doc.line; private_flag; rows]))
@@ -1555,7 +1558,8 @@ and print_constructor_declaration2 ~state i
   let comment_doc =
     match comment_attrs with
     | [] -> Doc.nil
-    | comment_attrs -> print_doc_comments ~state cmt_tbl comment_attrs
+    | comment_attrs ->
+      print_doc_comments ~sep:Doc.hard_line ~state cmt_tbl comment_attrs
   in
   let attrs = print_attributes ~state attrs cmt_tbl in
   let is_dot_dot_dot = cd.pcd_name.txt = "..." in
@@ -1579,8 +1583,8 @@ and print_constructor_declaration2 ~state i
   in
   Doc.concat
     [
-      bar;
       comment_doc;
+      bar;
       Doc.group
         (Doc.concat
            [
diff --git a/tests/syntax_benchmarks/data/Napkinscript.res b/tests/syntax_benchmarks/data/Napkinscript.res
index 03093ace2f..2a026803e8 100644
--- a/tests/syntax_benchmarks/data/Napkinscript.res
+++ b/tests/syntax_benchmarks/data/Napkinscript.res
@@ -1926,15 +1926,12 @@ module Grammar = {
     | PatternList
     | PatternOcamlList
     | PatternRecord
-
     | TypeDef
     | TypeConstrName
     | TypeParams
     | @live TypeParam
     | PackageConstraint
-
     | TypeRepresentation
-
     | RecordDecl
     | ConstructorDeclaration
     | ParameterList
diff --git a/tests/tests/src/arith_syntax.res b/tests/tests/src/arith_syntax.res
index e4e2980ba7..14be6752f1 100644
--- a/tests/tests/src/arith_syntax.res
+++ b/tests/tests/src/arith_syntax.res
@@ -1,16 +1,16 @@
 type rec expression =
-  | /** non-negative integer constant */
-  Numeral(float)
-  | /** Addition [e1 + e2] */
-  Plus(expression, expression)
-  | /** Difference [e1 - e2] */
-  Minus(expression, expression)
-  | /** Product [e1 * e2] */
-  Times(expression, expression)
-  | /** Quotient [e1 / e2] */
-  Divide(expression, expression)
-  | /** Opposite value [-e] */
-  Negate(expression)
+  /** non-negative integer constant */
+  | Numeral(float)
+  /** Addition [e1 + e2] */
+  | Plus(expression, expression)
+  /** Difference [e1 - e2] */
+  | Minus(expression, expression)
+  /** Product [e1 * e2] */
+  | Times(expression, expression)
+  /** Quotient [e1 / e2] */
+  | Divide(expression, expression)
+  /** Opposite value [-e] */
+  | Negate(expression)
   | Variable(string)
 
 let rec str = e =>
diff --git a/tests/tests/src/condition_compilation_test.mjs b/tests/tests/src/condition_compilation_test.mjs
index 533679e9e7..9ac6ac50a1 100644
--- a/tests/tests/src/condition_compilation_test.mjs
+++ b/tests/tests/src/condition_compilation_test.mjs
@@ -33,9 +33,9 @@ function eq(loc, x, y) {
   };
 }
 
-eq("File \"condition_compilation_test.res\", line 63, characters 5-12", 3, 3);
+eq("File \"condition_compilation_test.res\", line 60, characters 5-12", 3, 3);
 
-eq("File \"condition_compilation_test.res\", line 64, characters 5-12", v.contents, 2);
+eq("File \"condition_compilation_test.res\", line 61, characters 5-12", v.contents, 2);
 
 Mt.from_pair_suites("Condition_compilation_test", suites.contents);
 
diff --git a/tests/tests/src/condition_compilation_test.res b/tests/tests/src/condition_compilation_test.res
index 5bf56bed1b..8c7a8629ac 100644
--- a/tests/tests/src/condition_compilation_test.res
+++ b/tests/tests/src/condition_compilation_test.res
@@ -15,11 +15,8 @@ type open_flag =
   | O_DSYNC
   | O_SYNC
   | O_RSYNC
-
   | O_SHARE_DELETE
-
   | O_CLOEXEC
-
   | O_KEEPEXEC
 
 let vv = 3
diff --git a/tests/tests/src/gpr_1822_test.mjs b/tests/tests/src/gpr_1822_test.mjs
index 053f75f08a..c6a595a565 100644
--- a/tests/tests/src/gpr_1822_test.mjs
+++ b/tests/tests/src/gpr_1822_test.mjs
@@ -34,7 +34,7 @@ let area;
 
 area = myShape.TAG === "Circle" ? 100 * 3.14 : 10 * myShape._1 | 0;
 
-eq("File \"gpr_1822_test.res\", line 23, characters 3-10", area, 314);
+eq("File \"gpr_1822_test.res\", line 22, characters 3-10", area, 314);
 
 Mt.from_pair_suites("Gpr_1822_test", suites.contents);
 
diff --git a/tests/tests/src/gpr_1822_test.res b/tests/tests/src/gpr_1822_test.res
index 0d9006280f..a83c2a036c 100644
--- a/tests/tests/src/gpr_1822_test.res
+++ b/tests/tests/src/gpr_1822_test.res
@@ -11,7 +11,6 @@ let eq = (loc, x, y) => {
 
 type shape =
   | Circle(int)
-
   | Rectangle(int, int)
 
 let myShape = Circle(10)
diff --git a/tests/tests/src/mutual_non_recursive_type.res b/tests/tests/src/mutual_non_recursive_type.res
index 4b3a740bfb..e07c2a84b5 100644
--- a/tests/tests/src/mutual_non_recursive_type.res
+++ b/tests/tests/src/mutual_non_recursive_type.res
@@ -9,7 +9,7 @@ type t =
   | Ta(t) /* * u compilation error [nonrec applices to all] */
   | Tb(int)
 and u =
-  | /** one attribute nonrecursive will affect all */
-  H(t) /* refers to old t */
+  /** one attribute nonrecursive will affect all */
+  | H(t) /* refers to old t */
 
 let v: u = H(OT)
diff --git a/tests/tests/src/test_seq.res b/tests/tests/src/test_seq.res
index 8927d6119a..fd9bead672 100644
--- a/tests/tests/src/test_seq.res
+++ b/tests/tests/src/test_seq.res
@@ -29,7 +29,6 @@ type rec spec =
   | Set_float(ref<float>) /* Set the reference to the float argument */
   | Tuple(list<spec>) /* Take several arguments according to the
    spec list */
-
   | Symbol(list<string>, string => unit)
   /* Take one of the symbols as argument and
    call the function with the symbol. */
diff --git a/tests/tools_tests/src/DocExtractionRes.res b/tests/tools_tests/src/DocExtractionRes.res
index e86ab142e3..444cb8e12c 100644
--- a/tests/tools_tests/src/DocExtractionRes.res
+++ b/tests/tools_tests/src/DocExtractionRes.res
@@ -28,12 +28,12 @@ let \"SomeConstant" = 12
 module SomeInnerModule = {
   /*** Another module level docstring here.*/
   type status =
-    | /** If this is started or not */
-    Started(t)
-    | /** Stopped? */
-    Stopped
-    | /** Now idle.*/
-    Idle
+    /** If this is started or not */
+    | Started(t)
+    /** Stopped? */
+    | Stopped
+    /** Now idle.*/
+    | Idle
 
   /** These are all the valid inputs.*/
   type validInputs = [#something | #"needs-escaping" | #withPayload(int) | #status(status)]
@@ -55,8 +55,8 @@ module AnotherModule = {
 
   /** Trying how it looks with an inline record in a variant. */
   type someVariantWithInlineRecords =
-    | /** This has inline records...*/
-    SomeStuff({
+    /** This has inline records...*/
+    | SomeStuff({
         offline: bool,
         /** Is the user online? */
         online?: bool,