Go tool to modify/update field tags in structs. gomodifytags makes it easy to
update, add or delete the tags in a struct field. You can easily add new tags,
update existing tags (such as appending a new key, i.e: db, xml, etc..) or
remove existing tags. It also allows you to add and remove tag options. It's
intended to be used by an editor, but also has modes to run it from the
terminal. Read the usage section below for more information.

go install github.com/fatih/gomodifytags@latest
:GoAddTags and :GoRemoveTagsgolang:add-tags and golang:remove-tagsGo: Add Tags and Go: Remove Tagsaddtags and rmtagsgo-tag-add and go-tag-removegomodifytags has multiple ways to modify a tag. Let's start with an example package:
package main
type Server struct {
Name string
Port int
EnableLogs bool
BaseDomain string
Credentials struct {
Username string
Password string
}
}
We have to first pass a file. For that we can use the -file flag:
$ gomodifytags -file demo.go
-line, -offset, -struct or -all is not passed
What are these? There are four different ways of defining which field tags to change:
-struct: This accepts the struct name. i.e: -struct Server. The name
should be a valid type name. The -struct flag selects the whole struct, and
thus it will operate on all fields.-field: This accepts a field name. i.e: -field Address. Useful to select
a certain field. The name should be a valid field name. The -struct flag is required.-offset: This accepts a byte offset of the file. Useful for editors to pass
the position under the cursor. i.e: -offset 548. The offset has to be
inside a valid struct. The -offset selects the whole struct. If you need
more granular option see -line-line: This accepts a string that defines the line or lines of which fields
should be changed. I.e: -line 4 or -line 5,8-all: This is a boolean. The -all flag selects all structs of the given file.Let's continue by using the -struct tag:
$ gomodifytags -file demo.go -struct Server
one of [-add-tags, -add-options, -remove-tags, -remove-options, -clear-tags, -clear-options] should be defined
There are many options on how you can change the struct. Let us start by adding
tags. The following will add the json key to all fields. The value will be
automatically inherited from the field name and transformed to snake_case:
$ gomodifytags -file demo.go -struct Server -add-tags json
package main
type Server struct {
Name string `json:"name"`
Port int `json:"port"`
EnableLogs bool `json:"enable_logs"`
BaseDomain string `json:"base_domain"`
Credentials struct {
Username string `json:"username"`
Password string `json:"password"`
} `json:"credentials"`
}
By default changes will be printed to stdout and can be used for dry-run your
changes before making destructive changes. If you want to change it permanently,
pass the -w (write) flag.
$ gomodifytags -file demo.go -struct Server -add-tags json -w
You can disable printing the results to stdout with the --quiet flag:
$ gomodifytags -file demo.go -struct Server -add-tags json -w --quiet
You can pass multiple keys to add tags. The following will add json and xml
keys:
$ gomodifytags -file demo.go -struct Server -add-tags json,xml
package main
type Server struct {
Name string `json:"name" xml:"name"`
Port int `json:"port" xml:"port"`
EnableLogs bool `json:"enable_logs" xml:"enable_logs"`
BaseDomain string `json:"base_domain" xml:"base_domain"`
Credentials struct {
Username string `json:"username" xml:"username"`
Password string `json:"password" xml:"password"`
} `json:"credentials" xml:"credentials"`
}
If you prefer to use camelCase instead of snake_case for the values, you
can use the -transform flag to define a different transformation rule. The
following example uses the camelcase transformation rule:
$ gomodifytags -file demo.go -struct Server -add-tags json,xml -transform camelcase
package main
type Server struct {
Name string `json:"name" xml:"name"`
Port int `json:"port" xml:"port"`
EnableLogs bool `json:"enableLogs" xml:"enableLogs"`
BaseDomain string `json:"baseDomain" xml:"baseDomain"`
Credentials struct {
Username string `json:"username" xml:"username"`
Password string `json:"password" xml:"password"`
} `json:"credentials" xml:"credentials"`
}
By default a struct tag's value is transformed from a struct's field and used
directly. As an example for the field Server string, we generate a tag in the
form: json:"server" (assuming -add-tags=json is used).
However, some third party libraries use tags in a different way and might
require to them to have a particular formatting, such as is the case of
prefixing them (field_name=<your_value>). The --template flag allows you to
specify a custom format for the tag value to be applied.
$ gomodifytags -file demo.go -struct Server -add-tags gaum -template "field_name={field}"
package main
type Server struct {
Name string `gaum:"field_name=name"`
Port int `gaum:"field_name=port"`
EnableLogs bool `gaum:"field_name=enableLogs"`
BaseDomain string `gaum:"field_name=baseDomain"`
}
The {field} word is a special keyword that is replaced by the struct tag's value
after the transformation.
We currently support the following transformations:
snakecase: "BaseDomain" -> "base_domain"camelcase: "BaseDomain" -> "baseDomain"lispcase: "BaseDomain" -> "base-domain"pascalcase: "BaseDomain" -> "BaseDomain"titlecase: "BaseDomain" -> "Base Domain"keep: keeps the original field nameYou can also pass a static value for each fields. This is useful if you use Go
packages that validates the struct fields or extract values for certain
operations. The following example adds the json key, a validate key with
the value set to gt=1 and the scope key with the value read-only:
$ gomodifytags -file demo.go -struct Server -add-tags json,validate:gt=1,scope:read-only
package main
type Server struct {
Name string `json:"name" validate:"gt=1" scope:"read-only"`
Port int `json:"port" validate:"gt=1" scope:"read-only"`
EnableLogs bool `json:"enable_logs" validate:"gt=1" scope:"read-only"`
BaseDomain string `json:"base_domain" validate:"gt=1" scope:"read-only"`
Credentials struct {
Username string `json:"username" validate:"gt=1" scope:"read-only"`
Password string `json:"password" validate:"gt=1" scope:"read-only"`
} `json:"credentials" validate:"gt=1" scope:"read-only"`
}
To add options to for a given key, we use the -add-options flag. In the
example below we're going to add the json key and the omitempty option to
all json keys:
$ gomodifytags -file demo.go -struct Server -add-tags json -add-options json=omitempty
package main
type Server struct {
Name string `json:"name,omitempty"`
Port int `json:"port,omitempty"`
EnableLogs bool `json:"enable_logs,omitempty"`
BaseDomain string `json:"base_domain,omitempty"`
Credentials struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
} `json:"credentials,omitempty"`
}
If the key already exists you don't have to use -add-tags
By default all fields are processed. This main reason for this is to allow
structs to evolve with time and be ready in case a field is exported in the
future. However if you don't like this behavior, you can skip it by passing the
--skip-unexported flag:
$ gomodifytags -file demo.go -struct Server -add-tags json --skip-unexported
package main
type Server struct {
Name string `json:"name"`
Port int `json:"port"`
enableLogs bool
baseDomain string
}
Let's continue with removing tags. We're going to use the following simple package:
package main
type Server struct {
Name string `json:"name,omitempty" xml:"name,attr,cdata"`
Port int `json:"port,omitempty" xml:"port,attr,cdata"`
EnableLogs bool `json:"enable_logs,omitempty" xml:"enable_logs,attr,cdata"`
BaseDomain string `json:"base_domain,omitempty" xml:"base_domain,attr,cdata"`
Credentials struct {
Username string `json:"username,omitempty" xml:"username,attr,cdata"`
Password string `json:"password,omitempty" xml:"password,attr,cdata"`
} `json:"credentials,omitempty" xml:"credentials,attr,cdata"`
}
To remove the xml tags, we're going to use the -remove-tags flag:
$ gomodifytags -file demo.go -struct Server -remove-tags xml
package main
type Server struct {
Name string `json:"name"`
Port int `json:"port"`
EnableLogs bool `json:"enable_logs"`
BaseDomain string `json:"base_domain"`
Credentials struct {
Username string `json:"username"`
Password string `json:"password"`
} `json:"credentials"`
}
You can also remove multiple tags. The example below removs json and xml:
$ gomodifytags -file demo.go -struct Server -remove-tags json,xml
package main
type Server struct {
Name string
Port int
EnableLogs bool
BaseDomain string
Credentials struct {
Username string
Password string
}
}
If you want to remove all keys, we can also use the -clear-tags flag. This
flag removes all tags and doesn't require to explicitly pass the key names:
$ gomodifytags -file demo.go -struct Server -clear-tags
package main
type Server struct {
Name string
Port int
EnableLogs bool
BaseDomain string
Credentials struct {
Username string
Password string
}
}
To remove any option, we can use the -remove-options flag. The following will
remove all omitempty flags from the json key:
$ gomodifytags -file demo.go -struct Server -remove-options json=omitempty
package main
type Server struct {
Name string `json:"name" xml:"name,attr,cdata"`
Port int `json:"port" xml:"port,attr,cdata"`
EnableLogs bool `json:"enable_logs" xml:"enable_logs,attr,cdata"`
BaseDomain string `json:"base_domain" xml:"base_domain,attr,cdata"`
Credentials struct {
Username string `json:"username" xml:"username,attr,cdata"`
Password string `json:"password" xml:"password,attr,cdata"`
} `json:"credentials" xml:"credentials,attr,cdata"`
}
To remove multiple options from multiple tags just add another options:
$ gomodifytags -file demo.go -struct Server -remove-options json=omitempty,xml=cdata
package main
type Server struct {
Name string `json:"name" xml:"name,attr"`
Port int `json:"port" xml:"port,attr"`
EnableLogs bool `json:"enable_logs" xml:"enable_logs,attr"`
BaseDomain string `json:"base_domain" xml:"base_domain,attr"`
Credentials struct {
Username string `json:"username" xml:"username,attr"`
Password string `json:"password" xml:"password,attr"`
} `json:"credentials" xml:"credentials,attr"`
}
Lastly, to remove all options without explicitly defining the keys and names,
we can use the -clear-options flag. The following example will remove all
options for the given struct:
$ gomodifytags -file demo.go -struct Server -clear-options
package main
type Server struct {
Name string `json:"name" xml:"name"`
Port int `json:"port" xml:"port"`
EnableLogs bool `json:"enable_logs" xml:"enable_logs"`
BaseDomain string `json:"base_domain" xml:"base_domain"`
Credentials struct {
Username string `json:"username" xml:"username"`
Password string `json:"password" xml:"password"`
} `json:"credentials" xml:"credentials"`
}
So far all examples used the -struct flag. However we also can pass the line
numbers to only change certain files. Suppose we only want to remove the tags
for the Credentials struct (including the fields) for the following code (lines are included):
01 package main
02
03 type Server struct {
04 Name string `json:"name" xml:"name"`
05 Port int `json:"port" xml:"port"`
06 EnableLogs bool `json:"enable_logs" xml:"enable_logs"`
07 BaseDomain string `json:"base_domain" xml:"base_domain"`
08 Credentials struct {
09 Username string `json:"username" xml:"username"`
10 Password string `json:"password" xml:"password"`
11 } `json:"credentials" xml:"credentials"`
12 }
To remove the tags for the credentials we're going to pass the -line flag:
$ gomodifytags -file demo.go -line 8,11 -clear-tags xml
```go package main
type Server struct {
Name string json:"name" xml:"name"
Port int json:"port" xml:"port"
EnableLogs bool json:"enable_logs" xml:"enable_logs"
BaseDomain string json:"base_domain" xml:"base_domain"
Credentials struct {
Username string
Password string
}
}
$ claude mcp add gomodifytags \
-- python -m otcore.mcp_server <graph>