diff --git a/services/wsprd/app/app.go b/services/wsprd/app/app.go
index 32231b8..2e959e0 100644
--- a/services/wsprd/app/app.go
+++ b/services/wsprd/app/app.go
@@ -103,6 +103,11 @@
 
 	// Store for all the Blessings that javascript has a handle to.
 	blessingsStore *principal.JSBlessingsHandles
+
+	// reservedServices contains a map of reserved service names.  These
+	// are objects that serve requests in wspr without actually making
+	// an outgoing rpc call.
+	reservedServices map[string]ipc.Invoker
 }
 
 // NewController creates a new Controller.  writerCreator will be used to create a new flow for rpcs to
@@ -129,6 +134,19 @@
 		blessingsStore: principal.NewJSBlessingsHandles(),
 	}
 
+	controllerInvoker, err := ipc.ReflectInvoker(ControllerServer(controller))
+	if err != nil {
+		return nil, err
+	}
+	namespaceInvoker, err := ipc.ReflectInvoker(namespace.New(ctx))
+	if err != nil {
+		return nil, err
+	}
+	controller.reservedServices = map[string]ipc.Invoker{
+		"__controller": controllerInvoker,
+		"__namespace":  namespaceInvoker,
+	}
+
 	controller.setup()
 	return controller, nil
 }
@@ -347,9 +365,23 @@
 	ctx  *context.T
 	vrpc *VeyronRPCRequest
 	tags []*vdl.Value
+	w    lib.ClientWriter
 }
 
-func (l *localCall) Send(interface{}) error                          { return nil }
+func (l *localCall) Send(item interface{}) error {
+	vomItem, err := lib.VomEncode(item)
+	if err != nil {
+		err = verror.New(marshallingError, l.ctx, item, err)
+		l.w.Error(err)
+		return err
+	}
+	if err := l.w.Send(lib.ResponseStream, vomItem); err != nil {
+		err = verror.New(marshallingError, l.ctx, item)
+		l.w.Error(err)
+		return err
+	}
+	return nil
+}
 func (l *localCall) Recv(interface{}) error                          { return nil }
 func (l *localCall) Blessings() security.Blessings                   { return nil }
 func (l *localCall) Server() ipc.Server                              { return nil }
@@ -366,12 +398,7 @@
 func (l *localCall) LocalEndpoint() naming.Endpoint                  { return nil }
 func (l *localCall) RemoteEndpoint() naming.Endpoint                 { return nil }
 
-func (c *Controller) handleInternalCall(ctx *context.T, msg *VeyronRPCRequest, decoder *vom.Decoder, w lib.ClientWriter, span vtrace.Span) {
-	invoker, err := ipc.ReflectInvoker(ControllerServer(c))
-	if err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
+func (c *Controller) handleInternalCall(ctx *context.T, invoker ipc.Invoker, msg *VeyronRPCRequest, decoder *vom.Decoder, w lib.ClientWriter, span vtrace.Span) {
 	argptrs, tags, err := invoker.Prepare(msg.Method, int(msg.NumInArgs))
 	if err != nil {
 		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
@@ -383,11 +410,17 @@
 			return
 		}
 	}
-	results, err := invoker.Invoke(msg.Method, &localCall{ctx, msg, tags}, argptrs)
+	results, err := invoker.Invoke(msg.Method, &localCall{ctx, msg, tags, w}, argptrs)
 	if err != nil {
 		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
 		return
 	}
+	if msg.IsStreaming {
+		if err := w.Send(lib.ResponseStreamClose, nil); err != nil {
+			w.Error(verror.New(marshallingError, ctx, "ResponseStreamClose"))
+		}
+	}
+
 	// Convert results from []interface{} to []*vdl.Value.
 	vresults := make([]*vdl.Value, len(results))
 	for i, res := range results {
@@ -436,8 +469,8 @@
 	}
 
 	// If this message is for an internal service, do a short-circuit dispatch here.
-	if msg.Name == "controller" {
-		go c.handleInternalCall(ctx, &msg, decoder, w, span)
+	if invoker, ok := c.reservedServices[msg.Name]; ok {
+		go c.handleInternalCall(ctx, invoker, &msg, decoder, w, span)
 		return
 	}
 
@@ -701,8 +734,3 @@
 	blessings, _ := call.RemoteBlessings()
 	return blessings, nil
 }
-
-// HandleNamespaceRequest uses the namespace client to respond to namespace specific requests such as glob
-func (c *Controller) HandleNamespaceRequest(ctx *context.T, data string, w lib.ClientWriter) {
-	namespace.HandleRequest(ctx, data, w)
-}
diff --git a/services/wsprd/app/app_test.go b/services/wsprd/app/app_test.go
index 7a334ce..7fd7106 100644
--- a/services/wsprd/app/app_test.go
+++ b/services/wsprd/app/app_test.go
@@ -363,7 +363,7 @@
 	veyron2.GetNamespace(controller.Context()).SetRoots("/" + endpoint.String())
 
 	req, err := makeRequest(VeyronRPCRequest{
-		Name:       "controller",
+		Name:       "__controller",
 		Method:     "Serve",
 		NumInArgs:  2,
 		NumOutArgs: 1,
diff --git a/services/wsprd/app/messaging.go b/services/wsprd/app/messaging.go
index a737889..7865870 100644
--- a/services/wsprd/app/messaging.go
+++ b/services/wsprd/app/messaging.go
@@ -116,9 +116,6 @@
 	case AuthResponseMessage:
 		go c.HandleAuthResponse(msg.Id, msg.Data)
 
-	case NamespaceRequestMessage:
-		go c.HandleNamespaceRequest(ctx, msg.Data, w)
-
 	default:
 		w.Error(verror.New(errUnknownMessageType, ctx, msg.Type))
 	}
diff --git a/services/wsprd/namespace/namespace.vdl b/services/wsprd/namespace/namespace.vdl
new file mode 100644
index 0000000..d8ce654
--- /dev/null
+++ b/services/wsprd/namespace/namespace.vdl
@@ -0,0 +1,33 @@
+// Package namespace defines an RPC services that allows remoting of the
+// namespace client library over the wire.  This is useful for
+// javascript so it doesn't have to implement the library.
+// This should be kept in sync with the namespace library (v.io/core/veyron2/naming).
+package namespace
+
+import (
+	"time"
+
+	"v.io/core/veyron2/naming"
+)
+
+type Namespace interface {
+	// Run a glob query and stream the results.
+	Glob(pattern string) stream<_, naming.VDLGlobReply> error
+	// Mount mounts a server under the given name.
+	Mount(name, server string, ttl time.Duration, replace bool) error
+	// Unmount removes an existing mount point.
+	Unmount(name, server string) error
+	// Resolve resolves a name to an address.
+	Resolve(name string) ([]string | error)
+	// ResolveToMt resolves a name to the address of the mounttable directly
+	// hosting it.
+	ResolveToMT(name string) ([]string | error)
+	// FlushCacheEntry removes the namespace cache entry for a given name.
+	FlushCacheEntry(name string) (bool | error)
+	// DisableCache disables the naming cache.
+	DisableCache(disable bool) error
+	// Roots returns the addresses of the current mounttable roots.
+	Roots() ([]string | error)
+	// SetRoots sets the current mounttable roots.
+	SetRoots(roots []string) error
+}
diff --git a/services/wsprd/namespace/namespace.vdl.go b/services/wsprd/namespace/namespace.vdl.go
new file mode 100644
index 0000000..4cbe8c9
--- /dev/null
+++ b/services/wsprd/namespace/namespace.vdl.go
@@ -0,0 +1,476 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: namespace.vdl
+
+// Package namespace defines an RPC services that allows remoting of the
+// namespace client library over the wire.  This is useful for
+// javascript so it doesn't have to implement the library.
+// This should be kept in sync with the namespace library (v.io/core/veyron2/naming).
+package namespace
+
+import (
+	// VDL system imports
+	"io"
+	"v.io/core/veyron2"
+	"v.io/core/veyron2/context"
+	"v.io/core/veyron2/ipc"
+
+	// VDL user imports
+	"time"
+	"v.io/core/veyron2/naming"
+	_ "v.io/core/veyron2/vdl/vdlroot/src/time"
+)
+
+// NamespaceClientMethods is the client interface
+// containing Namespace methods.
+type NamespaceClientMethods interface {
+	// Run a glob query and stream the results.
+	Glob(ctx *context.T, pattern string, opts ...ipc.CallOpt) (NamespaceGlobCall, error)
+	// Mount mounts a server under the given name.
+	Mount(ctx *context.T, name string, server string, ttl time.Duration, replace bool, opts ...ipc.CallOpt) error
+	// Unmount removes an existing mount point.
+	Unmount(ctx *context.T, name string, server string, opts ...ipc.CallOpt) error
+	// Resolve resolves a name to an address.
+	Resolve(ctx *context.T, name string, opts ...ipc.CallOpt) ([]string, error)
+	// ResolveToMt resolves a name to the address of the mounttable directly
+	// hosting it.
+	ResolveToMT(ctx *context.T, name string, opts ...ipc.CallOpt) ([]string, error)
+	// FlushCacheEntry removes the namespace cache entry for a given name.
+	FlushCacheEntry(ctx *context.T, name string, opts ...ipc.CallOpt) (bool, error)
+	// DisableCache disables the naming cache.
+	DisableCache(ctx *context.T, disable bool, opts ...ipc.CallOpt) error
+	// Roots returns the addresses of the current mounttable roots.
+	Roots(*context.T, ...ipc.CallOpt) ([]string, error)
+	// SetRoots sets the current mounttable roots.
+	SetRoots(ctx *context.T, roots []string, opts ...ipc.CallOpt) error
+}
+
+// NamespaceClientStub adds universal methods to NamespaceClientMethods.
+type NamespaceClientStub interface {
+	NamespaceClientMethods
+	ipc.UniversalServiceMethods
+}
+
+// NamespaceClient returns a client stub for Namespace.
+func NamespaceClient(name string, opts ...ipc.BindOpt) NamespaceClientStub {
+	var client ipc.Client
+	for _, opt := range opts {
+		if clientOpt, ok := opt.(ipc.Client); ok {
+			client = clientOpt
+		}
+	}
+	return implNamespaceClientStub{name, client}
+}
+
+type implNamespaceClientStub struct {
+	name   string
+	client ipc.Client
+}
+
+func (c implNamespaceClientStub) c(ctx *context.T) ipc.Client {
+	if c.client != nil {
+		return c.client
+	}
+	return veyron2.GetClient(ctx)
+}
+
+func (c implNamespaceClientStub) Glob(ctx *context.T, i0 string, opts ...ipc.CallOpt) (ocall NamespaceGlobCall, err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "Glob", []interface{}{i0}, opts...); err != nil {
+		return
+	}
+	ocall = &implNamespaceGlobCall{Call: call}
+	return
+}
+
+func (c implNamespaceClientStub) Mount(ctx *context.T, i0 string, i1 string, i2 time.Duration, i3 bool, opts ...ipc.CallOpt) (err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "Mount", []interface{}{i0, i1, i2, i3}, opts...); err != nil {
+		return
+	}
+	err = call.Finish()
+	return
+}
+
+func (c implNamespaceClientStub) Unmount(ctx *context.T, i0 string, i1 string, opts ...ipc.CallOpt) (err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "Unmount", []interface{}{i0, i1}, opts...); err != nil {
+		return
+	}
+	err = call.Finish()
+	return
+}
+
+func (c implNamespaceClientStub) Resolve(ctx *context.T, i0 string, opts ...ipc.CallOpt) (o0 []string, err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "Resolve", []interface{}{i0}, opts...); err != nil {
+		return
+	}
+	err = call.Finish(&o0)
+	return
+}
+
+func (c implNamespaceClientStub) ResolveToMT(ctx *context.T, i0 string, opts ...ipc.CallOpt) (o0 []string, err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "ResolveToMT", []interface{}{i0}, opts...); err != nil {
+		return
+	}
+	err = call.Finish(&o0)
+	return
+}
+
+func (c implNamespaceClientStub) FlushCacheEntry(ctx *context.T, i0 string, opts ...ipc.CallOpt) (o0 bool, err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "FlushCacheEntry", []interface{}{i0}, opts...); err != nil {
+		return
+	}
+	err = call.Finish(&o0)
+	return
+}
+
+func (c implNamespaceClientStub) DisableCache(ctx *context.T, i0 bool, opts ...ipc.CallOpt) (err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "DisableCache", []interface{}{i0}, opts...); err != nil {
+		return
+	}
+	err = call.Finish()
+	return
+}
+
+func (c implNamespaceClientStub) Roots(ctx *context.T, opts ...ipc.CallOpt) (o0 []string, err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "Roots", nil, opts...); err != nil {
+		return
+	}
+	err = call.Finish(&o0)
+	return
+}
+
+func (c implNamespaceClientStub) SetRoots(ctx *context.T, i0 []string, opts ...ipc.CallOpt) (err error) {
+	var call ipc.Call
+	if call, err = c.c(ctx).StartCall(ctx, c.name, "SetRoots", []interface{}{i0}, opts...); err != nil {
+		return
+	}
+	err = call.Finish()
+	return
+}
+
+// NamespaceGlobClientStream is the client stream for Namespace.Glob.
+type NamespaceGlobClientStream interface {
+	// RecvStream returns the receiver side of the Namespace.Glob client stream.
+	RecvStream() interface {
+		// Advance stages an item so that it may be retrieved via Value.  Returns
+		// true iff there is an item to retrieve.  Advance must be called before
+		// Value is called.  May block if an item is not available.
+		Advance() bool
+		// Value returns the item that was staged by Advance.  May panic if Advance
+		// returned false or was not called.  Never blocks.
+		Value() naming.VDLGlobReply
+		// Err returns any error encountered by Advance.  Never blocks.
+		Err() error
+	}
+}
+
+// NamespaceGlobCall represents the call returned from Namespace.Glob.
+type NamespaceGlobCall interface {
+	NamespaceGlobClientStream
+	// Finish blocks until the server is done, and returns the positional return
+	// values for call.
+	//
+	// Finish returns immediately if the call has been canceled; depending on the
+	// timing the output could either be an error signaling cancelation, or the
+	// valid positional return values from the server.
+	//
+	// Calling Finish is mandatory for releasing stream resources, unless the call
+	// has been canceled or any of the other methods return an error.  Finish should
+	// be called at most once.
+	Finish() error
+}
+
+type implNamespaceGlobCall struct {
+	ipc.Call
+	valRecv naming.VDLGlobReply
+	errRecv error
+}
+
+func (c *implNamespaceGlobCall) RecvStream() interface {
+	Advance() bool
+	Value() naming.VDLGlobReply
+	Err() error
+} {
+	return implNamespaceGlobCallRecv{c}
+}
+
+type implNamespaceGlobCallRecv struct {
+	c *implNamespaceGlobCall
+}
+
+func (c implNamespaceGlobCallRecv) Advance() bool {
+	c.c.errRecv = c.c.Recv(&c.c.valRecv)
+	return c.c.errRecv == nil
+}
+func (c implNamespaceGlobCallRecv) Value() naming.VDLGlobReply {
+	return c.c.valRecv
+}
+func (c implNamespaceGlobCallRecv) Err() error {
+	if c.c.errRecv == io.EOF {
+		return nil
+	}
+	return c.c.errRecv
+}
+func (c *implNamespaceGlobCall) Finish() (err error) {
+	err = c.Call.Finish()
+	return
+}
+
+// NamespaceServerMethods is the interface a server writer
+// implements for Namespace.
+type NamespaceServerMethods interface {
+	// Run a glob query and stream the results.
+	Glob(ctx NamespaceGlobContext, pattern string) error
+	// Mount mounts a server under the given name.
+	Mount(ctx ipc.ServerContext, name string, server string, ttl time.Duration, replace bool) error
+	// Unmount removes an existing mount point.
+	Unmount(ctx ipc.ServerContext, name string, server string) error
+	// Resolve resolves a name to an address.
+	Resolve(ctx ipc.ServerContext, name string) ([]string, error)
+	// ResolveToMt resolves a name to the address of the mounttable directly
+	// hosting it.
+	ResolveToMT(ctx ipc.ServerContext, name string) ([]string, error)
+	// FlushCacheEntry removes the namespace cache entry for a given name.
+	FlushCacheEntry(ctx ipc.ServerContext, name string) (bool, error)
+	// DisableCache disables the naming cache.
+	DisableCache(ctx ipc.ServerContext, disable bool) error
+	// Roots returns the addresses of the current mounttable roots.
+	Roots(ipc.ServerContext) ([]string, error)
+	// SetRoots sets the current mounttable roots.
+	SetRoots(ctx ipc.ServerContext, roots []string) error
+}
+
+// NamespaceServerStubMethods is the server interface containing
+// Namespace methods, as expected by ipc.Server.
+// The only difference between this interface and NamespaceServerMethods
+// is the streaming methods.
+type NamespaceServerStubMethods interface {
+	// Run a glob query and stream the results.
+	Glob(ctx *NamespaceGlobContextStub, pattern string) error
+	// Mount mounts a server under the given name.
+	Mount(ctx ipc.ServerContext, name string, server string, ttl time.Duration, replace bool) error
+	// Unmount removes an existing mount point.
+	Unmount(ctx ipc.ServerContext, name string, server string) error
+	// Resolve resolves a name to an address.
+	Resolve(ctx ipc.ServerContext, name string) ([]string, error)
+	// ResolveToMt resolves a name to the address of the mounttable directly
+	// hosting it.
+	ResolveToMT(ctx ipc.ServerContext, name string) ([]string, error)
+	// FlushCacheEntry removes the namespace cache entry for a given name.
+	FlushCacheEntry(ctx ipc.ServerContext, name string) (bool, error)
+	// DisableCache disables the naming cache.
+	DisableCache(ctx ipc.ServerContext, disable bool) error
+	// Roots returns the addresses of the current mounttable roots.
+	Roots(ipc.ServerContext) ([]string, error)
+	// SetRoots sets the current mounttable roots.
+	SetRoots(ctx ipc.ServerContext, roots []string) error
+}
+
+// NamespaceServerStub adds universal methods to NamespaceServerStubMethods.
+type NamespaceServerStub interface {
+	NamespaceServerStubMethods
+	// Describe the Namespace interfaces.
+	Describe__() []ipc.InterfaceDesc
+}
+
+// NamespaceServer returns a server stub for Namespace.
+// It converts an implementation of NamespaceServerMethods into
+// an object that may be used by ipc.Server.
+func NamespaceServer(impl NamespaceServerMethods) NamespaceServerStub {
+	stub := implNamespaceServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := ipc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := ipc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implNamespaceServerStub struct {
+	impl NamespaceServerMethods
+	gs   *ipc.GlobState
+}
+
+func (s implNamespaceServerStub) Glob(ctx *NamespaceGlobContextStub, i0 string) error {
+	return s.impl.Glob(ctx, i0)
+}
+
+func (s implNamespaceServerStub) Mount(ctx ipc.ServerContext, i0 string, i1 string, i2 time.Duration, i3 bool) error {
+	return s.impl.Mount(ctx, i0, i1, i2, i3)
+}
+
+func (s implNamespaceServerStub) Unmount(ctx ipc.ServerContext, i0 string, i1 string) error {
+	return s.impl.Unmount(ctx, i0, i1)
+}
+
+func (s implNamespaceServerStub) Resolve(ctx ipc.ServerContext, i0 string) ([]string, error) {
+	return s.impl.Resolve(ctx, i0)
+}
+
+func (s implNamespaceServerStub) ResolveToMT(ctx ipc.ServerContext, i0 string) ([]string, error) {
+	return s.impl.ResolveToMT(ctx, i0)
+}
+
+func (s implNamespaceServerStub) FlushCacheEntry(ctx ipc.ServerContext, i0 string) (bool, error) {
+	return s.impl.FlushCacheEntry(ctx, i0)
+}
+
+func (s implNamespaceServerStub) DisableCache(ctx ipc.ServerContext, i0 bool) error {
+	return s.impl.DisableCache(ctx, i0)
+}
+
+func (s implNamespaceServerStub) Roots(ctx ipc.ServerContext) ([]string, error) {
+	return s.impl.Roots(ctx)
+}
+
+func (s implNamespaceServerStub) SetRoots(ctx ipc.ServerContext, i0 []string) error {
+	return s.impl.SetRoots(ctx, i0)
+}
+
+func (s implNamespaceServerStub) Globber() *ipc.GlobState {
+	return s.gs
+}
+
+func (s implNamespaceServerStub) Describe__() []ipc.InterfaceDesc {
+	return []ipc.InterfaceDesc{NamespaceDesc}
+}
+
+// NamespaceDesc describes the Namespace interface.
+var NamespaceDesc ipc.InterfaceDesc = descNamespace
+
+// descNamespace hides the desc to keep godoc clean.
+var descNamespace = ipc.InterfaceDesc{
+	Name:    "Namespace",
+	PkgPath: "v.io/wspr/veyron/services/wsprd/namespace",
+	Methods: []ipc.MethodDesc{
+		{
+			Name: "Glob",
+			Doc:  "// Run a glob query and stream the results.",
+			InArgs: []ipc.ArgDesc{
+				{"pattern", ``}, // string
+			},
+		},
+		{
+			Name: "Mount",
+			Doc:  "// Mount mounts a server under the given name.",
+			InArgs: []ipc.ArgDesc{
+				{"name", ``},    // string
+				{"server", ``},  // string
+				{"ttl", ``},     // time.Duration
+				{"replace", ``}, // bool
+			},
+		},
+		{
+			Name: "Unmount",
+			Doc:  "// Unmount removes an existing mount point.",
+			InArgs: []ipc.ArgDesc{
+				{"name", ``},   // string
+				{"server", ``}, // string
+			},
+		},
+		{
+			Name: "Resolve",
+			Doc:  "// Resolve resolves a name to an address.",
+			InArgs: []ipc.ArgDesc{
+				{"name", ``}, // string
+			},
+			OutArgs: []ipc.ArgDesc{
+				{"", ``}, // []string
+			},
+		},
+		{
+			Name: "ResolveToMT",
+			Doc:  "// ResolveToMt resolves a name to the address of the mounttable directly\n// hosting it.",
+			InArgs: []ipc.ArgDesc{
+				{"name", ``}, // string
+			},
+			OutArgs: []ipc.ArgDesc{
+				{"", ``}, // []string
+			},
+		},
+		{
+			Name: "FlushCacheEntry",
+			Doc:  "// FlushCacheEntry removes the namespace cache entry for a given name.",
+			InArgs: []ipc.ArgDesc{
+				{"name", ``}, // string
+			},
+			OutArgs: []ipc.ArgDesc{
+				{"", ``}, // bool
+			},
+		},
+		{
+			Name: "DisableCache",
+			Doc:  "// DisableCache disables the naming cache.",
+			InArgs: []ipc.ArgDesc{
+				{"disable", ``}, // bool
+			},
+		},
+		{
+			Name: "Roots",
+			Doc:  "// Roots returns the addresses of the current mounttable roots.",
+			OutArgs: []ipc.ArgDesc{
+				{"", ``}, // []string
+			},
+		},
+		{
+			Name: "SetRoots",
+			Doc:  "// SetRoots sets the current mounttable roots.",
+			InArgs: []ipc.ArgDesc{
+				{"roots", ``}, // []string
+			},
+		},
+	},
+}
+
+// NamespaceGlobServerStream is the server stream for Namespace.Glob.
+type NamespaceGlobServerStream interface {
+	// SendStream returns the send side of the Namespace.Glob server stream.
+	SendStream() interface {
+		// Send places the item onto the output stream.  Returns errors encountered
+		// while sending.  Blocks if there is no buffer space; will unblock when
+		// buffer space is available.
+		Send(item naming.VDLGlobReply) error
+	}
+}
+
+// NamespaceGlobContext represents the context passed to Namespace.Glob.
+type NamespaceGlobContext interface {
+	ipc.ServerContext
+	NamespaceGlobServerStream
+}
+
+// NamespaceGlobContextStub is a wrapper that converts ipc.ServerCall into
+// a typesafe stub that implements NamespaceGlobContext.
+type NamespaceGlobContextStub struct {
+	ipc.ServerCall
+}
+
+// Init initializes NamespaceGlobContextStub from ipc.ServerCall.
+func (s *NamespaceGlobContextStub) Init(call ipc.ServerCall) {
+	s.ServerCall = call
+}
+
+// SendStream returns the send side of the Namespace.Glob server stream.
+func (s *NamespaceGlobContextStub) SendStream() interface {
+	Send(item naming.VDLGlobReply) error
+} {
+	return implNamespaceGlobContextSend{s}
+}
+
+type implNamespaceGlobContextSend struct {
+	s *NamespaceGlobContextStub
+}
+
+func (s implNamespaceGlobContextSend) Send(item naming.VDLGlobReply) error {
+	return s.s.Send(item)
+}
diff --git a/services/wsprd/namespace/request_handler.go b/services/wsprd/namespace/request_handler.go
index e578015..fcf2cc5 100644
--- a/services/wsprd/namespace/request_handler.go
+++ b/services/wsprd/namespace/request_handler.go
@@ -1,119 +1,95 @@
 package namespace
 
 import (
-	"encoding/json"
 	"time"
 
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/context"
+	"v.io/core/veyron2/ipc"
 	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/verror"
-
-	"v.io/wspr/veyron/services/wsprd/lib"
 )
 
-// Function to format endpoints.  Used by browspr to swap 'tcp' for 'ws'.
-var EpFormatter func([]string) ([]string, error) = nil
-
-// request struct represents a request to call a method on the runtime's namespace client
-type request struct {
-	Method namespaceMethod
-	Args   json.RawMessage
+type Server struct {
+	ns naming.Namespace
 }
 
-type namespaceMethod int
-
-// enumerates the methods available to be called on the runtime's namespace client
-const (
-	methodGlob            namespaceMethod = 0
-	methodMount                           = 1
-	methodUnmount                         = 2
-	methodResolve                         = 3
-	methodResolveToMt                     = 4
-	methodFlushCacheEntry                 = 5
-	methodDisableCache                    = 6
-	methodRoots                           = 7
-	methodSetRoots                        = 8
-)
-
-// globArgs defines the args for the glob method
-type globArgs struct {
-	Pattern string
+func New(ctx *context.T) *Server {
+	return &Server{veyron2.GetNamespace(ctx)}
 }
 
-// mountArgs defines the args for the mount method
-type mountArgs struct {
-	Name         string
-	Server       string
-	Ttl          time.Duration
-	replaceMount bool
-}
-
-// unmountArgs defines the args for the unmount method
-type unmountArgs struct {
-	Name   string
-	Server string
-}
-
-// resolveArgs defines the args for the resolve method
-type resolveArgs struct {
-	Name string
-}
-
-// resolveToMtArgs defines the args for the resolveToMt method
-type resolveToMtArgs struct {
-	Name string
-}
-
-// flushCacheEntryArgs defines the args for the flushCacheEntry method
-type flushCacheEntryArgs struct {
-	Name string
-}
-
-// disableCacheArgs defines the args for the disableCache method
-type disableCacheArgs struct {
-	Disable bool
-}
-
-// setRootsArgs defines the args for the setRoots method
-type setRootsArgs struct {
-	Roots []string
-}
-
-// handleRequest uses the namespace client to respond to namespace specific requests such as glob
-func HandleRequest(ctx *context.T, data string, w lib.ClientWriter) {
-	// Decode the request
-	var req request
-	if err := json.Unmarshal([]byte(data), &req); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
+func (s *Server) Glob(ctx *NamespaceGlobContextStub, pattern string) error {
+	// Call Glob on the namespace client instance
+	ch, err := s.ns.Glob(ctx.Context(), pattern)
+	if err != nil {
+		return err
 	}
 
-	// Get the runtime's Namespace client
-	var ns = veyron2.GetNamespace(ctx)
+	stream := ctx.SendStream()
 
-	switch req.Method {
-	case methodGlob:
-		glob(ctx, ns, w, req.Args)
-	case methodMount:
-		mount(ctx, ns, w, req.Args)
-	case methodUnmount:
-		unmount(ctx, ns, w, req.Args)
-	case methodResolve:
-		resolve(ctx, ns, w, req.Args)
-	case methodResolveToMt:
-		resolveToMt(ctx, ns, w, req.Args)
-	case methodFlushCacheEntry:
-		flushCacheEntry(ctx, ns, w, req.Args)
-	case methodDisableCache:
-		disableCache(ctx, ns, w, req.Args)
-	case methodRoots:
-		roots(ctx, ns, w)
-	case methodSetRoots:
-		setRoots(ctx, ns, w, req.Args)
-	default:
-		w.Error(verror.New(verror.ErrNoExist, ctx, req.Method))
+	for mp := range ch {
+		var reply naming.VDLGlobReply
+		switch v := mp.(type) {
+		case *naming.GlobError:
+			reply = naming.VDLGlobReplyError{*v}
+		case *naming.MountEntry:
+			reply = naming.VDLGlobReplyEntry{convertToVDLEntry(*v)}
+		}
+		if err = stream.Send(reply); err != nil {
+			return err
+		}
 	}
+	return nil
+}
+
+func (s *Server) Mount(ctx ipc.ServerContext, name, server string, ttl time.Duration, replace bool) error {
+	rmOpt := naming.ReplaceMountOpt(replace)
+	err := s.ns.Mount(ctx.Context(), name, server, ttl, rmOpt)
+	if err != nil {
+		err = verror.Convert(verror.ErrInternal, ctx.Context(), err)
+	}
+	return err
+}
+
+func (s *Server) Unmount(ctx ipc.ServerContext, name, server string) error {
+	return s.ns.Unmount(ctx.Context(), name, server)
+}
+
+func (s *Server) Resolve(ctx ipc.ServerContext, name string) ([]string, error) {
+	me, err := s.ns.Resolve(ctx.Context(), name)
+	if err != nil {
+		return nil, verror.Convert(verror.ErrInternal, ctx.Context(), err)
+	}
+	return me.Names(), nil
+}
+
+func (s *Server) ResolveToMT(ctx ipc.ServerContext, name string) ([]string, error) {
+	me, err := s.ns.ResolveToMountTable(ctx.Context(), name)
+	if err != nil {
+		return nil, verror.Convert(verror.ErrInternal, ctx.Context(), err)
+	}
+	return me.Names(), nil
+}
+
+func (s *Server) FlushCacheEntry(ctx ipc.ServerContext, name string) (bool, error) {
+	return s.ns.FlushCacheEntry(name), nil
+}
+
+func (s *Server) DisableCache(ctx ipc.ServerContext, disable bool) error {
+	disableCacheCtl := naming.DisableCache(disable)
+	_ = s.ns.CacheCtl(disableCacheCtl)
+	return nil
+}
+
+func (s *Server) Roots(ctx ipc.ServerContext) ([]string, error) {
+	return s.ns.Roots(), nil
+}
+
+func (s *Server) SetRoots(ctx ipc.ServerContext, roots []string) error {
+	if err := s.ns.SetRoots(roots...); err != nil {
+		return verror.Convert(verror.ErrInternal, ctx.Context(), err)
+	}
+	return nil
 }
 
 func convertToVDLEntry(value naming.MountEntry) naming.VDLMountEntry {
@@ -130,190 +106,3 @@
 	}
 	return result
 }
-
-func glob(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args globArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	// Call Glob on the namespace client instance
-	ch, err := ns.Glob(ctx, args.Pattern)
-
-	if err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	for mp := range ch {
-		switch v := mp.(type) {
-		// send results that have error through the error stream.
-		// TODO(aghassemi) we want mp to be part of the error's ParamsList, but there is no good way right now in verror to do this.
-		case *naming.GlobError:
-			err := verror.Convert(verror.ErrUnknown, ctx, v.Error)
-			w.Error(err)
-		case *naming.MountEntry:
-			val, err := lib.VomEncode(convertToVDLEntry(*v))
-			if err != nil {
-				w.Error(verror.New(verror.ErrInternal, ctx, err))
-				return
-			}
-
-			if err := w.Send(lib.ResponseStream, val); err != nil {
-				w.Error(verror.New(verror.ErrInternal, ctx, *v))
-				return
-			}
-		}
-	}
-
-	if err := w.Send(lib.ResponseStreamClose, nil); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseStreamClose"))
-	}
-
-	if err := w.Send(lib.ResponseFinal, nil); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func mount(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args mountArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	rmOpt := naming.ReplaceMountOpt(args.replaceMount)
-	err := ns.Mount(ctx, args.Name, args.Server, args.Ttl, rmOpt)
-
-	if err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	if err := w.Send(lib.ResponseFinal, nil); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func unmount(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args unmountArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	err := ns.Unmount(ctx, args.Name, args.Server)
-
-	if err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	if err := w.Send(lib.ResponseFinal, nil); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func resolve(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args resolveArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	me, err := ns.Resolve(ctx, args.Name)
-
-	if err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	if err := w.Send(lib.ResponseFinal, me.Names()); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func resolveToMt(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args resolveToMtArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	me, err := ns.ResolveToMountTable(ctx, args.Name)
-
-	if err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	if err := w.Send(lib.ResponseFinal, me.Names()); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func flushCacheEntry(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args flushCacheEntryArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	flushed := ns.FlushCacheEntry(args.Name)
-
-	if err := w.Send(lib.ResponseFinal, flushed); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func disableCache(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args disableCacheArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	disableCacheCtl := naming.DisableCache(args.Disable)
-	_ = ns.CacheCtl(disableCacheCtl)
-
-	if err := w.Send(lib.ResponseFinal, nil); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func roots(ctx *context.T, ns naming.Namespace, w lib.ClientWriter) {
-	roots := ns.Roots()
-
-	if err := w.Send(lib.ResponseFinal, roots); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
-
-func setRoots(ctx *context.T, ns naming.Namespace, w lib.ClientWriter, rawArgs json.RawMessage) {
-	var args setRootsArgs
-	if err := json.Unmarshal([]byte(rawArgs), &args); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	var formattedRoots []string
-	var err error
-	if EpFormatter != nil {
-		formattedRoots, err = EpFormatter(args.Roots)
-		if err != nil {
-			w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		}
-	} else {
-		formattedRoots = args.Roots
-	}
-
-	if err := ns.SetRoots(formattedRoots...); err != nil {
-		w.Error(verror.Convert(verror.ErrInternal, ctx, err))
-		return
-	}
-
-	if err := w.Send(lib.ResponseFinal, nil); err != nil {
-		w.Error(verror.New(verror.ErrInternal, ctx, "ResponseFinal"))
-	}
-}
