diff --git a/api/projects_servicer.py b/api/projects_servicer.py
new file mode 100644
index 0000000..640a433
--- /dev/null
+++ b/api/projects_servicer.py
@@ -0,0 +1,341 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import logging
+
+import settings
+
+from api import monorail_servicer
+from api import converters
+from api.api_proto import projects_pb2
+from api.api_proto import project_objects_pb2
+from api.api_proto import projects_prpc_pb2
+from businesslogic import work_env
+from framework import framework_bizobj
+from framework import exceptions
+from framework import framework_views
+from framework import permissions
+from project import project_helpers
+from tracker import tracker_bizobj
+from tracker import tracker_helpers
+
+# TODO(zhangtiff): Remove dependency on tracker_views.
+from tracker import tracker_views
+
+
+class ProjectsServicer(monorail_servicer.MonorailServicer):
+  """Handle API requests related to Project objects.
+
+  Each API request is implemented with a method as defined in the .proto
+  file that does any request-specific validation, uses work_env to
+  safely operate on business objects, and returns a response proto.
+  """
+
+  DESCRIPTION = projects_prpc_pb2.ProjectsServiceDescription
+
+  def _GetProject(self, mc, request, use_cache=True):
+    """Get the project object specified in the request."""
+    with work_env.WorkEnv(mc, self.services, phase='getting project') as we:
+      project = we.GetProjectByName(request.project_name, use_cache=use_cache)
+      # Perms in this project are already looked up in MonorailServicer.
+    return project
+
+  @monorail_servicer.PRPCMethod
+  def ListProjects(self, _mc, _request):
+    return projects_pb2.ListProjectsResponse(
+        projects=[
+            project_objects_pb2.Project(name='One'),
+            project_objects_pb2.Project(name='Two')],
+        next_page_token='next...')
+
+  @monorail_servicer.PRPCMethod
+  def ListProjectTemplates(self, mc, request):
+    """Return the specific project's templates."""
+    if not request.project_name:
+      raise exceptions.InputException('Param `project_name` required.')
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+      templates = we.ListProjectTemplates(project.project_id)
+
+    with mc.profiler.Phase('converting to response objects'):
+      involved_user_ids = tracker_bizobj.UsersInvolvedInTemplates(templates)
+      users_by_id = framework_views.MakeAllUserViews(
+          mc.cnxn, self.services.user, involved_user_ids)
+      response = projects_pb2.ListProjectTemplatesResponse(
+          templates=converters.ConvertProjectTemplateDefs(
+              templates, users_by_id, config))
+
+    return response
+
+  @monorail_servicer.PRPCMethod
+  def GetConfig(self, mc, request):
+    """Return the specified project config."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+
+    with mc.profiler.Phase('making user views'):
+      involved_user_ids = tracker_bizobj.UsersInvolvedInConfig(config)
+      users_by_id = framework_views.MakeAllUserViews(
+          mc.cnxn, self.services.user, involved_user_ids)
+      framework_views.RevealAllEmailsToMembers(
+          mc.cnxn, self.services, mc.auth, users_by_id, project)
+
+      label_ids = tracker_bizobj.LabelIDsInvolvedInConfig(config)
+      labels_by_id = {
+        label_id: self.services.config.LookupLabel(
+            mc.cnxn, config.project_id, label_id)
+        for label_id in label_ids}
+
+    result = converters.ConvertConfig(
+        project, config, users_by_id, labels_by_id)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def GetPresentationConfig(self, mc, request):
+    """Return the UI centric pieces of the project config."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+
+    project_thumbnail_url = tracker_views.LogoView(project).thumbnail_url
+    project_summary = project.summary
+    custom_issue_entry_url = config.custom_issue_entry_url
+    revision_url_format = (
+        project.revision_url_format or settings.revision_url_format)
+
+    default_query = None
+    saved_queries = None
+
+    # Only show default query or project saved queries for project
+    # members, in case they contain sensitive information.
+    if framework_bizobj.UserIsInProject(
+        project, mc.auth.effective_ids):
+      default_query = config.member_default_query
+
+      saved_queries = self.services.features.GetCannedQueriesByProjectID(
+          mc.cnxn, project.project_id)
+
+    return project_objects_pb2.PresentationConfig(
+        project_thumbnail_url=project_thumbnail_url,
+        project_summary=project_summary,
+        custom_issue_entry_url=custom_issue_entry_url,
+        default_query=default_query,
+        default_col_spec=config.default_col_spec,
+        default_sort_spec=config.default_sort_spec,
+        default_x_attr=config.default_x_attr,
+        default_y_attr=config.default_y_attr,
+        saved_queries=converters.IngestSavedQueries(
+            mc.cnxn, self.services.project, saved_queries),
+        revision_url_format=revision_url_format)
+
+  @monorail_servicer.PRPCMethod
+  def GetCustomPermissions(self, mc, request):
+    """Return the custom permissions for the given project."""
+    project = self._GetProject(mc, request)
+    custom_permissions = permissions.GetCustomPermissions(project)
+
+    result = projects_pb2.GetCustomPermissionsResponse(
+        permissions=custom_permissions)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def GetVisibleMembers(self, mc, request):
+    """Return the members of the project that the user can see.
+
+    Raises:
+      PermissionException the user is not allowed to view the project members.
+    """
+    project = self._GetProject(mc, request)
+    if not permissions.CanViewContributorList(mc, project):
+      raise permissions.PermissionException(
+          'User is not allowed to view the project members')
+
+    users_by_id = tracker_helpers.GetVisibleMembers(mc, project, self.services)
+
+    sorted_user_ids = sorted(
+        users_by_id, key=lambda uid: users_by_id[uid].email)
+    user_refs = converters.ConvertUserRefs(
+        sorted_user_ids, [], users_by_id, True)
+    sorted_group_ids = sorted(
+        (uv.user_id for uv in users_by_id.values() if uv.is_group),
+        key=lambda uid: users_by_id[uid].email)
+    group_refs = converters.ConvertUserRefs(
+        sorted_group_ids, [], users_by_id, True)
+
+    result = projects_pb2.GetVisibleMembersResponse(
+        user_refs=user_refs, group_refs=group_refs)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def GetLabelOptions(self, mc, request):
+    """Return the label options for autocomplete for the given project."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+
+    label_options = tracker_helpers.GetLabelOptions(
+        config, permissions.GetCustomPermissions(project))
+    label_defs = [
+        project_objects_pb2.LabelDef(
+            label=label['name'],
+            docstring=label['doc'])
+        for label in label_options]
+
+    result = projects_pb2.GetLabelOptionsResponse(
+        label_options=label_defs,
+        exclusive_label_prefixes=config.exclusive_label_prefixes)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def ListStatuses(self, mc, request):
+    """Return all well-known statuses in the specified project."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+
+    status_defs = [
+        converters.ConvertStatusDef(sd)
+        for sd in config.well_known_statuses]
+    statuses_offer_merge = [
+        converters.ConvertStatusRef(sd.status, None, config)
+        for sd in config.well_known_statuses
+        if sd.status in config.statuses_offer_merge]
+
+    result = projects_pb2.ListStatusesResponse(
+        status_defs=status_defs,
+        statuses_offer_merge=statuses_offer_merge,
+        restrict_to_known=config.restrict_to_known)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def ListComponents(self, mc, request):
+    """Return all component defs in the specified project."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+
+    with mc.profiler.Phase('making user views'):
+      users_by_id = {}
+      if request.include_admin_info:
+        users_involved = tracker_bizobj.UsersInvolvedInConfig(config)
+        users_by_id = framework_views.MakeAllUserViews(
+            mc.cnxn, self.services.user, users_involved)
+        framework_views.RevealAllEmailsToMembers(
+            mc.cnxn, self.services, mc.auth, users_by_id, project)
+
+    with mc.profiler.Phase('looking up labels'):
+      labels_by_id = {}
+      if request.include_admin_info:
+        label_ids = tracker_bizobj.LabelIDsInvolvedInConfig(config)
+        labels_by_id = {
+          label_id: self.services.config.LookupLabel(
+              mc.cnxn, config.project_id, label_id)
+          for label_id in label_ids}
+
+    component_defs = [
+        converters.ConvertComponentDef(
+            cd, users_by_id, labels_by_id, request.include_admin_info)
+        for cd in config.component_defs]
+
+    result = projects_pb2.ListComponentsResponse(
+        component_defs=component_defs)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def ListFields(self, mc, request):
+    """List all fields for the specified project."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      config = we.GetProjectConfig(project.project_id)
+
+    users_by_id = {}
+    users_for_perm = {}
+    # Only look for members if user choices are requested and there are user
+    # fields that need permissions.
+    if request.include_user_choices:
+      perms_needed = {
+          fd.needs_perm
+          for fd in config.field_defs
+          if fd.needs_perm and not fd.is_deleted}
+      if perms_needed:
+        users_by_id = tracker_helpers.GetVisibleMembers(
+            mc, project, self.services)
+        effective_ids_by_user = self.services.usergroup.LookupAllMemberships(
+            mc.cnxn, users_by_id)
+        users_for_perm = project_helpers.UsersWithPermsInProject(
+            project, perms_needed, users_by_id, effective_ids_by_user)
+
+    field_defs = [
+        converters.ConvertFieldDef(
+            fd, users_for_perm.get(fd.needs_perm, []), users_by_id, config,
+            request.include_admin_info)
+        for fd in config.field_defs
+        if not fd.is_deleted]
+
+    result = projects_pb2.ListFieldsResponse(field_defs=field_defs)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def GetProjectStarCount(self, mc, request):
+    """Get the star count for the specified project."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      star_count = we.GetProjectStarCount(project.project_id)
+
+    result = projects_pb2.GetProjectStarCountResponse(star_count=star_count)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def StarProject(self, mc, request):
+    """Star the specified project."""
+    project = self._GetProject(mc, request)
+
+    with work_env.WorkEnv(mc, self.services) as we:
+      we.StarProject(project.project_id, request.starred)
+      star_count = we.GetProjectStarCount(project.project_id)
+
+    result = projects_pb2.StarProjectResponse(star_count=star_count)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def CheckProjectName(self, mc, request):
+    """Check that a project name is valid and not already in use."""
+    with work_env.WorkEnv(mc, self.services) as we:
+      error = we.CheckProjectName(request.project_name)
+    result = projects_pb2.CheckProjectNameResponse(error=error)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def CheckComponentName(self, mc, request):
+    """Check that the component name is valid and not already in use."""
+    project = self._GetProject(mc, request)
+    with work_env.WorkEnv(mc, self.services) as we:
+      error = we.CheckComponentName(
+          project.project_id, request.parent_path, request.component_name)
+    result = projects_pb2.CheckComponentNameResponse(error=error)
+    return result
+
+  @monorail_servicer.PRPCMethod
+  def CheckFieldName(self, mc, request):
+    """Check that a field name is valid and not already in use."""
+    project = self._GetProject(mc, request)
+    with work_env.WorkEnv(mc, self.services) as we:
+      error = we.CheckFieldName(project.project_id, request.field_name)
+    result = projects_pb2.CheckFieldNameResponse(error=error)
+    return result
