diff --git a/cf.js b/cf.js
index 639fb6111d67fd015b92d279d1225e541deeb8f1..1fd69108e2ac11d8599cadbd35240e29b5ba0c41 100644
--- a/cf.js
+++ b/cf.js
@@ -2,6 +2,8 @@
 
 const express = require('express')
 const app = express()
+// this include lets us read data out of put requests,
+const bodyparser = require('body-parser')
 // our fs tools,
 const filesys = require('./filesys.js')
 // will use these to figure where tf we are
@@ -10,6 +12,8 @@ let ifaces = os.networkInterfaces()
 
 // serve everything: https://expressjs.com/en/resources/middleware/serve-static.html
 app.use(express.static(__dirname))
+app.use(bodyparser.json())
+app.use(bodyparser.urlencoded({extended: true}))
 // if these don't exist, they get 'nexted' to any other 'middleware' we write
 app.get('/fileList', (req, res) => {
   try{
@@ -37,10 +41,13 @@ app.get('/fileList', (req, res) => {
     res.send('server-side error retrieving list')
   }
 })
-
 // we also handle file-saving this way,
-app.put('/save/systems/:file', (req, res) => {
-  console.log('put req to ' + req.params.file)
+app.post('/save/contexts/:context/:file', (req, res) => {
+  // this is probably fine for now, but I kind of want a websocket to do this kind of stuff ?
+  console.log('put req to context' + req.params.context, 'with name', req.params.file)
+  console.log('the file as', req.body)
+  // now we fs.write() this thing, and reply...
+  res.send({ok: true})
 })
 
 let port = 8080
diff --git a/gogetter.js b/gogetter.js
index f71cf1b6eb8e6e6753c4d3445e58b5d7b63831b5..767eb1cb682cb1544b240f58727ee1bad5847898 100644
--- a/gogetter.js
+++ b/gogetter.js
@@ -39,6 +39,7 @@ function GoGetter() {
         }
       })
     })
+
     // ... previously, this hack... but why?
     /*
     return new Promise((resolve, reject) => {
diff --git a/view/vcontextmenu.js b/view/vcontextmenu.js
index f666d9c2c43b5b9a14030f6246d3af04ce48702f..3b37280ffedd3185c4de0cf17facc2b82b70ce2c 100644
--- a/view/vcontextmenu.js
+++ b/view/vcontextmenu.js
@@ -69,7 +69,7 @@ function cfContextMenu(evt, view, dt) {
     }, ms)
   }
 
-  let setupForSave = (se, obj) => {
+  let setupForSave = (se, callback) => {
     $(se.target).closest('li').text('')
     let tinput = $('<input>').attr('type', 'text').attr('size', 24).attr('value', 'name').get(0)
     $(se.target).closest('li').append(tinput) // etc
@@ -77,7 +77,9 @@ function cfContextMenu(evt, view, dt) {
     $(tinput).select()
     $(tinput).on('keyup', (ke) => {
       if (ke.keyCode == 13) {
-        let bleb = JSON.stringify(obj)
+        callback(tinput.value)
+        // this would present a download link
+        /*
         let url = URL.createObjectURL(new Blob([JSON.stringify(obj, null, 2)], {
           type: "application/json"
         }))
@@ -87,6 +89,7 @@ function cfContextMenu(evt, view, dt) {
         anchor.click()
         // finally, rip
         fadeOut(400)
+        */
       }
     })
   }
@@ -226,8 +229,12 @@ function cfContextMenu(evt, view, dt) {
   // save patches
   addContextOption('<i class="em em-blue_book"></i> save this context', (ce) => {
     let ptch = scope.patchset.writeCurrent()
-    console.log('-> patch!', ptch)
-    setupForSave(ce, ptch)
+    setupForSave(ce, (name) => {
+      let serialized = JSON.stringify(ptch)
+      jQuery.post(`/save/contexts/${scope.interpreterName}/${name}`, serialized, (res) => {
+        console.log('post result', res)
+      }, 'json')
+    })
   })
 
   // load patches,
@@ -320,7 +327,9 @@ function cfContextMenu(evt, view, dt) {
     // once that runs to completion, should have the hierarchichal patch
     console.log('CONSIDER THIS: a system patch ... ', tlp)
     // now present-and-save
-    setupForSave(ce, tlp)
+    setupForSave(ce, (name) => {
+      // ship blob 2 server at put /
+    })
   }) // end save entire system
 
   // MERGE A SYSTEM