diff --git a/server/api.go b/server/api.go
new file mode 100644
index 0000000000000000000000000000000000000000..41fec0207149a72ba6a700cb50b493ba5620c821
--- /dev/null
+++ b/server/api.go
@@ -0,0 +1,64 @@
+package server
+
+import (
+	"errors"
+	"log"
+
+	"golang.org/x/net/context"
+
+	"github.com/coreos/dex/api"
+	"github.com/coreos/dex/storage"
+)
+
+// NewAPI returns a server which implements the gRPC API interface.
+func NewAPI(s storage.Storage) api.DexServer {
+	return dexAPI{s: s}
+}
+
+type dexAPI struct {
+	s storage.Storage
+}
+
+func (d dexAPI) CreateClient(ctx context.Context, req *api.CreateClientReq) (*api.CreateClientResp, error) {
+	if req.Client == nil {
+		return nil, errors.New("no client supplied")
+	}
+
+	if req.Client.Id == "" {
+		req.Client.Id = storage.NewID()
+	}
+	if req.Client.Secret == "" {
+		req.Client.Secret = storage.NewID() + storage.NewID()
+	}
+
+	c := storage.Client{
+		ID:           req.Client.Id,
+		Secret:       req.Client.Secret,
+		RedirectURIs: req.Client.RedirectUris,
+		TrustedPeers: req.Client.TrustedPeers,
+		Public:       req.Client.Public,
+		Name:         req.Client.Name,
+		LogoURL:      req.Client.LogoUrl,
+	}
+	if err := d.s.CreateClient(c); err != nil {
+		log.Printf("api: failed to create client: %v", err)
+		// TODO(ericchiang): Surface "already exists" errors.
+		return nil, err
+	}
+
+	return &api.CreateClientResp{
+		Client: req.Client,
+	}, nil
+}
+
+func (d dexAPI) DeleteClient(ctx context.Context, req *api.DeleteClientReq) (*api.DeleteClientResp, error) {
+	err := d.s.DeleteClient(req.Id)
+	if err != nil {
+		if err == storage.ErrNotFound {
+			return &api.DeleteClientResp{NotFound: true}, nil
+		}
+		log.Printf("api: failed to delete client: %v", err)
+		return nil, err
+	}
+	return &api.DeleteClientResp{}, nil
+}
diff --git a/server/api_test.go b/server/api_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..abb4e431abd516750a5a1e5e2b77073c236b8f9e
--- /dev/null
+++ b/server/api_test.go
@@ -0,0 +1 @@
+package server
diff --git a/server/server.go b/server/server.go
index 2e3c00af3eee2d94121eaf1c701c83af24029549..c3ede5d90bf085bed7397236acec13a37041403e 100644
--- a/server/server.go
+++ b/server/server.go
@@ -78,8 +78,8 @@ type Server struct {
 	idTokensValidFor time.Duration
 }
 
-// New constructs a server from the provided config.
-func New(c Config) (*Server, error) {
+// NewServer constructs a server from the provided config.
+func NewServer(c Config) (*Server, error) {
 	return newServer(c, defaultRotationStrategy(
 		value(c.RotateKeysAfter, 6*time.Hour),
 		value(c.IDTokensValidFor, 24*time.Hour),