## File: README.md

Translations: [English](README.md) | [简体中文](README_zh.md)

# Kratos

Kratos is a lightweight Go framework for building cloud-native microservices. It provides small, explicit APIs for transport, middleware, registry, configuration, logging, encoding, and code generation so applications can focus on business logic.

## Features

- API-first development with Protobuf and generated HTTP/gRPC code.
- Unified [transport](https://go-kratos.dev/docs/component/transport/overview) layer for [HTTP](https://go-kratos.dev/docs/component/transport/http) and [gRPC](https://go-kratos.dev/docs/component/transport/grpc).
- Composable [middleware](https://go-kratos.dev/docs/component/middleware/overview) for recovery, logging, validation, tracing, metrics, auth, and more.
- Pluggable [registry](https://go-kratos.dev/docs/component/registry), [configuration](https://go-kratos.dev/docs/component/config), and [encoding](https://go-kratos.dev/docs/component/encoding) components.
- Standard-library `log/slog` based logging with OpenTelemetry extensions in contrib packages.
- Consistent metadata, errors, validation, OpenAPI, and code-generation workflows.
- A contrib ecosystem for optional integrations such as registries, config stores, middleware, encodings, and observability.

## Installation

### Requirements

- [Go](https://go.dev/dl/) 1.25 or later
- [protoc](https://github.com/protocolbuffers/protobuf)
- [protoc-gen-go](https://github.com/protocolbuffers/protobuf-go)

### Install the CLI

```shell
go install github.com/go-kratos/kratos/cmd/kratos/v3@latest
kratos upgrade
```

## Create a Service

```shell
kratos new helloworld
cd helloworld
go mod tidy
kratos run
```

Visit `http://localhost:8000/helloworld/kratos` after the service starts.

For a fuller generated service flow:

```shell
kratos proto add api/helloworld/helloworld.proto
kratos proto client api/helloworld/helloworld.proto
kratos proto server api/helloworld/helloworld.proto -t internal/service
go generate ./...
kratos run
```

## Usage Example

```go
package main

import (
	"github.com/go-kratos/kratos/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
	"github.com/go-kratos/kratos/v3/transport/http"
)

func main() {
	httpSrv := http.NewServer(http.Address(":8000"))
	grpcSrv := grpc.NewServer(grpc.Address(":9000"))

	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Version("v1.0.0"),
		kratos.Server(httpSrv, grpcSrv),
	)
	if err := app.Run(); err != nil {
		panic(err)
	}
}
```

## v3 Migration

Kratos v3 reduces core dependencies and makes previously implicit behavior explicit. Review the [v2 to v3 migration guide](docs/migration/v2-to-v3.md) before upgrading production services.

## Further Reading

- [Documentation](https://go-kratos.dev/docs/getting-started/start)
- [Examples](https://github.com/go-kratos/examples)
- [Project Layout](https://github.com/go-kratos/kratos-layout)
- [v2 to v3 Migration Guide](docs/migration/v2-to-v3.md)
- [Community Contribution Guide](https://go-kratos.dev/docs/community/contribution)

## Development

```shell
make test
make lint
```

## Community

- [Documentation](https://go-kratos.dev/en)
- [WeChat Group](https://github.com/go-kratos/kratos/issues/682)
- [Discord Group](https://discord.gg/BWzJsUJ)
- [Discussions](https://github.com/go-kratos/kratos/discussions)

## Security

If you discover a security vulnerability in Kratos, please contact go-kratos@googlegroups.com. Security reports are handled privately before disclosure.

## Contributors

Thank you for contributing to Kratos. The contribution guide is available in the [Kratos documentation](https://go-kratos.dev/docs/community/contribution).

<a href="https://github.com/go-kratos/kratos/graphs/contributors">
  
</a>

## Acknowledgments

The following projects influenced Kratos design:

- [go-kit/kit](https://github.com/go-kit/kit)
- [go-micro](https://github.com/asim/go-micro)
- [google/go-cloud](https://github.com/google/go-cloud)
- [go-zero](https://github.com/zeromicro/go-zero)
- [beego](https://github.com/beego/beego)

## License

Kratos is open-sourced software licensed under the [MIT license](./LICENSE).

---

## File: config/README.md

# Config

## kubernetes

```shell
go get -u github.com/go-kratos/kratos/contrib/config/kubernetes/v3
```

## apollo

```shell
go get -u github.com/go-kratos/kratos/contrib/config/apollo/v3
```

## etcd

```shell
go get -u github.com/go-kratos/kratos/contrib/config/etcd/v3
```

## nacos

```shell
go get -u github.com/go-kratos/kratos/contrib/config/nacos/v3
```

---

## File: contrib/transport/mcp/README.md

# MCP Transport

This module implements the MCP server in Kratos based on mcp-go.

[](https://pkg.go.dev/github.com/go-kratos/kratos/contrib/transport/mcp/v3)

## Quick start
```go
import(
    tm "github.com/go-kratos/kratos/contrib/transport/mcp/v3"
    mcp "github.com/mark3labs/mcp-go/mcp"
)

func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    name, ok := request.Params.Arguments["name"].(string)
    if !ok {
        return nil, errors.New("name must be a string")
    }
    return mcp.NewToolResultText(fmt.Sprintf("Hello, %s!", name)), nil
}

func Health(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/health/ready" {
			w.WriteHeader(http.StatusOK)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
    srv := tm.NewServer("kratos-mcp", "v1.0.0", tm.Address(":8000"), tm.Middleware(Health))
    tool := mcp.NewTool("hello_world",
        mcp.WithDescription("Say hello to someone"),
        mcp.WithString("name",
            mcp.Required(),
            mcp.Description("Name of the person to greet"),
        ),
    )
    // Add tool handler
    srv.AddTool(tool, helloHandler)
    // creates a kratos application
    app := kratos.New(
        kratos.Name("kratos-app"),
        kratos.Server(srv),
    )
    if err := app.Run(); err != nil {
        panic(err)
    }
}
```

---

## File: contrib/registry/servicecomb/README.md

# Servicecomb Registry

## example

### server
```go
package main

import (
	"log"

	"github.com/go-chassis/sc-client"
	"github.com/go-kratos/kratos/contrib/registry/servicecomb/v3"
	"github.com/go-kratos/kratos/v3"
)

func main() {
	c, err := sc.NewClient(sc.Options{
		Endpoints: []string{"127.0.0.1:30100"},
	})
	if err != nil {
		log.Panic(err)
	}
	r := servicecomb.NewRegistry(c)
	app := kratos.New(
		kratos.Name("helloServicecomb"),
		kratos.Registrar(r),
	)
	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}
```

### client
```go
package main

import (
	"context"
	"log"

	"github.com/go-chassis/sc-client"
	"github.com/go-kratos/kratos/contrib/registry/servicecomb/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
)

func main() {
	c, err := sc.NewClient(sc.Options{
		Endpoints: []string{"127.0.0.1:30100"},
	})
	if err != nil {
		log.Panic(err)
	}
	r := servicecomb.NewRegistry(c)
	ctx := context.Background()
	conn, err := grpc.NewClient(
		ctx,
		grpc.WithEndpoint("discovery:///helloServicecomb"),
		grpc.WithDiscovery(r),
	)
	if err != nil {
		return
	}
	defer conn.Close()
}
```

---

## File: contrib/registry/nacos/README.md

# Nacos Registry

## example
### server
```go
package main

import (
	"log"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"

	"github.com/go-kratos/kratos/contrib/registry/nacos/v3"
	"github.com/go-kratos/kratos/v3"
)

func main() {
	sc := []constant.ServerConfig{
		*constant.NewServerConfig("127.0.0.1", 8848),
	}

	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ServerConfigs: sc,
		},
	)

	if err != nil {
		log.Panic(err)
	}

	r := nacos.New(client)

	// server
	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Registrar(r),
	)
	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}
```
### client
```go
package main

import (
	"context"
	"log"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"

	"github.com/go-kratos/kratos/contrib/registry/nacos/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
)

func main() {
	cc := constant.ClientConfig{
		NamespaceId: "public",
		TimeoutMs:   5000,
	}

	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig: &cc,
		},
	)

	if err != nil {
		log.Panic(err)
	}

	r := nacos.New(client)

	// client
	conn, err := grpc.NewClient(
		context.Background(),
		grpc.WithEndpoint("discovery:///helloworld"),
		grpc.WithDiscovery(r),
	)
	defer conn.Close()
}
```

---

## File: contrib/registry/discovery/README.md

## Discovery Registry

This module implements a `registry.Registrar` and `registry.Discovery` interface in kratos based `bilibili/discovery`.

[](https://pkg.go.dev/github.com/go-kratos/kratos/contrib/registry/discovery/v3)

### Quick Start

**_Register a service_**

```go
import (
	"github.com/go-kratos/kratos/contrib/registry/discovery/v3"
)

func main() {
	// initialize a registry
	r := discovery.New(&discovery.Config{
		Nodes:  []string{"0.0.0.0:7171"},
		Env:    "dev",
		Region: "sh1",
		Zone:   "zone1",
		Host:   "hostname",
	})

	// construct srv instance
	// ...

	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Server(
			httpSrv,
			grpcSrv,
		),
		kratos.Metadata(map[string]string{"color": "gray"}),
		// use Registrar
		kratos.Registrar(r),
	)

	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}
```

**_Discover a service_**

```go
import (
	"github.com/go-kratos/kratos/contrib/registry/discovery/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
)

func main() {
	// initialize a discovery
	r := discovery.New(&discovery.Config{
		Nodes:  []string{"0.0.0.0:7171"},
		Env:    "dev",
		Region: "sh1",
		Zone:   "zone1",
		Host:   "localhost",
	}, nil)

	conn, err := grpc.NewClient(
		context.Background(),
		grpc.WithEndpoint("discovery:///appid"),
		// use discovery
		grpc.WithDiscovery(r),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	// request and log
}
```

### Config explain

```go
type Config struct {
	Nodes  []string // discovery nodes address
	Region string   // region of the service, sh
	Zone   string   // zone of region, sh001
	Env    string   // env of service, dev, prod and etc
	Host   string   // hostname of service
}
```

### References

- [bilibili/discovery](https://github.com/bilibili/discovery)

---

## File: contrib/opensergo/README.md

# OpenSergo

## Usage

```go
osServer, err := opensergo.New(opensergo.WithEndpoint("localhost:9090"))
if err != nil {
	panic("init opensergo error")
}

s := &server{}
grpcSrv := grpc.NewServer(
	grpc.Address(":9000"),
	grpc.Middleware(
		recovery.Recovery(),
	),
)
helloworld.RegisterGreeterServer(grpcSrv, s)

app := kratos.New(
	kratos.Name(Name),
	kratos.Server(
		grpcSrv,
	),
)

osServer.ReportMetadata(context.Background(), app)

if err := app.Run(); err != nil {
	log.Fatal(err)
}
```

---

## File: contrib/middleware/validate/README.md

# Validator Middleware for Kratos Project

This module provides a middleware for Kratos to validate request parameters, using schema defined in `.proto` files.

There used to be a middleware named `Validator` in Kratos, which calls the generated validation functions
from [PGV](https://github.com/bufbuild/protoc-gen-validate) at runtime. Since PGV has been
in [maintenance](https://github.com/bufbuild/protoc-gen-validate/commit/4a8ffc4942463929c4289407cd4b8c8328ff5422), and
recommend using [protovalidate](https://github.com/bufbuild/protovalidate) as an alternative.

That's why we provide a new middleware that uses the schema definitions and validation functions provided by
protovalidate.

protovalidate no longer requires code generation at build time, but for compatibility with existing Kratos
projects, we enable the legacy mode of protovalidate. For most users, no changes are needed to existing code. **But for
users who have manually implemented the Validator interface, you need to migrate the relevant implementation yourself**.

---

## File: contrib/errortracker/sentry/README.md

# Sentry middleware for Kratos
This middleware helps you to catch panics and report them to [sentry](https://sentry.io/)

## Quick Start
You could check the full demo in example folder.
```go
// Step 1:
// init sentry in the entry of your application
import "github.com/getsentry/sentry-go"

sentry.Init(sentry.ClientOptions{
	Dsn: "<your dsn>",
	AttachStacktrace: true, // recommended
})

// Step 2:
// set middleware
import (
	"context"

	ksentry "github.com/go-kratos/kratos/contrib/errortracker/sentry/v3"
	"github.com/go-kratos/kratos/contrib/otel/v3/tracing"
)

// for HTTP server, new HTTP server with sentry middleware options
var opts = []http.ServerOption{
	http.Middleware(
		recovery.Recovery(),
		tracing.Server(),
		ksentry.Server(
			ksentry.WithTags(map[string]string{
				"tag": "some-custom-constant-tag",
			}),
			ksentry.WithContextTags(func(ctx context.Context) map[string]string {
				return map[string]string{"trace_id": tracing.TraceID(ctx)}
			}),
		), // must after Recovery middleware, because of the exiting order will be reversed
		logging.Server(logger),
	),
}

// for gRPC server, new gRPC server with sentry middleware options
var opts = []grpc.ServerOption{
	grpc.Middleware(
		recovery.Recovery(),
		tracing.Server(),
		ksentry.Server(
			ksentry.WithTags(map[string]string{
				"tag": "some-custom-constant-tag",
			}),
			ksentry.WithContextTags(func(ctx context.Context) map[string]string {
				return map[string]string{"trace_id": tracing.TraceID(ctx)}
			}),
		), // must after Recovery middleware, because of the exiting order will be reversed
		logging.Server(logger),
	),
}

// Then, the framework will report events to Sentry when your trigger panics.
// Or your can push events to Sentry manually
```

## Reference
* [https://docs.sentry.io/platforms/go/](https://docs.sentry.io/platforms/go/)