I was wondering where this goes and how you could get so far.
Caché uses a temp file.
 

USER>set sbJSON =##class(%Stream.FileCharacter).%New()
USER>s sc=sbJSON.WriteLine(12123)
 
USER>zw sc
sc=1
 
USER>zw sbJSON
sbJSON=<OBJECT REFERENCE>[6@%Stream.FileCharacter]
+----------------- general information ---------------
|      oref value: 6
|      class name: %Stream.FileCharacter
| reference count: 2
+----------------- attribute values ------------------
|     (%Concurrency) = 1
|          %Location = ""  <Set>
|         (%LockRef) = ""
|          (%Locked) = 0
|              AtEnd = 0
|                BOM = ""
|         (CurrFile) = "C:\InterSystems\17E20\mgr\Temp\mAiLCZXuPXOaSQ.stream"
|                 Id = ""  <Set>
|     LineTerminator = $c(13,10)  <Set>
|      (MakePermLoc) = 1
|             (Mode) = 3
|(NormalizedDirectory) = "C:\InterSystems\17E20\mgr\Temp\"
|(OidTranslateTable) = 0
|         (ReadMode) = 0
|           ReadSize = ""
|      RemoveOnClose = 0
|        (StoreFile) = ""
|  StreamFormatWrite = 1
|         (TempFile) = "mAiLCZXuPXOaSQ.stream"
|     TranslateTable = ""  <Set>
|      UseVMSVersion = 0
|   (VariableRecord) = 0
+--------------- calculated references ---------------
|  CanonicalFilename   <Get>
|           Filename   <Get,Set>
|       LastModified   <Get>
|               Size   <Get>
+-----------------------------------------------------
 
USER>

Analyzing you code I see the problem in this line:

              do sbJSON.WriteLine($C(92)_..SafeJSON(node.GetDocumentNode())_$C(92)_$C(58))


I take for given that sbJSON is a valid object.
So I further investigate on node 

   ..XmlToJSONnode( )  is called twice + recursive
#1  from ..
XmlToJSON() looks fine

#2 is suspicious as in  .. OutputNode() I see   
 

Method OutputNode(childname As %String, alChild As %RegisteredObject, sbJSON As %Stream, showNodeName As %Boolean)
{
             if (alChild = null)      // EMPTY, NOT AN OBJECT
            ... }
            elseif (alChild)          // IT IS eventually an OBJECT REFERENCE
            { ...  }
            else       // NOT EMPTY, NOT NUMERIC, AND NOT AN OBJECT REFERENCE
            {
               do ..XmlToJSONnode(sbJSON,alChild, showNodeName)
; > > > > > > > > > > > > > > > > > > > >^^^^^^  // WHAT is this now ???

            }
             do sbJSON.WriteLine($C(4))
}

so what you hand over is not an oref as this looks like <integer>@<classname>  
therefore you fail with <INVALID OREF>zXmlToJSONnode+3^SharpJSONToXML.1

so some action is required to find out what happens

BTW:

passing sbJSON by reference would make this recursive construct easier to understand
as you intend to work to the same stream object anyhow.
or just use %sbJSON as single common reference

with 

set tSc AuthToken.Post("/webservices/Void")

you miss some content to POST and get

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header/>
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>Client</faultcode>
            <faultstring>An exception has been raised as a result of client data.</faultstring>
            <detail>
                <err:Errors xmlns:err="http://www.ups.com/schema/xpci/1.0/error">
                    <err:ErrorDetail>
                        <err:Severity>Hard</err:Severity>
                        <err:PrimaryErrorCode>
                            <err:Code>10001</err:Code>
                            <err:Description>The XML document is not well formed</err:Description>
                            <err:Digest>Unexpected element: CDATA</err:Digest>
                        </err:PrimaryErrorCode>
                        <err:Location/>
                    </err:ErrorDetail>
                </err:Errors>
            </detail>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>

use instead

set tSc AuthToken.Get("/webservices/Void")

and receive

<HTML>
<HEAD><TITLE>UPS Online Tools VoidWS</TITLE></HEAD>
<BODY><H2>
Service Name: VoidWS<br>
Remote User: null<br>
Server Port: 443<br>
Server Name: wwwcie.ups.com<br>
Servlet Path: /Void<br>
</H2>
</BODY></HTML>

just run $System.OBJ.Export() for your Global and hand over the result to your CVS.

USER>s sc=$system.OBJ.Export("^rcc.GBL","exportTest.txt",,.error,"UTF8")
 
Exportieren in XML gestartet am 04/01/2018 10:25:26
Exportiere Global: ^rcc

the result is a nice XML structure

and $system.OBJ.Import()  reloads it  

The extension  .GBL is the important thing

http://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?P...

Update: 

Blocks.Router uses $toJSONFormat() {CR/LF formatedOutput }
this hidden function hasn't been ported. replacement with %ToJSON()  does it as well.
So TREE view works nice.

Map view gets no content (and no colored dots  crying ).
Reason:  Block Count=0 and also %Fill -> nothing to display (makes sense somehow). 
This is also with the original classes in 2016.1.4 ;
Looks like an privilege issue.

You are missing the point.

12345 is the port used by the cache DB server   (default=1972) of your instance.
internally there is a mapping between the logical NAMESPACE and the physical disk directory and that NAMESPACE is used in connection string.
if your namespace is called DB then  you have to use 

jdbc:Cache://localhost:12345/DB

But if you just have the directory .../cache/db/cache.dat  you can't say what NAMESPACE this is
You have to know your Caché configuration.

Some reading on Caché configuration may give you background information
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...

OK. I understand.
- I doubt if a Linux distribution of Caché contains any Windows mechanics. ( to be checked with WRC )
- on the other hand I don't believe it's possible or make sense  to run Caché Win distribution in a Win-Shell ...
So suggested workaround:
Have a VM (or small machine) with Windows +Caché and connect via ECP or similar (REST, WebService, JDBC, ...)  to your main Caché instance on Linux. 

OR:

Wrap some C# around your DLL on a Windows box and present it as a WebService that you call from Linux.

Hi Jeffrey,

Your descriptions matches pretty well what is titled in Ensemble as "Workflow"
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...

It uses specialized Request and Response messages that are designed to allow a significant time gap in between.
It's originally designed for human interactions but to my understanding it implements exactly your "sideline".
And human interaction is just there to show it may take long time to get a reply.
There is also an example in ENSDEMO  Demo.Workflow.Production  ​

 HTH,

Robert