diff --git a/Step_3.md b/Step_3.md
new file mode 100644
index 0000000000000000000000000000000000000000..56d6e7cfd3acaa8486cd7895acad33827676ee93
--- /dev/null
+++ b/Step_3.md
@@ -0,0 +1,82 @@
+# Step-3: Implement a server.
+
+This step extends the generated server skeleton code to write a simple server
+that provides the hello service.  This in introduces two new classes
+
+- a service implementation [GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java).
+
+- a server that hosts the service implementation and allows to accessed over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java).
+
+## Service implementation
+
+[GreetingsSImpl.java](src/main/java/ex/grpc/GreetingsImpl.java)
+implements the behaviour we require of our GreetingService.  There are a
+number of important features of gRPC being used here:
+
+```
+  public void hello(Helloworld.HelloRequest req,
+      StreamObserver<Helloworld.HelloReply> responseObserver) {
+    Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage(
+        "Hello " + req.getName()).build();
+    responseObserver.onValue(reply);
+    responseObserver.onCompleted();
+  }
+```
+
+- it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings`
+- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto)
+- `hello's` signature is typesafe:
+   hello(Helloworld.HelloRequest req, StreamObserver<Helloworld.HelloReply> responseObserver)
+- `hello` takes two parameters:
+  `Helloworld.HelloRequest`: the request
+  `StreamObserver<Helloworld.HelloReply>`: a response observer, an interface to be called with the response value
+- to complete the call
+  - the return value is constructed
+  - the responseObserver.onValue() is called with the response
+  - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC.
+
+
+## Server implementation
+
+[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the
+other main feature to required to provde gRPC service; how to allow a service
+implementation to be accessed from the network.
+
+```
+  private void start() throws Exception {
+    server = NettyServerBuilder.forPort(port)
+             .addService(GreetingsGrpc.bindService(new GreetingsImpl()))
+             .build();
+    server.startAsync();
+    server.awaitRunning(5, TimeUnit.SECONDS);
+  }
+
+```
+
+- it provides a class `GreetingsServer` that holds a `ServerImpl` that will run the server
+- in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it
+- there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits
+
+## Build it
+
+This is the same as before: our client and server are part of the same maven
+package so the same command builds both.
+
+```
+$ mvn package
+```
+
+## Try them out
+
+We've added simple shell scripts to simplifying running the examples.  Now
+that they are built, you can run the server with.
+
+```
+$ ./run_greetings_server.sh
+```
+
+In another termainal window and confirm that it receives a message.
+
+```
+$ ./run_greetings_client.sh
+```
diff --git a/src/main/java/ex/grpc/GreetingsImpl.java b/src/main/java/ex/grpc/GreetingsImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..005489acaa2057222452c28c1e18eac952ff0073
--- /dev/null
+++ b/src/main/java/ex/grpc/GreetingsImpl.java
@@ -0,0 +1,16 @@
+package ex.grpc;
+
+import com.google.net.stubby.stub.StreamObserver;
+
+public class GreetingsImpl implements GreetingsGrpc.Greetings {
+
+  @Override
+  public void hello(Helloworld.HelloRequest req,
+      StreamObserver<Helloworld.HelloReply> responseObserver) {
+    Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage(
+        "Hello " + req.getName()).build();
+    responseObserver.onValue(reply);
+    responseObserver.onCompleted();
+  }
+
+}
diff --git a/src/main/java/ex/grpc/GreetingsServer.java b/src/main/java/ex/grpc/GreetingsServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..834ae985a441f7154b4b8c1981ae2d93c9846615
--- /dev/null
+++ b/src/main/java/ex/grpc/GreetingsServer.java
@@ -0,0 +1,51 @@
+package ex.grpc;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.net.stubby.ServerImpl;
+import com.google.net.stubby.transport.netty.NettyServerBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Server that manages startup/shutdown of a {@code Greetings} server.
+ */
+public class GreetingsServer {
+  /* The port on which the server should run */
+  private int port = 50051;
+  private ServerImpl server;
+
+  private void start() throws Exception {
+    server = NettyServerBuilder.forPort(port)
+             .addService(GreetingsGrpc.bindService(new GreetingsImpl()))
+             .build();
+    server.startAsync();
+    server.awaitRunning(5, TimeUnit.SECONDS);
+    System.out.println("Server started on port:" + port);
+  }
+
+  private void stop() throws Exception {
+    server.stopAsync();
+    server.awaitTerminated();
+    System.out.println("Server shutting down ...");
+  }
+
+  /**
+   * Main launches the server from the command line.
+   */
+  public static void main(String[] args) throws Exception {
+    final GreetingsServer server = new GreetingsServer();
+
+    Runtime.getRuntime().addShutdownHook(new Thread() {
+      @Override
+      public void run() {
+        try {
+          System.out.println("Shutting down");
+          server.stop();
+        } catch (Exception e) {
+          e.printStackTrace();
+        }
+      }
+      });
+    server.start();
+  }
+}