diff --git a/src/ruby/Gemfile b/src/ruby/Gemfile
index dc05f7946b2caa9b9f8e43a9f005a55a3fe1f4df..597a7d4f4b04b5a8585852fc64eb77c1fa7ff8ef 100755
--- a/src/ruby/Gemfile
+++ b/src/ruby/Gemfile
@@ -1,12 +1,4 @@
 source 'https://rubygems.org'
 
-# Modify this when working locally, see README.md
-# e.g,
-# gem 'beefcake', path: "/usr/local/google/repos/beefcake"
-#
-# The default value is what's used for gRPC ruby's GCE configuration
-#
-gem 'beefcake', path: "/var/local/git/beefcake"
-
 # Specify your gem's dependencies in grpc.gemspec
 gemspec
diff --git a/src/ruby/README.md b/src/ruby/README.md
index 3a5c50819b200dbc43df97d57a4d461c7690b615..23aec2b20afe1f21dffa7060ebddd8de11fa415e 100755
--- a/src/ruby/README.md
+++ b/src/ruby/README.md
@@ -20,67 +20,25 @@ DEPENDENCIES
 The extension can be built and tested using
 [rake](https://rubygems.org/gems/rake).  However, the rake-extensiontask rule
 is not supported on older versions of rubygems, and the necessary version of
-rubygems is not available on the latest version of Goobuntu.
+rubygems.
 
 This is resolved by using [RVM](https://rvm.io/) instead; install a single-user
-ruby environment, and develop on the latest stable version of ruby (2.1.2).
-
-
-* Proto code generation
-
-To build generate service stubs and skeletons, it's currently necessary to use
-a patched version of a beefcake, a simple third-party proto2 library.  This is
-feature compatible with proto3 and will be replaced by official proto3 support
-in protoc.
-
-* Patched protoc
-
-The patched version of beefcake in turn depends on a patched version of protoc.
-This is an update of the latest open source release of protoc with some forward
-looking proto3 patches.
+ruby environment, and develop on the latest stable version of ruby (2.1.5).
 
 
 INSTALLATION PREREQUISITES
 --------------------------
 
-Install the patched protoc
-
-$ cd <git_repo_dir>
-$ git clone sso://team/one-platform-grpc-team/protobuf
-$ cd protobuf
-$ ./configure --prefix=/usr
-$ make
-$ sudo make install
-
-Install an update to OpenSSL with ALPN support
-
-$ wget https://www.openssl.org/source/openssl-1.0.2-beta3.tar.gz
-$ tar -zxvf openssl-1.0.2-beta3.tar.gz
-$ cd openssl-1.0.2-beta3
-$ ./config shared
-$ make
-$ sudo make install
-
 Install RVM
 
-$ # the -with-openssl-dir ensures that ruby uses the updated version of SSL
 $ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
 $ \curl -sSL https://get.rvm.io | bash -s stable --ruby
 $
 $ # follow the instructions to ensure that your're using the latest stable version of Ruby
 $ # and that the rvm command is installed
 $
-$ rvm reinstall 2.1.5 --with-openssl-dir=/usr/local/ssl
 $ gem install bundler  # install bundler, the standard ruby package manager
 
-Install the patched beefcake, and update the Gemfile to reference
-
-$ cd <git_repo_dir>
-$ git clone sso://team/one-platform-grpc-team/grpc-ruby-beefcake beefcake
-$ cd beefcake
-$ bundle install
-$
-
 HACKING
 -------
 
diff --git a/src/ruby/bin/interop/interop_client.rb b/src/ruby/bin/interop/interop_client.rb
index 6e7bfeef97663deabb36eb08d9557e36793b7d9d..d0478bb4d1cd4c2abfc7b8120d7d01ee2fe63bac 100644
--- a/src/ruby/bin/interop/interop_client.rb
+++ b/src/ruby/bin/interop/interop_client.rb
@@ -47,9 +47,11 @@ require 'minitest'
 require 'minitest/assertions'
 
 require 'grpc'
+require 'google/protobuf'
 
-require 'third_party/stubby/testing/proto/test.pb'
-require 'third_party/stubby/testing/proto/messages.pb'
+require 'test/cpp/interop/test_services'
+require 'test/cpp/interop/messages'
+require 'test/cpp/interop/empty'
 
 # loads the certificates used to access the test server securely.
 def load_test_certs
@@ -79,7 +81,7 @@ end
 # produces a string of null chars (\0) of length l.
 def nulls(l)
   raise 'requires #{l} to be +ve' if l < 0
-  [].pack('x' * l)
+  [].pack('x' * l).force_encoding('utf-8')
 end
 
 # a PingPongPlayer implements the ping pong bidi test.
@@ -105,10 +107,11 @@ class PingPongPlayer
       req_size, resp_size = m
       req = req_cls.new(:payload => Payload.new(:body => nulls(req_size)),
                         :response_type => COMPRESSABLE,
-                        :response_parameters => p_cls.new(:size => resp_size))
+                        :response_parameters => [p_cls.new(:size => resp_size)])
       yield req
       resp = @queue.pop
-      assert_equal(COMPRESSABLE, resp.payload.type, 'payload type is wrong')
+      assert_equal(PayloadType.lookup(COMPRESSABLE), resp.payload.type,
+                   'payload type is wrong')
       assert_equal(resp_size, resp.payload.body.length,
                    'payload body #{i} has the wrong length')
       p "OK: ping_pong #{count}"
@@ -132,10 +135,10 @@ class NamedTests
   # TESTING
   # PASSED
   # FAIL
-  #   ruby server: fails beefcake throws on deserializing the 0-length message
+  #   ruby server: fails protobuf-ruby can't pass an empty message
   def empty_unary
-    resp = @stub.empty_call(Proto2::Empty.new)
-    assert resp.is_a?(Proto::Empty), 'empty_unary: invalid response'
+    resp = @stub.empty_call(Empty.new)
+    assert resp.is_a?(Empty), 'empty_unary: invalid response'
     p 'OK: empty_unary'
   end
 
@@ -186,7 +189,8 @@ class NamedTests
     resps = @stub.streaming_output_call(req)
     resps.each_with_index do |r, i|
       assert i < msg_sizes.length, 'too many responses'
-      assert_equal(COMPRESSABLE, r.payload.type, 'payload type is wrong')
+      assert_equal(PayloadType.lookup(COMPRESSABLE), r.payload.type,
+                   'payload type is wrong')
       assert_equal(msg_sizes[i], r.payload.body.length,
                    'payload body #{i} has the wrong length')
     end
@@ -197,9 +201,6 @@ class NamedTests
   # PASSED
   #   ruby server
   # FAILED
-  #
-  # TODO(temiola): update this test to stay consistent with the java test's
-  # interpretation of the test spec.
   def ping_pong
     msg_sizes = [[27182, 31415], [8, 9], [1828, 2653], [45904, 58979]]
     ppp = PingPongPlayer.new(msg_sizes)
diff --git a/src/ruby/bin/interop/interop_server.rb b/src/ruby/bin/interop/interop_server.rb
index 35d69f6fd383e71d3350ddfb6978dfe41b595675..53e271e80d5cc01511d5a045c095e1dd8fca6794 100644
--- a/src/ruby/bin/interop/interop_server.rb
+++ b/src/ruby/bin/interop/interop_server.rb
@@ -47,8 +47,9 @@ require 'optparse'
 
 require 'grpc'
 
-require 'third_party/stubby/testing/proto/test.pb'
-require 'third_party/stubby/testing/proto/messages.pb'
+require 'test/cpp/interop/test_services'
+require 'test/cpp/interop/messages'
+require 'test/cpp/interop/empty'
 
 # loads the certificates by the test server.
 def load_test_certs
@@ -67,7 +68,7 @@ end
 # produces a string of null chars (\0) of length l.
 def nulls(l)
   raise 'requires #{l} to be +ve' if l < 0
-  [].pack('x' * l)
+  [].pack('x' * l).force_encoding('utf-8')
 end
 
 # A EnumeratorQueue wraps a Queue yielding the items added to it via each_item.
@@ -98,7 +99,7 @@ class TestTarget < Grpc::Testing::TestService::Service
   include Grpc::Testing::PayloadType
 
   def empty_call(empty, call)
-    Proto::Empty.new
+    Empty.new
   end
 
   def unary_call(simple_req, call)
diff --git a/src/ruby/bin/interop/net/proto2/bridge/proto/message_set.pb.rb b/src/ruby/bin/interop/net/proto2/bridge/proto/message_set.pb.rb
deleted file mode 100755
index eadd1d4ceb58b9cff98923188e4d6ec249172f69..0000000000000000000000000000000000000000
--- a/src/ruby/bin/interop/net/proto2/bridge/proto/message_set.pb.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-## Generated from net/proto2/bridge/proto/message_set.proto for proto2.bridge
-require 'beefcake'
-
-module Proto2
-  module Bridge
-
-    class MessageSet
-      include Beefcake::Message
-    end
-
-    class MessageSet
-    end
-  end
-end
diff --git a/src/ruby/bin/interop/net/proto2/proto/empty.pb.rb b/src/ruby/bin/interop/net/proto2/proto/empty.pb.rb
deleted file mode 100755
index 2aa0c765091cc144de0b44286e4a8c27a64cbaa2..0000000000000000000000000000000000000000
--- a/src/ruby/bin/interop/net/proto2/proto/empty.pb.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-## Generated from net/proto2/proto/empty.proto for proto2
-require 'beefcake'
-
-module Proto2
-
-  class Empty
-    include Beefcake::Message
-  end
-
-  class Empty
-  end
-end
diff --git a/src/ruby/bin/interop/test/cpp/interop/empty.rb b/src/ruby/bin/interop/test/cpp/interop/empty.rb
new file mode 100644
index 0000000000000000000000000000000000000000..acd4160d248509c87f22ba66fa59b1c2817a29c1
--- /dev/null
+++ b/src/ruby/bin/interop/test/cpp/interop/empty.rb
@@ -0,0 +1,44 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test/cpp/interop/empty.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.testing.Empty" do
+  end
+end
+
+module Grpc
+  module Testing
+    Empty = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Empty").msgclass
+  end
+end
diff --git a/src/ruby/bin/interop/test/cpp/interop/messages.rb b/src/ruby/bin/interop/test/cpp/interop/messages.rb
new file mode 100644
index 0000000000000000000000000000000000000000..491608bff263ca34cded356bf587460f33ba3b51
--- /dev/null
+++ b/src/ruby/bin/interop/test/cpp/interop/messages.rb
@@ -0,0 +1,86 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test/cpp/interop/messages.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.testing.Payload" do
+    optional :type, :enum, 1, "grpc.testing.PayloadType"
+    optional :body, :string, 2
+  end
+  add_message "grpc.testing.SimpleRequest" do
+    optional :response_type, :enum, 1, "grpc.testing.PayloadType"
+    optional :response_size, :int32, 2
+    optional :payload, :message, 3, "grpc.testing.Payload"
+  end
+  add_message "grpc.testing.SimpleResponse" do
+    optional :payload, :message, 1, "grpc.testing.Payload"
+    optional :effective_gaia_user_id, :int64, 2
+  end
+  add_message "grpc.testing.StreamingInputCallRequest" do
+    optional :payload, :message, 1, "grpc.testing.Payload"
+  end
+  add_message "grpc.testing.StreamingInputCallResponse" do
+    optional :aggregated_payload_size, :int32, 1
+  end
+  add_message "grpc.testing.ResponseParameters" do
+    optional :size, :int32, 1
+    optional :interval_us, :int32, 2
+  end
+  add_message "grpc.testing.StreamingOutputCallRequest" do
+    optional :response_type, :enum, 1, "grpc.testing.PayloadType"
+    repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters"
+    optional :payload, :message, 3, "grpc.testing.Payload"
+  end
+  add_message "grpc.testing.StreamingOutputCallResponse" do
+    optional :payload, :message, 1, "grpc.testing.Payload"
+  end
+  add_enum "grpc.testing.PayloadType" do
+    value :COMPRESSABLE, 0
+    value :UNCOMPRESSABLE, 1
+    value :RANDOM, 2
+  end
+end
+
+module Grpc
+  module Testing
+    Payload = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Payload").msgclass
+    SimpleRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleRequest").msgclass
+    SimpleResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleResponse").msgclass
+    StreamingInputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallRequest").msgclass
+    StreamingInputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallResponse").msgclass
+    ResponseParameters = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ResponseParameters").msgclass
+    StreamingOutputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallRequest").msgclass
+    StreamingOutputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallResponse").msgclass
+    PayloadType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
+  end
+end
diff --git a/src/ruby/bin/interop/test/cpp/interop/test.rb b/src/ruby/bin/interop/test/cpp/interop/test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0b391ed6af0ab4ba84ddac33bdbb397ff2e58061
--- /dev/null
+++ b/src/ruby/bin/interop/test/cpp/interop/test.rb
@@ -0,0 +1,43 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test/cpp/interop/test.proto
+
+require 'google/protobuf'
+
+require 'test/cpp/interop/empty'
+require 'test/cpp/interop/messages'
+Google::Protobuf::DescriptorPool.generated_pool.build do
+end
+
+module Grpc
+  module Testing
+  end
+end
diff --git a/src/ruby/bin/interop/test/cpp/interop/test_services.rb b/src/ruby/bin/interop/test/cpp/interop/test_services.rb
new file mode 100644
index 0000000000000000000000000000000000000000..464d5e24f65020a20931294c8e7efea8c708bc02
--- /dev/null
+++ b/src/ruby/bin/interop/test/cpp/interop/test_services.rb
@@ -0,0 +1,59 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: test/cpp/interop/test.proto for package 'grpc.testing'
+
+require 'grpc'
+require 'test/cpp/interop/test'
+
+module Grpc
+  module Testing
+    module TestService
+
+      # TODO: add proto service documentation here
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+
+        rpc :EmptyCall, Empty, Empty
+        rpc :UnaryCall, SimpleRequest, SimpleResponse
+        rpc :StreamingOutputCall, StreamingOutputCallRequest, stream(StreamingOutputCallResponse)
+        rpc :StreamingInputCall, stream(StreamingInputCallRequest), StreamingInputCallResponse
+        rpc :FullDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
+        rpc :HalfDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+  end
+end
diff --git a/src/ruby/bin/interop/third_party/stubby/testing/proto/messages.pb.rb b/src/ruby/bin/interop/third_party/stubby/testing/proto/messages.pb.rb
deleted file mode 100755
index 9a913f93e58161104241bf39d44fb1fc58fc337f..0000000000000000000000000000000000000000
--- a/src/ruby/bin/interop/third_party/stubby/testing/proto/messages.pb.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-## Generated from third_party/stubby/testing/proto/messages.proto for grpc.testing
-require 'beefcake'
-
-require 'net/proto2/bridge/proto/message_set.pb'
-
-module Grpc
-  module Testing
-
-    module PayloadType
-      COMPRESSABLE = 0
-      UNCOMPRESSABLE = 1
-      RANDOM = 2
-    end
-
-    class Payload
-      include Beefcake::Message
-    end
-
-    class SimpleRequest
-      include Beefcake::Message
-    end
-
-    class SimpleResponse
-      include Beefcake::Message
-    end
-
-    class SimpleContext
-      include Beefcake::Message
-    end
-
-    class StreamingInputCallRequest
-      include Beefcake::Message
-    end
-
-    class StreamingInputCallResponse
-      include Beefcake::Message
-    end
-
-    class ResponseParameters
-      include Beefcake::Message
-    end
-
-    class StreamingOutputCallRequest
-      include Beefcake::Message
-    end
-
-    class StreamingOutputCallResponse
-      include Beefcake::Message
-    end
-
-    class Payload
-      optional :type, PayloadType, 1
-      optional :body, :bytes, 2
-    end
-
-    class SimpleRequest
-      optional :response_type, PayloadType, 1
-      optional :response_size, :int32, 2
-      optional :payload, Payload, 3
-    end
-
-    class SimpleResponse
-      optional :payload, Payload, 1
-      optional :effective_gaia_user_id, :int64, 2
-    end
-
-    class SimpleContext
-      optional :value, :string, 1
-    end
-
-    class StreamingInputCallRequest
-      optional :payload, Payload, 1
-    end
-
-    class StreamingInputCallResponse
-      optional :aggregated_payload_size, :int32, 1
-    end
-
-    class ResponseParameters
-      optional :size, :int32, 1
-      optional :interval_us, :int32, 2
-    end
-
-    class StreamingOutputCallRequest
-      optional :response_type, PayloadType, 1
-      repeated :response_parameters, ResponseParameters, 2
-      optional :payload, Payload, 3
-    end
-
-    class StreamingOutputCallResponse
-      optional :payload, Payload, 1
-    end
-  end
-end
diff --git a/src/ruby/bin/interop/third_party/stubby/testing/proto/test.pb.rb b/src/ruby/bin/interop/third_party/stubby/testing/proto/test.pb.rb
deleted file mode 100755
index 2e21460fe656201e135e47d3061d7315717be596..0000000000000000000000000000000000000000
--- a/src/ruby/bin/interop/third_party/stubby/testing/proto/test.pb.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-## Generated from third_party/stubby/testing/proto/test.proto for grpc.testing
-require 'beefcake'
-require 'grpc'
-
-require 'third_party/stubby/testing/proto/messages.pb'
-require 'net/proto2/proto/empty.pb'
-
-module Grpc
-  module Testing
-
-    module TestService
-
-      class Service
-        include GRPC::GenericService
-
-        self.marshal_class_method = :encode
-        self.unmarshal_class_method = :decode
-
-        rpc :EmptyCall, Proto2::Empty, Proto2::Empty
-        rpc :UnaryCall, SimpleRequest, SimpleResponse
-        rpc :StreamingOutputCall, StreamingOutputCallRequest, stream(StreamingOutputCallResponse)
-        rpc :StreamingInputCall, stream(StreamingInputCallRequest), StreamingInputCallResponse
-        rpc :FullDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
-        rpc :HalfDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
-      end
-      Stub = Service.rpc_stub_class
-
-    end
-  end
-end
diff --git a/src/ruby/bin/math.pb.rb b/src/ruby/bin/math.pb.rb
deleted file mode 100755
index f6976be568419d0079656f46d08519e0de9b59eb..0000000000000000000000000000000000000000
--- a/src/ruby/bin/math.pb.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-## Generated from bin/math.proto for math
-require "beefcake"
-require "grpc"
-
-module Math
-
-  class DivArgs
-    include Beefcake::Message
-  end
-
-  class DivReply
-    include Beefcake::Message
-  end
-
-  class FibArgs
-    include Beefcake::Message
-  end
-
-  class Num
-    include Beefcake::Message
-  end
-
-  class FibReply
-    include Beefcake::Message
-  end
-
-  class DivArgs
-    required :dividend, :int64, 1
-    required :divisor, :int64, 2
-  end
-
-  class DivReply
-    required :quotient, :int64, 1
-    required :remainder, :int64, 2
-  end
-
-  class FibArgs
-    optional :limit, :int64, 1
-  end
-
-  class Num
-    required :num, :int64, 1
-  end
-
-  class FibReply
-    required :count, :int64, 1
-  end
-
-  module Math
-
-    class Service
-      include GRPC::GenericService
-
-      self.marshal_class_method = :encode
-      self.unmarshal_class_method = :decode
-
-      rpc :Div, DivArgs, DivReply
-      rpc :DivMany, stream(DivArgs), stream(DivReply)
-      rpc :Fib, FibArgs, stream(Num)
-      rpc :Sum, stream(Num), Num
-    end
-    Stub = Service.rpc_stub_class
-
-  end
-end
diff --git a/src/ruby/bin/math.proto b/src/ruby/bin/math.proto
index de18a5026024d29ae45ea58b0562826e6092294d..c49787ad54d046b6fcaf600a6072039f601ad723 100755
--- a/src/ruby/bin/math.proto
+++ b/src/ruby/bin/math.proto
@@ -1,15 +1,15 @@
-syntax = "proto2";
+syntax = "proto3";
 
 package math;
 
 message DivArgs {
-  required int64 dividend = 1;
-  required int64 divisor = 2;
+  optional int64 dividend = 1;
+  optional int64 divisor = 2;
 }
 
 message DivReply {
-  required int64 quotient = 1;
-  required int64 remainder = 2;
+  optional int64 quotient = 1;
+  optional int64 remainder = 2;
 }
 
 message FibArgs {
@@ -17,11 +17,11 @@ message FibArgs {
 }
 
 message Num {
-  required int64 num = 1;
+  optional int64 num = 1;
 }
 
 message FibReply {
-  required int64 count = 1;
+  optional int64 count = 1;
 }
 
 service Math {
diff --git a/src/ruby/bin/math.rb b/src/ruby/bin/math.rb
new file mode 100644
index 0000000000000000000000000000000000000000..09d1e9858640e4ca8c9ca4daee61d69c8cb25c20
--- /dev/null
+++ b/src/ruby/bin/math.rb
@@ -0,0 +1,61 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: math.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "math.DivArgs" do
+    optional :dividend, :int64, 1
+    optional :divisor, :int64, 2
+  end
+  add_message "math.DivReply" do
+    optional :quotient, :int64, 1
+    optional :remainder, :int64, 2
+  end
+  add_message "math.FibArgs" do
+    optional :limit, :int64, 1
+  end
+  add_message "math.Num" do
+    optional :num, :int64, 1
+  end
+  add_message "math.FibReply" do
+    optional :count, :int64, 1
+  end
+end
+
+module Math
+  DivArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("math.DivArgs").msgclass
+  DivReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("math.DivReply").msgclass
+  FibArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("math.FibArgs").msgclass
+  Num = Google::Protobuf::DescriptorPool.generated_pool.lookup("math.Num").msgclass
+  FibReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("math.FibReply").msgclass
+end
diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb
index 8a62764c084bc34fb5b268e68f2638abe792cf1c..5cba9317f4f5efefb01db97488b0b74b00626584 100644
--- a/src/ruby/bin/math_client.rb
+++ b/src/ruby/bin/math_client.rb
@@ -40,7 +40,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
 $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
 
 require 'grpc'
-require 'math.pb'
+require 'math_services'
 require 'optparse'
 
 include GRPC::Core::TimeConsts
@@ -111,8 +111,8 @@ def main
     'secure' => false
   }
   OptionParser.new do |opts|
-    opts.banner = 'Usage: [--host|-h <hostname>:<port>] [--secure|-s]'
-    opts.on('-h', '--host', '<hostname>:<port>') do |v|
+    opts.banner = 'Usage: [--host <hostname>:<port>] [--secure|-s]'
+    opts.on('--host HOST', '<hostname>:<port>') do |v|
       options['host'] = v
     end
     opts.on('-s', '--secure', 'access using test creds') do |v|
diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb
index ed39144d7aa16b7eaa45a43234caf1ebdad3b5aa..a0f301c3e79d1138ca943671b7edc20fd6cc4098 100644
--- a/src/ruby/bin/math_server.rb
+++ b/src/ruby/bin/math_server.rb
@@ -41,7 +41,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
 
 require 'forwardable'
 require 'grpc'
-require 'math.pb'
+require 'math_services'
 require 'optparse'
 
 # Holds state for a fibonacci series
@@ -168,8 +168,8 @@ def main
     'secure' => false
   }
   OptionParser.new do |opts|
-    opts.banner = 'Usage: [--host|-h <hostname>:<port>] [--secure|-s]'
-    opts.on('-h', '--host', '<hostname>:<port>') do |v|
+    opts.banner = 'Usage: [--host <hostname>:<port>] [--secure|-s]'
+    opts.on('--host HOST', '<hostname>:<port>') do |v|
       options['host'] = v
     end
     opts.on('-s', '--secure', 'access using test creds') do |v|
diff --git a/src/ruby/bin/math_services.rb b/src/ruby/bin/math_services.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7e056025cfa29d2ff73c03bea675d0e784b25d3e
--- /dev/null
+++ b/src/ruby/bin/math_services.rb
@@ -0,0 +1,55 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: math.proto for package 'math'
+
+require 'grpc'
+require 'math'
+
+module Math
+  module Math
+
+    # TODO: add proto service documentation here
+    class Service
+
+      include GRPC::GenericService
+
+      self.marshal_class_method = :encode
+      self.unmarshal_class_method = :decode
+
+      rpc :Div, DivArgs, DivReply
+      rpc :DivMany, stream(DivArgs), stream(DivReply)
+      rpc :Fib, FibArgs, stream(Num)
+      rpc :Sum, stream(Num), Num
+    end
+
+    Stub = Service.rpc_stub_class
+  end
+end
diff --git a/src/ruby/bin/noproto_client.rb b/src/ruby/bin/noproto_client.rb
index 29ed6d9f7cca6c3f09ec811590a27f64070c8d8f..50ae9fb68f899c55eb6618cdfb47eac35ff42e0f 100644
--- a/src/ruby/bin/noproto_client.rb
+++ b/src/ruby/bin/noproto_client.rb
@@ -37,36 +37,68 @@ lib_dir = File.join(File.dirname(this_dir), 'lib')
 $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
 
 require 'grpc'
+require 'optparse'
 
-class EchoMsg
-  def marshal
+class NoProtoMsg
+  def self.marshal(o)
     ''
   end
 
   def self.unmarshal(o)
-    EchoMsg.new
+    NoProtoMsg.new
   end
 end
 
-class EchoService
+class NoProtoService
   include GRPC::GenericService
-  rpc :AnRPC, EchoMsg, EchoMsg
+  rpc :AnRPC, NoProtoMsg, NoProtoMsg
+end
 
-  def initialize(default_var='ignored')
-  end
+NoProtoStub = NoProtoService.rpc_stub_class
 
-  def an_rpc(req, call)
-    logger.info('echo service received a request')
-    req
-  end
+def load_test_certs
+  this_dir = File.expand_path(File.dirname(__FILE__))
+  data_dir = File.join(File.dirname(this_dir), 'spec/testdata')
+  files = ['ca.pem', 'server1.key', 'server1.pem']
+  files.map { |f| File.open(File.join(data_dir, f)).read }
 end
 
-EchoStub = EchoService.rpc_stub_class
+def test_creds
+  certs = load_test_certs
+  creds = GRPC::Core::Credentials.new(certs[0])
+end
 
 def main
-  stub = EchoStub.new('localhost:9090')
-  logger.info('sending an rpc')
-  resp = stub.an_rpc(EchoMsg.new)
+  options = {
+    'host' => 'localhost:7071',
+    'secure' => false
+  }
+  OptionParser.new do |opts|
+    opts.banner = 'Usage: [--host <hostname>:<port>] [--secure|-s]'
+    opts.on('--host HOST', '<hostname>:<port>') do |v|
+      options['host'] = v
+    end
+    opts.on('-s', '--secure', 'access using test creds') do |v|
+      options['secure'] = true
+    end
+  end.parse!
+
+  if options['secure']
+    stub_opts = {
+      :creds => test_creds,
+      GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com',
+    }
+    p stub_opts
+    p options['host']
+    stub = NoProtoStub.new(options['host'], **stub_opts)
+    logger.info("... connecting securely on #{options['host']}")
+  else
+    stub = NoProtoStub.new(options['host'])
+    logger.info("... connecting insecurely on #{options['host']}")
+  end
+
+  logger.info('sending a NoProto rpc')
+  resp = stub.an_rpc(NoProtoMsg.new)
   logger.info("got a response: #{resp}")
 end
 
diff --git a/src/ruby/bin/noproto_server.rb b/src/ruby/bin/noproto_server.rb
index 7b74fa13ec26f7eea299a53d4c592dd94ed679f8..d410827b22ddc7859dfd5c7f584d2fdf06cfdc70 100644
--- a/src/ruby/bin/noproto_server.rb
+++ b/src/ruby/bin/noproto_server.rb
@@ -37,23 +37,24 @@ lib_dir = File.join(File.dirname(this_dir), 'lib')
 $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
 
 require 'grpc'
+require 'optparse'
 
-class EchoMsg
-  def marshal
+class NoProtoMsg
+  def self.marshal(o)
     ''
   end
 
   def self.unmarshal(o)
-    EchoMsg.new
+    NoProtoMsg.new
   end
 end
 
-class EchoService
+class NoProtoService
   include GRPC::GenericService
-  rpc :AnRPC, EchoMsg, EchoMsg
+  rpc :AnRPC, NoProtoMsg, NoProtoMsg
 end
 
-class Echo < EchoService
+class NoProto < NoProtoService
   def initialize(default_var='ignored')
   end
 
@@ -63,11 +64,46 @@ class Echo < EchoService
   end
 end
 
+def load_test_certs
+  this_dir = File.expand_path(File.dirname(__FILE__))
+  data_dir = File.join(File.dirname(this_dir), 'spec/testdata')
+  files = ['ca.pem', 'server1.key', 'server1.pem']
+  files.map { |f| File.open(File.join(data_dir, f)).read }
+end
+
+def test_server_creds
+  certs = load_test_certs
+  server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
+end
+
 def main
-  s = GRPC::RpcServer.new()
-  s.add_http2_port('localhost:9090')
-  s.handle(Echo)
+  options = {
+    'host' => 'localhost:9090',
+    'secure' => false
+  }
+  OptionParser.new do |opts|
+    opts.banner = 'Usage: [--host <hostname>:<port>] [--secure|-s]'
+    opts.on('--host HOST', '<hostname>:<port>') do |v|
+      options['host'] = v
+    end
+    opts.on('-s', '--secure', 'access using test creds') do |v|
+      options['secure'] = true
+    end
+  end.parse!
+
+  if options['secure']
+    s = GRPC::RpcServer.new(creds: test_server_creds)
+    s.add_http2_port(options['host'], true)
+    logger.info("... running securely on #{options['host']}")
+  else
+    s = GRPC::RpcServer.new
+    s.add_http2_port(options['host'])
+    logger.info("... running insecurely on #{options['host']}")
+  end
+
+  s.handle(NoProto)
   s.run
 end
 
+
 main
diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec
index b535de49467948fc6f2cc77f8d70498e58b95a21..3e1dcd578b641daf08e164e435248757e21e7263 100755
--- a/src/ruby/grpc.gemspec
+++ b/src/ruby/grpc.gemspec
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
 
   s.add_dependency 'xray'
   s.add_dependency 'logging', '~> 1.8'
-  s.add_dependency 'beefcake', '~> 1.1'
+  s.add_dependency 'google-protobuf', '~> 3.0.0alpha'
   s.add_dependency 'minitest', '~> 5.4'  # not a dev dependency, used by the interop tests
 
   s.add_development_dependency "bundler", "~> 1.7"
diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb
index c7eec3388c8b62cd8beec03c66b17bc28961734a..81c67ec8592c7e664dee23bced427bace59c86a2 100644
--- a/src/ruby/lib/grpc.rb
+++ b/src/ruby/lib/grpc.rb
@@ -27,7 +27,6 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-require 'grpc/beefcake'  # extends beefcake
 require 'grpc/errors'
 require 'grpc/grpc'
 require 'grpc/logconfig'