diff --git a/pkg/collaborators/collaborator.go b/pkg/collaborators/collaborator.go
new file mode 100644
index 0000000000000000000000000000000000000000..701d8e85b578dafc2036c281c204720080412ac5
--- /dev/null
+++ b/pkg/collaborators/collaborator.go
@@ -0,0 +1,7 @@
+package collaborators
+
+type Collaborator struct {
+	SpaceID string `bson:"spaceId"`
+	Subject string `bson:"subject"`
+	Role    string `bson:"role"`
+}
diff --git a/pkg/collaborators/mocks/Collaborators.go b/pkg/collaborators/mocks/Collaborators.go
new file mode 100644
index 0000000000000000000000000000000000000000..6bcd7fb1c462ae85ef01ca50efa6145ce2f8d591
--- /dev/null
+++ b/pkg/collaborators/mocks/Collaborators.go
@@ -0,0 +1,110 @@
+// 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"
+)
+
+// Collaborators is an autogenerated mock type for the Collaborators type
+type Collaborators struct {
+	mock.Mock
+}
+
+// Get provides a mock function with given fields: ctx, spaceId, userId
+func (_m *Collaborators) Get(ctx context.Context, spaceId, subject string) (string, error) {
+	ret := _m.Called(ctx, spaceId, subject)
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func(context.Context, string, string) string); ok {
+		r0 = rf(ctx, spaceId, subject)
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
+		r1 = rf(ctx, spaceId, subject)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ListCollaborators provides a mock function with given fields: ctx, spaceId
+func (_m *Collaborators) ListCollaborators(ctx context.Context, spaceId string) ([]*collaborators.Collaborator, error) {
+	ret := _m.Called(ctx, spaceId)
+
+	var r0 []*collaborators.Collaborator
+	if rf, ok := ret.Get(0).(func(context.Context, string) []*collaborators.Collaborator); ok {
+		r0 = rf(ctx, spaceId)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*collaborators.Collaborator)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+		r1 = rf(ctx, spaceId)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ListSpaces provides a mock function with given fields: ctx, userId
+func (_m *Collaborators) ListSpaces(ctx context.Context, subject string) ([]*collaborators.Collaborator, error) {
+	ret := _m.Called(ctx, subject)
+
+	var r0 []*collaborators.Collaborator
+	if rf, ok := ret.Get(0).(func(context.Context, string) []*collaborators.Collaborator); ok {
+		r0 = rf(ctx, subject)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*collaborators.Collaborator)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+		r1 = rf(ctx, subject)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Remove provides a mock function with given fields: ctx, spaceId, userId
+func (_m *Collaborators) Remove(ctx context.Context, spaceId, subject string) error {
+	ret := _m.Called(ctx, spaceId, subject)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
+		r0 = rf(ctx, spaceId, subject)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Set provides a mock function with given fields: ctx, spaceId, userId, role
+func (_m *Collaborators) Set(ctx context.Context, spaceId, subject, role string) error {
+	ret := _m.Called(ctx, spaceId, subject, role)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, string) error); ok {
+		r0 = rf(ctx, spaceId, subject, role)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
diff --git a/pkg/collaborators/service.go b/pkg/collaborators/service.go
new file mode 100644
index 0000000000000000000000000000000000000000..fa56271b89e57a87fc501a11a1ae648f6214a7d5
--- /dev/null
+++ b/pkg/collaborators/service.go
@@ -0,0 +1,26 @@
+package collaborators
+
+import (
+	"context"
+)
+
+// @microgen grpc, recovering, middleware
+// @protobuf git.perx.ru/perxis/perxis-go/proto/collaborators
+// @grpc-addr content.collaborators.Collaborators
+type Collaborators interface {
+
+	// Set - устанавливает участие пользователя в пространстве и его роль
+	Set(ctx context.Context, spaceId, subject, role string) (err error)
+
+	// Get - возвращает роль пользователя в пространстве
+	Get(ctx context.Context, spaceId, subject string) (role string, err error)
+
+	// Remove - удаляет участие пользователя в пространстве
+	Remove(ctx context.Context, spaceId, subject string) (err error)
+
+	// ListCollaborators - возвращает участников пространства и их ролей
+	ListCollaborators(ctx context.Context, spaceId string) (collaborators []*Collaborator, err error)
+
+	// ListSpaces - возвращает список пространств пользователя
+	ListSpaces(ctx context.Context, subject string) (spaces []*Collaborator, err error)
+}
diff --git a/pkg/collaborators/transport/client.microgen.go b/pkg/collaborators/transport/client.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..eb0dbbe7bc1ea7bad07220fba5cdc6e3b1c9e503
--- /dev/null
+++ b/pkg/collaborators/transport/client.microgen.go
@@ -0,0 +1,82 @@
+// 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) Set(arg0 context.Context, arg1 string, arg2 string, arg3 string) (res0 error) {
+	request := SetRequest{
+		Role:    arg3,
+		SpaceId: arg1,
+		Subject: arg2,
+	}
+	_, res0 = set.SetEndpoint(arg0, &request)
+	if res0 != nil {
+		if e, ok := status.FromError(res0); ok || e.Code() == codes.Internal || e.Code() == codes.Unknown {
+			res0 = errors.New(e.Message())
+		}
+		return
+	}
+	return res0
+}
+
+func (set EndpointsSet) Get(arg0 context.Context, arg1 string, arg2 string) (res0 string, res1 error) {
+	request := GetRequest{
+		SpaceId: arg1,
+		Subject: arg2,
+	}
+	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).Role, res1
+}
+
+func (set EndpointsSet) Remove(arg0 context.Context, arg1 string, arg2 string) (res0 error) {
+	request := RemoveRequest{
+		SpaceId: arg1,
+		Subject: arg2,
+	}
+	_, res0 = set.RemoveEndpoint(arg0, &request)
+	if res0 != nil {
+		if e, ok := status.FromError(res0); ok || e.Code() == codes.Internal || e.Code() == codes.Unknown {
+			res0 = errors.New(e.Message())
+		}
+		return
+	}
+	return res0
+}
+
+func (set EndpointsSet) ListCollaborators(arg0 context.Context, arg1 string) (res0 []*collaborators.Collaborator, res1 error) {
+	request := ListCollaboratorsRequest{SpaceId: arg1}
+	response, res1 := set.ListCollaboratorsEndpoint(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.(*ListCollaboratorsResponse).Collaborators, res1
+}
+
+func (set EndpointsSet) ListSpaces(arg0 context.Context, arg1 string) (res0 []*collaborators.Collaborator, res1 error) {
+	request := ListSpacesRequest{Subject: arg1}
+	response, res1 := set.ListSpacesEndpoint(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.(*ListSpacesResponse).Spaces, res1
+}
diff --git a/pkg/collaborators/transport/endpoints.microgen.go b/pkg/collaborators/transport/endpoints.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..022bf403e3a574918d006786c54cfc854f318915
--- /dev/null
+++ b/pkg/collaborators/transport/endpoints.microgen.go
@@ -0,0 +1,14 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import endpoint "github.com/go-kit/kit/endpoint"
+
+// EndpointsSet implements Collaborators API and used for transport purposes.
+type EndpointsSet struct {
+	SetEndpoint               endpoint.Endpoint
+	GetEndpoint               endpoint.Endpoint
+	RemoveEndpoint            endpoint.Endpoint
+	ListCollaboratorsEndpoint endpoint.Endpoint
+	ListSpacesEndpoint        endpoint.Endpoint
+}
diff --git a/pkg/collaborators/transport/exchanges.microgen.go b/pkg/collaborators/transport/exchanges.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..a51674f40f696f15d1f625fbf7923bdd4879e6b5
--- /dev/null
+++ b/pkg/collaborators/transport/exchanges.microgen.go
@@ -0,0 +1,44 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+
+type (
+	SetRequest struct {
+		SpaceId string `json:"space_id"`
+		Subject string `json:"subject"`
+		Role    string `json:"role"`
+	}
+	// Formal exchange type, please do not delete.
+	SetResponse struct{}
+
+	GetRequest struct {
+		SpaceId string `json:"space_id"`
+		Subject string `json:"subject"`
+	}
+	GetResponse struct {
+		Role string `json:"role"`
+	}
+
+	RemoveRequest struct {
+		SpaceId string `json:"space_id"`
+		Subject string `json:"subject"`
+	}
+	// Formal exchange type, please do not delete.
+	RemoveResponse struct{}
+
+	ListCollaboratorsRequest struct {
+		SpaceId string `json:"space_id"`
+	}
+	ListCollaboratorsResponse struct {
+		Collaborators []*collaborators.Collaborator `json:"collaborators"`
+	}
+
+	ListSpacesRequest struct {
+		Subject string `json:"subject"`
+	}
+	ListSpacesResponse struct {
+		Spaces []*collaborators.Collaborator `json:"spaces"`
+	}
+)
diff --git a/pkg/collaborators/transport/grpc/client.microgen.go b/pkg/collaborators/transport/grpc/client.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..eaf778f878438fc2a44ef980a25a3aed803fcee8
--- /dev/null
+++ b/pkg/collaborators/transport/grpc/client.microgen.go
@@ -0,0 +1,54 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transportgrpc
+
+import (
+	transport "git.perx.ru/perxis/perxis-go/pkg/collaborators/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/collaborators"
+	grpckit "github.com/go-kit/kit/transport/grpc"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	grpc "google.golang.org/grpc"
+)
+
+func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOption) transport.EndpointsSet {
+	if addr == "" {
+		addr = "content.collaborators.Collaborators"
+	}
+	return transport.EndpointsSet{
+		GetEndpoint: grpckit.NewClient(
+			conn, addr, "Get",
+			_Encode_Get_Request,
+			_Decode_Get_Response,
+			pb.GetResponse{},
+			opts...,
+		).Endpoint(),
+		ListCollaboratorsEndpoint: grpckit.NewClient(
+			conn, addr, "ListCollaborators",
+			_Encode_ListCollaborators_Request,
+			_Decode_ListCollaborators_Response,
+			pb.ListCollaboratorsResponse{},
+			opts...,
+		).Endpoint(),
+		ListSpacesEndpoint: grpckit.NewClient(
+			conn, addr, "ListSpaces",
+			_Encode_ListSpaces_Request,
+			_Decode_ListSpaces_Response,
+			pb.ListSpacesResponse{},
+			opts...,
+		).Endpoint(),
+		RemoveEndpoint: grpckit.NewClient(
+			conn, addr, "Remove",
+			_Encode_Remove_Request,
+			_Decode_Remove_Response,
+			empty.Empty{},
+			opts...,
+		).Endpoint(),
+		SetEndpoint: grpckit.NewClient(
+			conn, addr, "Set",
+			_Encode_Set_Request,
+			_Decode_Set_Response,
+			empty.Empty{},
+			opts...,
+		).Endpoint(),
+	}
+}
diff --git a/pkg/collaborators/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/collaborators/transport/grpc/protobuf_endpoint_converters.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..ec484dfe3b9a8ee1cb38d1d1d03cbfc5ce7a1f8a
--- /dev/null
+++ b/pkg/collaborators/transport/grpc/protobuf_endpoint_converters.microgen.go
@@ -0,0 +1,193 @@
+// 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/collaborators/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/collaborators"
+	empty "github.com/golang/protobuf/ptypes/empty"
+)
+
+func _Encode_Set_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil SetRequest")
+	}
+	req := request.(*transport.SetRequest)
+	return &pb.SetRequest{
+		Role:    req.Role,
+		SpaceId: req.SpaceId,
+		Subject: req.Subject,
+	}, nil
+}
+
+func _Encode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil GetRequest")
+	}
+	req := request.(*transport.GetRequest)
+	return &pb.GetRequest{
+		SpaceId: req.SpaceId,
+		Subject: req.Subject,
+	}, nil
+}
+
+func _Encode_Remove_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil RemoveRequest")
+	}
+	req := request.(*transport.RemoveRequest)
+	return &pb.RemoveRequest{
+		SpaceId: req.SpaceId,
+		Subject: req.Subject,
+	}, nil
+}
+
+func _Encode_ListCollaborators_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil ListCollaboratorsRequest")
+	}
+	req := request.(*transport.ListCollaboratorsRequest)
+	return &pb.ListCollaboratorsRequest{SpaceId: req.SpaceId}, nil
+}
+
+func _Encode_ListSpaces_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil ListSpacesRequest")
+	}
+	req := request.(*transport.ListSpacesRequest)
+	return &pb.ListSpacesRequest{Subject: req.Subject}, nil
+}
+
+func _Encode_Set_Response(ctx context.Context, response 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.(*transport.GetResponse)
+	return &pb.GetResponse{Role: resp.Role}, nil
+}
+
+func _Encode_Remove_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Encode_ListCollaborators_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil ListCollaboratorsResponse")
+	}
+	resp := response.(*transport.ListCollaboratorsResponse)
+	respCollaborators, err := ListPtrCollaboratorToProto(resp.Collaborators)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.ListCollaboratorsResponse{Collaborators: respCollaborators}, nil
+}
+
+func _Encode_ListSpaces_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil ListSpacesResponse")
+	}
+	resp := response.(*transport.ListSpacesResponse)
+	respSpaces, err := ListPtrCollaboratorToProto(resp.Spaces)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.ListSpacesResponse{Spaces: respSpaces}, nil
+}
+
+func _Decode_Set_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil SetRequest")
+	}
+	req := request.(*pb.SetRequest)
+	return &transport.SetRequest{
+		Role:    string(req.Role),
+		SpaceId: string(req.SpaceId),
+		Subject: string(req.Subject),
+	}, nil
+}
+
+func _Decode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil GetRequest")
+	}
+	req := request.(*pb.GetRequest)
+	return &transport.GetRequest{
+		SpaceId: string(req.SpaceId),
+		Subject: string(req.Subject),
+	}, nil
+}
+
+func _Decode_Remove_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil RemoveRequest")
+	}
+	req := request.(*pb.RemoveRequest)
+	return &transport.RemoveRequest{
+		SpaceId: string(req.SpaceId),
+		Subject: string(req.Subject),
+	}, nil
+}
+
+func _Decode_ListCollaborators_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil ListCollaboratorsRequest")
+	}
+	req := request.(*pb.ListCollaboratorsRequest)
+	return &transport.ListCollaboratorsRequest{SpaceId: string(req.SpaceId)}, nil
+}
+
+func _Decode_ListSpaces_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil ListSpacesRequest")
+	}
+	req := request.(*pb.ListSpacesRequest)
+	return &transport.ListSpacesRequest{Subject: string(req.Subject)}, nil
+}
+
+func _Decode_Set_Response(ctx context.Context, response 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)
+	return &transport.GetResponse{Role: string(resp.Role)}, nil
+}
+
+func _Decode_Remove_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Decode_ListCollaborators_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil ListCollaboratorsResponse")
+	}
+	resp := response.(*pb.ListCollaboratorsResponse)
+	respCollaborators, err := ProtoToListPtrCollaborator(resp.Collaborators)
+	if err != nil {
+		return nil, err
+	}
+	return &transport.ListCollaboratorsResponse{Collaborators: respCollaborators}, nil
+}
+
+func _Decode_ListSpaces_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil ListSpacesResponse")
+	}
+	resp := response.(*pb.ListSpacesResponse)
+	respSpaces, err := ProtoToListPtrCollaborator(resp.Spaces)
+	if err != nil {
+		return nil, err
+	}
+	return &transport.ListSpacesResponse{Spaces: respSpaces}, nil
+}
diff --git a/pkg/collaborators/transport/grpc/protobuf_type_converters.microgen.go b/pkg/collaborators/transport/grpc/protobuf_type_converters.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..5752acdf6235ab7b1bd09a46fc9ff3c8467ca7df
--- /dev/null
+++ b/pkg/collaborators/transport/grpc/protobuf_type_converters.microgen.go
@@ -0,0 +1,34 @@
+// 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 (
+	service "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	pbcommon "git.perx.ru/perxis/perxis-go/proto/common"
+)
+
+func ListPtrCollaboratorToProto(collaborators []*service.Collaborator) ([]*pbcommon.Collaborator, error) {
+	protoCollaborators := make([]*pbcommon.Collaborator, 0, len(collaborators))
+	for _, c := range collaborators {
+		protoCollaborators = append(protoCollaborators, &pbcommon.Collaborator{
+			SpaceId: c.SpaceID,
+			Subject: c.Subject,
+			Role:    c.Role,
+		})
+	}
+	return protoCollaborators, nil
+}
+
+func ProtoToListPtrCollaborator(protoCollaborators []*pbcommon.Collaborator) ([]*service.Collaborator, error) {
+	collaborators := make([]*service.Collaborator, 0, len(protoCollaborators))
+	for _, c := range protoCollaborators {
+		collaborators = append(collaborators, &service.Collaborator{
+			SpaceID: c.SpaceId,
+			Subject: c.Subject,
+			Role:    c.Role,
+		})
+	}
+	return collaborators, nil
+}
diff --git a/pkg/collaborators/transport/grpc/server.microgen.go b/pkg/collaborators/transport/grpc/server.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..6ece1b8b7d40f2c78d178ea88cf2aeb2ff7bb44f
--- /dev/null
+++ b/pkg/collaborators/transport/grpc/server.microgen.go
@@ -0,0 +1,97 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+// DO NOT EDIT.
+package transportgrpc
+
+import (
+	transport "git.perx.ru/perxis/perxis-go/pkg/collaborators/transport"
+	pb "git.perx.ru/perxis/perxis-go/proto/collaborators"
+	grpc "github.com/go-kit/kit/transport/grpc"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	context "golang.org/x/net/context"
+)
+
+type collaboratorsServer struct {
+	set               grpc.Handler
+	get               grpc.Handler
+	remove            grpc.Handler
+	listCollaborators grpc.Handler
+	listSpaces        grpc.Handler
+
+	pb.UnimplementedCollaboratorsServer
+}
+
+func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) pb.CollaboratorsServer {
+	return &collaboratorsServer{
+		get: grpc.NewServer(
+			endpoints.GetEndpoint,
+			_Decode_Get_Request,
+			_Encode_Get_Response,
+			opts...,
+		),
+		listCollaborators: grpc.NewServer(
+			endpoints.ListCollaboratorsEndpoint,
+			_Decode_ListCollaborators_Request,
+			_Encode_ListCollaborators_Response,
+			opts...,
+		),
+		listSpaces: grpc.NewServer(
+			endpoints.ListSpacesEndpoint,
+			_Decode_ListSpaces_Request,
+			_Encode_ListSpaces_Response,
+			opts...,
+		),
+		remove: grpc.NewServer(
+			endpoints.RemoveEndpoint,
+			_Decode_Remove_Request,
+			_Encode_Remove_Response,
+			opts...,
+		),
+		set: grpc.NewServer(
+			endpoints.SetEndpoint,
+			_Decode_Set_Request,
+			_Encode_Set_Response,
+			opts...,
+		),
+	}
+}
+
+func (S *collaboratorsServer) Set(ctx context.Context, req *pb.SetRequest) (*empty.Empty, error) {
+	_, resp, err := S.set.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*empty.Empty), nil
+}
+
+func (S *collaboratorsServer) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) {
+	_, resp, err := S.get.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.GetResponse), nil
+}
+
+func (S *collaboratorsServer) Remove(ctx context.Context, req *pb.RemoveRequest) (*empty.Empty, error) {
+	_, resp, err := S.remove.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*empty.Empty), nil
+}
+
+func (S *collaboratorsServer) ListCollaborators(ctx context.Context, req *pb.ListCollaboratorsRequest) (*pb.ListCollaboratorsResponse, error) {
+	_, resp, err := S.listCollaborators.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.ListCollaboratorsResponse), nil
+}
+
+func (S *collaboratorsServer) ListSpaces(ctx context.Context, req *pb.ListSpacesRequest) (*pb.ListSpacesResponse, error) {
+	_, resp, err := S.listSpaces.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.ListSpacesResponse), nil
+}
diff --git a/pkg/collaborators/transport/server.microgen.go b/pkg/collaborators/transport/server.microgen.go
new file mode 100644
index 0000000000000000000000000000000000000000..7d0a571d32ebe2ec2a49190a5d79136ff96ba8c1
--- /dev/null
+++ b/pkg/collaborators/transport/server.microgen.go
@@ -0,0 +1,60 @@
+// Code generated by microgen 0.9.1. DO NOT EDIT.
+
+package transport
+
+import (
+	"context"
+
+	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	endpoint "github.com/go-kit/kit/endpoint"
+)
+
+func Endpoints(svc collaborators.Collaborators) EndpointsSet {
+	return EndpointsSet{
+		GetEndpoint:               GetEndpoint(svc),
+		ListCollaboratorsEndpoint: ListCollaboratorsEndpoint(svc),
+		ListSpacesEndpoint:        ListSpacesEndpoint(svc),
+		RemoveEndpoint:            RemoveEndpoint(svc),
+		SetEndpoint:               SetEndpoint(svc),
+	}
+}
+
+func SetEndpoint(svc collaborators.Collaborators) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*SetRequest)
+		res0 := svc.Set(arg0, req.SpaceId, req.Subject, req.Role)
+		return &SetResponse{}, res0
+	}
+}
+
+func GetEndpoint(svc collaborators.Collaborators) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*GetRequest)
+		res0, res1 := svc.Get(arg0, req.SpaceId, req.Subject)
+		return &GetResponse{Role: res0}, res1
+	}
+}
+
+func RemoveEndpoint(svc collaborators.Collaborators) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*RemoveRequest)
+		res0 := svc.Remove(arg0, req.SpaceId, req.Subject)
+		return &RemoveResponse{}, res0
+	}
+}
+
+func ListCollaboratorsEndpoint(svc collaborators.Collaborators) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*ListCollaboratorsRequest)
+		res0, res1 := svc.ListCollaborators(arg0, req.SpaceId)
+		return &ListCollaboratorsResponse{Collaborators: res0}, res1
+	}
+}
+
+func ListSpacesEndpoint(svc collaborators.Collaborators) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*ListSpacesRequest)
+		res0, res1 := svc.ListSpaces(arg0, req.Subject)
+		return &ListSpacesResponse{Spaces: res0}, res1
+	}
+}