diff --git a/pkg/account/account.go b/pkg/account/account.go
new file mode 100644
index 0000000000000000000000000000000000000000..0461807e492425d636715ac4ae56620e5fc7c901
--- /dev/null
+++ b/pkg/account/account.go
@@ -0,0 +1,26 @@
+package account
+
+import (
+	"git.perx.ru/perxis/perxis-go/pkg/account/versions"
+	"git.perx.ru/perxis/perxis-go/pkg/auth"
+	"git.perx.ru/perxis/perxis-go/pkg/members"
+	msobserver "git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	"git.perx.ru/perxis/perxis-go/pkg/organizations"
+	"git.perx.ru/perxis/perxis-go/pkg/users"
+	"google.golang.org/grpc"
+)
+
+type Account struct {
+	users.Users
+	members.Members
+	organizations.Organizations
+	versions.Versions
+
+	// сервис, отвечающий за отслеживание сервисом `members` событий от других сервисов
+	MembersObserver msobserver.Observer
+
+	// используется для добавления в контекст информации о пользователе, инициировавшем запрос
+	PrincipalFactory *auth.PrincipalFactory
+
+	ClientConn *grpc.ClientConn
+}
diff --git a/pkg/account/client/client.go b/pkg/account/client/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..43df5462f9302a2a3c4f631e72bce29b3e9a73f9
--- /dev/null
+++ b/pkg/account/client/client.go
@@ -0,0 +1,139 @@
+package client
+
+import (
+	"context"
+	"crypto/tls"
+	"crypto/x509"
+	"fmt"
+	"net/url"
+	"time"
+
+	"git.perx.ru/perxis/perxis-go/pkg/account"
+	"git.perx.ru/perxis/perxis-go/pkg/cache"
+	serviceMembers "git.perx.ru/perxis/perxis-go/pkg/members/middleware"
+	membersObserverTransport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport/grpc"
+	membersTransport "git.perx.ru/perxis/perxis-go/pkg/members/transport/grpc"
+	serviceOrganizations "git.perx.ru/perxis/perxis-go/pkg/organizations/middleware"
+	organizationsTransport "git.perx.ru/perxis/perxis-go/pkg/organizations/transport/grpc"
+	serviceUsers "git.perx.ru/perxis/perxis-go/pkg/users/middleware"
+	usersTransport "git.perx.ru/perxis/perxis-go/pkg/users/transport/grpc"
+	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
+	"go.uber.org/zap"
+	"golang.org/x/oauth2/clientcredentials"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/credentials/insecure"
+	"google.golang.org/grpc/credentials/oauth"
+)
+
+const (
+	DefaultCacheSize = 1000
+	DefaultCacheTTL  = time.Second * 10
+)
+
+func NewClient(ctx context.Context, addr string, opts ...Option) (*account.Account, *grpc.ClientConn, error) {
+
+	client := &account.Account{}
+	dialOpts := make([]grpc.DialOption, 0)
+	config := &config{}
+
+	for _, o := range opts {
+		o(config)
+
+	}
+
+	if config.logger == nil {
+		config.logger = zap.NewNop()
+	}
+
+	dialOpts = append(dialOpts, grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
+		grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()))
+
+	if config.auth == nil {
+		dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
+	} else {
+		if config.auth.TLS != nil {
+
+			certPool := x509.NewCertPool()
+
+			if !certPool.AppendCertsFromPEM(config.auth.TLS.cacert) {
+				return nil, nil, fmt.Errorf("CA certificate not loaded")
+			}
+
+			clientCert, err := tls.X509KeyPair(config.auth.TLS.cert, config.auth.TLS.key)
+			if err != nil {
+				return nil, nil, err
+
+			}
+
+			tlsConfig := &tls.Config{
+				Certificates: []tls.Certificate{clientCert},
+				RootCAs:      certPool,
+			}
+
+			dialOpts = append(dialOpts,
+				grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)),
+			)
+		}
+
+		if config.auth.OAuth2 != nil {
+			if config.auth.OAuth2 != nil {
+				// create external grpc client
+				conf := &clientcredentials.Config{
+					TokenURL:       config.auth.OAuth2.tokenURL,
+					ClientID:       config.auth.OAuth2.clientID,
+					ClientSecret:   config.auth.OAuth2.clientSecret,
+					EndpointParams: url.Values{"audience": {config.auth.OAuth2.audience}},
+				}
+				cred := oauth.TokenSource{
+					TokenSource: conf.TokenSource(ctx),
+				}
+				dialOpts = append(dialOpts,
+					grpc.WithPerRPCCredentials(cred),
+					grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})), // обязательно использовать tls для credentials oauth.TokenSource https://github.com/grpc/grpc-go/blob/64031cbfcf4d84c026be93ad7b74b3c290100893/credentials/oauth/oauth.go#L160
+				)
+			}
+		}
+
+	}
+
+	accountConn, err := grpc.Dial(addr, dialOpts...)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	client.Members = membersTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
+	client.Organizations = organizationsTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
+	client.Users = usersTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
+	client.MembersObserver = membersObserverTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
+
+	if !config.noCache {
+		client = WithCaching(client, DefaultCacheSize, DefaultCacheTTL)
+	}
+
+	if !config.noLog {
+		client = WithLogging(client, config.logger, config.accessLog)
+	}
+
+	return client, accountConn, nil
+}
+
+func WithCaching(client *account.Account, size int, ttl time.Duration) *account.Account {
+	c := *client
+
+	c.Members = serviceMembers.CachingMiddleware(cache.NewCache(size, ttl))(client.Members)
+	c.Organizations = serviceOrganizations.CachingMiddleware(cache.NewCache(size, ttl))(client.Organizations)
+	c.Users = serviceUsers.CachingMiddleware(cache.NewCache(size, ttl))(client.Users)
+
+	return &c
+}
+
+func WithLogging(client *account.Account, logger *zap.Logger, accessLog bool) *account.Account {
+	c := *client
+
+	c.Members = serviceMembers.WithLog(c.Members, logger, accessLog)
+	c.Organizations = serviceOrganizations.WithLog(c.Organizations, logger, accessLog)
+	c.Users = serviceUsers.WithLog(c.Users, logger, accessLog)
+
+	return &c
+}
diff --git a/pkg/account/client/config.go b/pkg/account/client/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..f92abf1e3020b5c4091bcd0ea19222b5ee2defc7
--- /dev/null
+++ b/pkg/account/client/config.go
@@ -0,0 +1,95 @@
+package client
+
+import (
+	"github.com/go-kit/kit/transport/grpc"
+	"go.uber.org/zap"
+)
+
+type config struct {
+	auth      *authConfig
+	noCache   bool
+	noLog     bool
+	accessLog bool
+	debug     bool
+
+	clientOptions []grpc.ClientOption
+
+	logger *zap.Logger
+}
+
+type authConfig struct {
+	OAuth2 *authOAuth2Config
+	TLS    *authTLSConfig
+}
+
+type authOAuth2Config struct {
+	tokenURL     string
+	clientID     string // параметр из auth0 (клиент с таким id должен быть создан в perxis)
+	clientSecret string
+	audience     string // параметр из auth0 (название связанного с Application API)
+}
+
+type authTLSConfig struct {
+	cacert []byte
+	cert   []byte
+	key    []byte
+}
+
+type Option func(c *config)
+
+func AuthOAuth2(tokenUrl, clientID, clientSecret, audience string) Option {
+	return func(c *config) {
+		if c.auth == nil {
+			c.auth = &authConfig{}
+		}
+		c.auth.OAuth2 = &authOAuth2Config{
+			tokenURL:     tokenUrl,
+			clientID:     clientID,
+			clientSecret: clientSecret,
+			audience:     audience,
+		}
+	}
+}
+
+func AuthTLS(cacert, cert, key []byte) Option {
+	return func(c *config) {
+		if c.auth == nil {
+			c.auth = &authConfig{}
+		}
+		c.auth.TLS = &authTLSConfig{
+			cacert: cacert,
+			cert:   cert,
+			key:    key,
+		}
+	}
+}
+
+func NoCache() Option {
+	return func(c *config) {
+		c.noCache = true
+	}
+}
+
+func NoLog() Option {
+	return func(c *config) {
+		c.noLog = true
+	}
+}
+
+func GrpcClientOptions(opts ...grpc.ClientOption) Option {
+	return func(c *config) {
+		c.clientOptions = opts
+	}
+}
+
+func Logger(logger *zap.Logger) Option {
+	return func(c *config) {
+		c.logger = logger
+	}
+}
+
+func AccessLog() Option {
+	return func(c *config) {
+		c.accessLog = true
+	}
+}
diff --git a/pkg/account/versions/mocks/Versions.go b/pkg/account/versions/mocks/Versions.go
new file mode 100644
index 0000000000000000000000000000000000000000..e4572bac6ac23903d7ad0bdd94e2f7044f9fa7e3
--- /dev/null
+++ b/pkg/account/versions/mocks/Versions.go
@@ -0,0 +1,38 @@
+// Code generated by mockery v2.7.4. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	version "git.perx.ru/perxis/perxis-go/pkg/version"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Versions is an autogenerated mock type for the Versions type
+type Versions struct {
+	mock.Mock
+}
+
+// Get provides a mock function with given fields: ctx
+func (_m *Versions) Get(ctx context.Context) (*version.Version, error) {
+	ret := _m.Called(ctx)
+
+	var r0 *version.Version
+	if rf, ok := ret.Get(0).(func(context.Context) *version.Version); ok {
+		r0 = rf(ctx)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*version.Version)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+		r1 = rf(ctx)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
diff --git a/pkg/account/versions/service.go b/pkg/account/versions/service.go
new file mode 100644
index 0000000000000000000000000000000000000000..573fb51331a58548673730302252f3df52a7c297
--- /dev/null
+++ b/pkg/account/versions/service.go
@@ -0,0 +1,14 @@
+package versions
+
+import (
+	"context"
+
+	"git.perx.ru/perxis/perxis-go/pkg/version"
+)
+
+// @microgen grpc
+// @protobuf git.perx.ru/perxis/perxis-go/proto/versions/account
+// @grpc-addr account.Versions
+type Versions interface {
+	Get(ctx context.Context) (version *version.Version, err error)
+}
diff --git a/pkg/account/versions/transport/client.microgen.go b/pkg/account/versions/transport/client.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..e32a794e62283420a351cadb37efd34026d79777
--- /dev/null
+++ b/pkg/account/versions/transport/client.microgen.go
@@ -0,0 +1,23 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import (
+	"context"
+	"errors"
+	version "git.perx.ru/perxis/perxis-go/pkg/version"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+func (set EndpointsSet) Get(arg0 context.Context) (res0 *version.Version, res1 error) {
+	request := GetRequest{}
+	response, res1 := set.GetEndpoint(arg0, &request)
+	if res1 != nil {
+		if e, ok := status.FromError(res1); ok || e.Code() == codes.Internal || e.Code() == codes.Unknown {
+			res1 = errors.New(e.Message())
+		}
+		return
+	}
+	return response.(*GetResponse).Version, res1
+}
diff --git a/pkg/account/versions/transport/endpoints.microgen.go b/pkg/account/versions/transport/endpoints.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..b670fc2bb09ce1fe180f427ea600f703ebda02d5
--- /dev/null
+++ b/pkg/account/versions/transport/endpoints.microgen.go
@@ -0,0 +1,10 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import endpoint "github.com/go-kit/kit/endpoint"
+
+// EndpointsSet implements Versions API and used for transport purposes.
+type EndpointsSet struct {
+	GetEndpoint endpoint.Endpoint
+}
diff --git a/pkg/account/versions/transport/exchanges.microgen.go b/pkg/account/versions/transport/exchanges.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..11c9bfbda2c9d21ecd76cc67961c59f8439936c1
--- /dev/null
+++ b/pkg/account/versions/transport/exchanges.microgen.go
@@ -0,0 +1,13 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import version "git.perx.ru/perxis/perxis-go/pkg/version"
+
+type (
+	// Formal exchange type, please do not delete.
+	GetRequest  struct{}
+	GetResponse struct {
+		Version *version.Version `json:"version"`
+	}
+)
diff --git a/pkg/account/versions/transport/grpc/client.microgen.go b/pkg/account/versions/transport/grpc/client.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..2e029d6ca5a7d432e146c103f97da52599a1a8e5
--- /dev/null
+++ b/pkg/account/versions/transport/grpc/client.microgen.go
@@ -0,0 +1,23 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transportgrpc
+
+import (
+	transport "git.perx.ru/perxis/perxis-go/pkg/account/versions/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/versions/account"
+	grpckit "github.com/go-kit/kit/transport/grpc"
+	grpc "google.golang.org/grpc"
+)
+
+func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOption) transport.EndpointsSet {
+	if addr == "" {
+		addr = "account.Versions"
+	}
+	return transport.EndpointsSet{GetEndpoint: grpckit.NewClient(
+		conn, addr, "Get",
+		_Encode_Get_Request,
+		_Decode_Get_Response,
+		pb.GetResponse{},
+		opts...,
+	).Endpoint()}
+}
diff --git a/pkg/account/versions/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/account/versions/transport/grpc/protobuf_endpoint_converters.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..b473a81a79ce5ac8d1d851ebfa5fc61c1dabe7e5
--- /dev/null
+++ b/pkg/account/versions/transport/grpc/protobuf_endpoint_converters.microgen.go
@@ -0,0 +1,44 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// Please, do not change functions names!
+package transportgrpc
+
+import (
+	"context"
+	"errors"
+	transport2 "git.perx.ru/perxis/perxis-go/pkg/account/versions/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/versions/account"
+	empty "github.com/golang/protobuf/ptypes/empty"
+)
+
+func _Encode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Encode_Get_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil GetResponse")
+	}
+	resp := response.(*transport2.GetResponse)
+	respVersion, err := PtrVersionsVersionToProto(resp.Version)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.GetResponse{Version: respVersion}, nil
+}
+
+func _Decode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Decode_Get_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil GetResponse")
+	}
+	resp := response.(*pb.GetResponse)
+	respVersion, err := ProtoToPtrVersionsVersion(resp.Version)
+	if err != nil {
+		return nil, err
+	}
+	return &transport2.GetResponse{Version: respVersion}, nil
+}
diff --git a/pkg/account/versions/transport/grpc/protobuf_type_converters.microgen.go b/pkg/account/versions/transport/grpc/protobuf_type_converters.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..d57d8fc986d4d98e697e7c43b4018b2cd5db3c49
--- /dev/null
+++ b/pkg/account/versions/transport/grpc/protobuf_type_converters.microgen.go
@@ -0,0 +1,40 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// It is better for you if you do not change functions names!
+// This file will never be overwritten.
+package transportgrpc
+
+import (
+	"git.perx.ru/perxis/perxis-go/pkg/version"
+	"git.perx.ru/perxis/perxis-go/proto/common"
+)
+
+func PtrVersionsVersionToProto(version *version.Version) (*common.Version, error) {
+	pVersion := &common.Version{
+		ApiVersion:    version.APIVersion,
+		ServerVersion: version.ServerVersion,
+		Commit:        version.Commit,
+		BuildTime:     version.BuildTime,
+		BuildNumber:   int32(version.BuildNumber),
+	}
+	return pVersion, nil
+}
+
+func ProtoToPtrVersionsVersion(protoVersion *common.Version) (*version.Version, error) {
+	version := &version.Version{
+		APIVersion:    protoVersion.ApiVersion,
+		ServerVersion: protoVersion.ServerVersion,
+		Commit:        protoVersion.Commit,
+		BuildTime:     protoVersion.BuildTime,
+		BuildNumber:   int(protoVersion.BuildNumber),
+	}
+	return version, nil
+}
+
+func PtrVersionVersionToProto(version *version.Version) (*common.Version, error) {
+	panic("function not provided") // TODO: provide converter
+}
+
+func ProtoToPtrVersionVersion(protoVersion *common.Version) (*version.Version, error) {
+	panic("function not provided") // TODO: provide converter
+}
diff --git a/pkg/account/versions/transport/grpc/server.microgen.go b/pkg/account/versions/transport/grpc/server.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..9de34e92049e1c1278e4573862b4a7502289f260
--- /dev/null
+++ b/pkg/account/versions/transport/grpc/server.microgen.go
@@ -0,0 +1,35 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// DO NOT EDIT.
+package transportgrpc
+
+import (
+	transport "git.perx.ru/perxis/perxis-go/pkg/account/versions/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/versions/account"
+	grpc "github.com/go-kit/kit/transport/grpc"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	context "golang.org/x/net/context"
+)
+
+type versionsServer struct {
+	get grpc.Handler
+
+	pb.UnimplementedVersionsServer
+}
+
+func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) pb.VersionsServer {
+	return &versionsServer{get: grpc.NewServer(
+		endpoints.GetEndpoint,
+		_Decode_Get_Request,
+		_Encode_Get_Response,
+		opts...,
+	)}
+}
+
+func (S *versionsServer) Get(ctx context.Context, req *empty.Empty) (*pb.GetResponse, error) {
+	_, resp, err := S.get.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.GetResponse), nil
+}
diff --git a/pkg/account/versions/transport/server.microgen.go b/pkg/account/versions/transport/server.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..9ef5bac4d81f411da9acbdad416d1fb3598a24b3
--- /dev/null
+++ b/pkg/account/versions/transport/server.microgen.go
@@ -0,0 +1,20 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import (
+	"context"
+	versions "git.perx.ru/perxis/perxis-go/pkg/account/versions"
+	endpoint "github.com/go-kit/kit/endpoint"
+)
+
+func Endpoints(svc versions.Versions) EndpointsSet {
+	return EndpointsSet{GetEndpoint: GetEndpoint(svc)}
+}
+
+func GetEndpoint(svc versions.Versions) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		res0, res1 := svc.Get(arg0)
+		return &GetResponse{Version: res0}, res1
+	}
+}
diff --git a/pkg/members/observer/mocks/Observer.go b/pkg/members/observer/mocks/Observer.go
new file mode 100644
index 0000000000000000000000000000000000000000..3cdd32202f982c34e32bdf13943d56aa50e05c99
--- /dev/null
+++ b/pkg/members/observer/mocks/Observer.go
@@ -0,0 +1,30 @@
+// Code generated by mockery v2.7.4. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Observer is an autogenerated mock type for the Observer type
+type Observer struct {
+	mock.Mock
+}
+
+// OnCollaboratorSet provides a mock function with given fields: ctx, collaborator
+func (_m *Observer) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (string, error) {
+	ret := _m.Called(ctx, collaborator)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, *collaborators.Collaborator) error); ok {
+		r0 = rf(ctx, collaborator)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return "", r0
+}
diff --git a/pkg/members/observer/service.go b/pkg/members/observer/service.go
new file mode 100644
index 0000000000000000000000000000000000000000..b9bf10e43f901f4f1ccbfb1c3eee83320ddd5f04
--- /dev/null
+++ b/pkg/members/observer/service.go
@@ -0,0 +1,14 @@
+package observer
+
+import (
+	"context"
+
+	"git.perx.ru/perxis/perxis-go/pkg/collaborators"
+)
+
+// @microgen grpc
+// @protobuf git.perx.ru/perxis/perxis/proto/members
+// @grpc-addr account.members.Observer
+type Observer interface {
+	OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error)
+}
diff --git a/pkg/members/observer/transport/client.microgen.go b/pkg/members/observer/transport/client.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..f60e6717d8b4804cd5d42a0064fe3ed274bcb7e1
--- /dev/null
+++ b/pkg/members/observer/transport/client.microgen.go
@@ -0,0 +1,23 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import (
+	"context"
+	"errors"
+	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+func (set EndpointsSet) OnCollaboratorSet(arg0 context.Context, arg1 *collaborators.Collaborator) (res0 string, res1 error) {
+	request := OnCollaboratorSetRequest{Collaborator: arg1}
+	response, res1 := set.OnCollaboratorSetEndpoint(arg0, &request)
+	if res1 != nil {
+		if e, ok := status.FromError(res1); ok || e.Code() == codes.Internal || e.Code() == codes.Unknown {
+			res1 = errors.New(e.Message())
+		}
+		return
+	}
+	return response.(*OnCollaboratorSetResponse).DelayedTaskID, res1
+}
diff --git a/pkg/members/observer/transport/endpoints.microgen.go b/pkg/members/observer/transport/endpoints.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..859f2e0c3edd4edcf67e21acca5545b927b07f32
--- /dev/null
+++ b/pkg/members/observer/transport/endpoints.microgen.go
@@ -0,0 +1,10 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import endpoint "github.com/go-kit/kit/endpoint"
+
+// EndpointsSet implements Observer API and used for transport purposes.
+type EndpointsSet struct {
+	OnCollaboratorSetEndpoint endpoint.Endpoint
+}
diff --git a/pkg/members/observer/transport/exchanges.microgen.go b/pkg/members/observer/transport/exchanges.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..56b68bd77675c788e11605b58a6e2ef9c1cffd7e
--- /dev/null
+++ b/pkg/members/observer/transport/exchanges.microgen.go
@@ -0,0 +1,14 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+
+type (
+	OnCollaboratorSetRequest struct {
+		Collaborator *collaborators.Collaborator `json:"collaborator"`
+	}
+	OnCollaboratorSetResponse struct {
+		DelayedTaskID string `json:"delayed_task_id"`
+	}
+)
diff --git a/pkg/members/observer/transport/grpc/client.microgen.go b/pkg/members/observer/transport/grpc/client.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..6e1e21c700a08ab5738950f6b8b95aa8ed34e732
--- /dev/null
+++ b/pkg/members/observer/transport/grpc/client.microgen.go
@@ -0,0 +1,23 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transportgrpc
+
+import (
+	transport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/members"
+	grpckit "github.com/go-kit/kit/transport/grpc"
+	grpc "google.golang.org/grpc"
+)
+
+func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOption) transport.EndpointsSet {
+	if addr == "" {
+		addr = "account.members.Observer"
+	}
+	return transport.EndpointsSet{OnCollaboratorSetEndpoint: grpckit.NewClient(
+		conn, addr, "OnCollaboratorSet",
+		_Encode_OnCollaboratorSet_Request,
+		_Decode_OnCollaboratorSet_Response,
+		pb.OnCollaboratorSetResponse{},
+		opts...,
+	).Endpoint()}
+}
diff --git a/pkg/members/observer/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/members/observer/transport/grpc/protobuf_endpoint_converters.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..57c7b9d9e66969a356a1fcd8ad180731059206ab
--- /dev/null
+++ b/pkg/members/observer/transport/grpc/protobuf_endpoint_converters.microgen.go
@@ -0,0 +1,52 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// Please, do not change functions names!
+package transportgrpc
+
+import (
+	"context"
+	"errors"
+
+	transport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/members"
+)
+
+func _Encode_OnCollaboratorSet_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil OnCollaboratorSetRequest")
+	}
+	req := request.(*transport.OnCollaboratorSetRequest)
+	reqCollaborator, err := PtrCollaboratorsCollaboratorToProto(req.Collaborator)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.OnCollaboratorSetRequest{Collaborator: reqCollaborator}, nil
+}
+
+func _Decode_OnCollaboratorSet_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil OnCollaboratorSetRequest")
+	}
+	req := request.(*pb.OnCollaboratorSetRequest)
+	reqCollaborator, err := ProtoToPtrCollaboratorsCollaborator(req.Collaborator)
+	if err != nil {
+		return nil, err
+	}
+	return &transport.OnCollaboratorSetRequest{Collaborator: reqCollaborator}, nil
+}
+
+func _Decode_OnCollaboratorSet_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil OnCollaboratorSetResponse")
+	}
+	resp := response.(*pb.OnCollaboratorSetResponse)
+	return &transport.OnCollaboratorSetResponse{DelayedTaskID: string(resp.DelayedTaskId)}, nil
+}
+
+func _Encode_OnCollaboratorSet_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil OnCollaboratorSetResponse")
+	}
+	resp := response.(*transport.OnCollaboratorSetResponse)
+	return &pb.OnCollaboratorSetResponse{DelayedTaskId: resp.DelayedTaskID}, nil
+}
diff --git a/pkg/members/observer/transport/grpc/protobuf_type_converters.microgen.go b/pkg/members/observer/transport/grpc/protobuf_type_converters.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..9016b6319c0747adcb032e119623a19aa3696ca6
--- /dev/null
+++ b/pkg/members/observer/transport/grpc/protobuf_type_converters.microgen.go
@@ -0,0 +1,32 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// It is better for you if you do not change functions names!
+// This file will never be overwritten.
+package transportgrpc
+
+import (
+	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	pbcommon "git.perx.ru/perxis/perxis-go/proto/common"
+)
+
+func PtrCollaboratorsCollaboratorToProto(collaborator *collaborators.Collaborator) (*pbcommon.Collaborator, error) {
+	if collaborator == nil {
+		return nil, nil
+	}
+	return &pbcommon.Collaborator{
+		SpaceId: collaborator.SpaceID,
+		Subject: collaborator.Subject,
+		Role:    collaborator.Role,
+	}, nil
+}
+
+func ProtoToPtrCollaboratorsCollaborator(protoCollaborator *pbcommon.Collaborator) (*collaborators.Collaborator, error) {
+	if protoCollaborator == nil {
+		return nil, nil
+	}
+	return &collaborators.Collaborator{
+		SpaceID: protoCollaborator.SpaceId,
+		Subject: protoCollaborator.Subject,
+		Role:    protoCollaborator.Role,
+	}, nil
+}
diff --git a/pkg/members/observer/transport/grpc/server.microgen.go b/pkg/members/observer/transport/grpc/server.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..68d0069d06b5c3b34ccb98507e01a860672b00d2
--- /dev/null
+++ b/pkg/members/observer/transport/grpc/server.microgen.go
@@ -0,0 +1,34 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// DO NOT EDIT.
+package transportgrpc
+
+import (
+	transport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/members"
+	grpc "github.com/go-kit/kit/transport/grpc"
+	context "golang.org/x/net/context"
+)
+
+type observerServer struct {
+	onCollaboratorSet grpc.Handler
+
+	pb.UnimplementedObserverServer
+}
+
+func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) pb.ObserverServer {
+	return &observerServer{onCollaboratorSet: grpc.NewServer(
+		endpoints.OnCollaboratorSetEndpoint,
+		_Decode_OnCollaboratorSet_Request,
+		_Encode_OnCollaboratorSet_Response,
+		opts...,
+	)}
+}
+
+func (S *observerServer) OnCollaboratorSet(ctx context.Context, req *pb.OnCollaboratorSetRequest) (*pb.OnCollaboratorSetResponse, error) {
+	_, resp, err := S.onCollaboratorSet.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.OnCollaboratorSetResponse), nil
+}
diff --git a/pkg/members/observer/transport/server.microgen.go b/pkg/members/observer/transport/server.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..3277c72b263e6efaea0687a526edcaafcb43ddd8
--- /dev/null
+++ b/pkg/members/observer/transport/server.microgen.go
@@ -0,0 +1,21 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import (
+	"context"
+	observer "git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	endpoint "github.com/go-kit/kit/endpoint"
+)
+
+func Endpoints(svc observer.Observer) EndpointsSet {
+	return EndpointsSet{OnCollaboratorSetEndpoint: OnCollaboratorSetEndpoint(svc)}
+}
+
+func OnCollaboratorSetEndpoint(svc observer.Observer) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*OnCollaboratorSetRequest)
+		res0, res1 := svc.OnCollaboratorSet(arg0, req.Collaborator)
+		return &OnCollaboratorSetResponse{DelayedTaskID: res0}, res1
+	}
+}