diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Peter Harpending
+
+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 Peter Harpending nor the names of other
+      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.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,130 @@
+# eros-client
+
+This is a command line interface to the
+[eros library](https://github.com/pharpend/eros).
+
+# Usage - v.0.4.0.0
+
+This is a usage guide for version 0.4.0.0. There will be more up-to-date usage
+guides as more versions come, hopefully.
+
+To install, run `cabal install eros-client-0.4.0.0`.
+
+The only way to interact with the library, for the time being is through the
+client I built, `erosc`. It accepts input in Javascript Object Notation (JSON)
+through `stdin`.
+
+Here is the schema for the input:
+
+```json
+{
+  "name": "erosc-input",
+  "type": "object",
+  "description": "The schema for the input to erosc.",
+  "properties": {
+    "text": {
+      "type": "string",
+      "description": "The text you want to be checked against the phraselists.",
+      "required": true
+    },
+    "eros-lists": {
+      "type": "array",
+      "description": "The phraselists provided by eros you want \"text\" to be checked against.",
+      "required": true,
+      "items": {
+        "type": "string"
+      }
+    },
+  }
+}
+```
+
+That is the up-to-date schema, as of version 0.4.0.0 . It is liable to
+change. If the version you downloaded is greater than 0.4.0.0, make sure to
+check the schema (it is distributed with the package) to make sure it is up to
+date. The schema is located in `res/schemata/erosc-input.json`.
+
+`erosc` will take that input, and send back output in JSON, in accordance with
+the schema found in `res/schemata/erosc-output.json`.
+
+```json
+{
+  "name": "erosc-output",
+  "type": "array",
+  "description": "The output of erosc.",
+  "items": {
+    "type": "object",
+    "description": "The phraselist name, along with the score for that phraselist.",
+    "properties": {
+      "eros-list": {
+        "type": "string",
+        "description": "The name of the phraselist corresponding to this object."
+      },
+      "score": {
+        "type": "number",
+        "description": "The score corresponding to this phraselist."
+      }
+    }
+  }
+}
+```
+
+## Example
+
+This is the example input from `res/erosc-dummy-inputs/input0.json`.
+
+```json
+{
+  "text": "Fuck you, you fucking fuck! Fucking bitch tits milf sex sluts!",
+  "eros-lists": [
+    "gambling",
+    "pornography"
+  ]
+}
+```
+
+Running `erosc < res/erosc-dummy-inputs/input0.json` yields
+
+```json
+[
+  {
+    "score": 0,
+    "eros-list": "gambling"
+  },
+  {
+    "score": 11394,
+    "eros-list": "pornography"
+  }
+]
+```
+
+# Contributing
+
+I would love if people would contribute. This client is BSD-licensed, so you can
+pretty much do whatever you want with it.
+
+If you have any ideas, don't hesitate to contact me.
+
+## Planned features
+
+### `erosc` ⟶ `eros-server`
+
+As it stands, `erosc` is tedious and a bit difficult to use. I plan on rewriting
+`erosc` to act as an HTTP[s] server, using Happstack, using acid-state as a RAM
+cloud. This will be the fastest and easiest to maintain solution.
+
+I will still include an offline client, but it won't be the focus of
+development.
+
+### More options
+
+I need to add more filtering options, such as phraselist-specific thresholds,
+custom phraselists, and, well, just more stuff.
+
+# Contact
+
+The best way to contact me is via IRC. I hang out a lot on `#archlinux` and
+`#haskell` on the FreeNode network. My nicks are `l0cust` and `isomorpheous`.
+
+You can also email me at <pharpend2@gmail.com>, although I'm not great at
+checking that email address.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/eros-client.cabal b/eros-client.cabal
new file mode 100644
--- /dev/null
+++ b/eros-client.cabal
@@ -0,0 +1,44 @@
+name:                eros-client
+version:             0.4.0.0
+synopsis:            A command-line interface to the eros library.
+description:
+  This is a command-line interface to the
+  <https://github.com/pharpend/eros eros library>.
+
+  It is terrible at the moment, and will be deprecated before version 0.5.0.0,
+  so it isn't a huge priority.
+
+license:             BSD3
+license-file:        LICENSE
+author:              Peter Harpending
+maintainer:          Peter Harpending <pharpend2@gmail.com>
+copyright:           2014, Peter Harpending.
+category:            Text
+build-type:          Simple
+data-files:
+  res/schemata/*.json
+cabal-version:       >=1.10
+extra-source-files:
+  README.md
+  res/erosc-dummy-inputs/*.json
+  res/schemata/*.json
+
+executable erosc
+  build-depends:
+      aeson
+    , aeson-pretty
+    , base          >=4.7 && <4.8
+    , bytestring
+    , containers
+    , eros          ==0.4.0.0
+    , text
+  hs-source-dirs:   src/
+  main-is:          Main.lhs
+  other-modules:    Erosc.Processor
+  default-language: Haskell2010
+  ghc-options:      -Wall
+
+source-repository head
+  type:     git
+  location: https://github.com/pharpend/eros-client.git
+  branch:   master
diff --git a/res/erosc-dummy-inputs/input0.json b/res/erosc-dummy-inputs/input0.json
new file mode 100644
--- /dev/null
+++ b/res/erosc-dummy-inputs/input0.json
@@ -0,0 +1,7 @@
+{
+  "text": "Fuck you, you fucking fuck! Fucking bitch tits milf sex sluts!",
+  "eros-lists": [
+    "gambling",
+    "pornography"
+  ]
+}
diff --git a/res/schemata/erosc-input.json b/res/schemata/erosc-input.json
new file mode 100644
--- /dev/null
+++ b/res/schemata/erosc-input.json
@@ -0,0 +1,20 @@
+{
+  "name": "erosc-input",
+  "type": "object",
+  "description": "The schema for the input to erosc.",
+  "properties": {
+    "text": {
+      "type": "string",
+      "description": "The text you want to be checked against the phraselists.",
+      "required": true
+    },
+    "eros-lists": {
+      "type": "array",
+      "description": "The phraselists provided by eros you want \"text\" to be checked against.",
+      "required": true,
+      "items": {
+        "type": "string"
+      }
+    },
+  }
+}
diff --git a/res/schemata/erosc-output.json b/res/schemata/erosc-output.json
new file mode 100644
--- /dev/null
+++ b/res/schemata/erosc-output.json
@@ -0,0 +1,19 @@
+{
+  "name": "erosc-output",
+  "type": "array",
+  "description": "The output of erosc.",
+  "items": {
+    "type": "object",
+    "description": "The phraselist name, along with the score for that phraselist.",
+    "properties": {
+      "eros-list": {
+        "type": "string",
+        "description": "The name of the phraselist corresponding to this object."
+      },
+      "score": {
+        "type": "number",
+        "description": "The score corresponding to this phraselist."
+      }
+    }
+  }
+}
diff --git a/src/Erosc/Processor.hs b/src/Erosc/Processor.hs
new file mode 100644
--- /dev/null
+++ b/src/Erosc/Processor.hs
@@ -0,0 +1,94 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- |This is the module which actually processes the marshals the
+-- data. As far as erosc goes, this is the meat & potatoes.
+-- 
+-- Basically, Main.hs was getting to be too long, so I created this
+-- file.
+-- 
+-- Copyright (c) 2014, Peter Harpending <pharpend2@gmail.com>. All
+-- Rights Reserved.
+-- 
+-- I'm supposed to say "All Rights Reserved," but this is actuallly
+-- BSD-licensed. So, really you can do whatever you want with
+-- this. Have fun!
+
+module Erosc.Processor where
+
+-- One of these days, I'm going to figure out how to cut down on these
+-- imports. 
+import           Control.Applicative
+import           Control.Monad                         (mzero)
+import           Data.Aeson                     hiding (encode)
+import           Data.Aeson.Encode.Pretty
+import qualified Data.ByteString.Lazy as LzByte
+import qualified Data.Text.Lazy       as LzText
+import           Text.Eros
+
+-- |Okay, here's a function that actually does something. It takes an
+-- 'Input' type, and process it.
+processInput :: Input -> IO Output
+processInput (Input txt lists) = do
+    outLists <- mapM listPair lists
+    return $ Output outLists
+  where
+    listPair :: ErosList -> IO (ErosList, Score)
+    listPair ls = do
+      pmap <- loadPhraseMap ls
+      let scr = messageScore txt pmap
+      return (ls, scr)
+
+-- |This will print JSON in a pretty matter, using 2-space indents. I
+-- have no idea why 4-space indents are the default.
+encode :: ToJSON a => a -> LzByte.ByteString
+encode = encodePretty' defConfig { confIndent = 2
+                                 }
+
+-- |We represent the input data in its own data type. This is needed
+-- for JSON parsing, but it will also be useful down the road, when I
+-- allow input that isn't JSON.
+data Input = Input { text      :: LzText.Text
+                   , erosLists :: [ErosList]
+                   }
+
+-- |This is pretty self-explanatory
+instance FromJSON ErosList where
+  parseJSON (String s) = case erosListByName (LzText.fromStrict s) of
+                           Just list -> return list
+                           Nothing   -> mzero
+  parseJSON _          = mzero
+
+-- |This is pretty self-explanatory
+instance FromJSON Input where
+  parseJSON (Object v) = Input
+    <$> v .: "text"
+    <*> v .: "eros-lists"
+  parseJSON _          = mzero
+
+-- |This is the output data type. I will make an instance of ToJSON
+-- for this data type. Again, at the start, only JSON input and output
+-- is existent.
+data Output = Output { elScore :: [(ErosList, Score)] }
+
+-- |Pretty self-explanatory
+instance ToJSON ErosList where
+  toJSON el = case erosNameByList el of
+                Just nom -> toJSON nom
+                Nothing  -> "There's probably a bug in the JSON parsing \
+                            \library Eros uses. You should file a bug \
+                            \report at https://github.com/pharpend/eros/issues."
+
+-- |Pretty self-explanatory
+instance ToJSON (ErosList, Score) where
+  toJSON (el, sc) = object [ "eros-list" .= el
+                           , "score"     .= sc
+                           ]
+
+-- |Pretty self-explanatory
+instance ToJSON Output where
+  toJSON (Output elm) = toJSON elm
+
+-- |It's convenient to think of Scores as Scores, although, they are
+-- truly ints.
+type Score = Int
diff --git a/src/Main.lhs b/src/Main.lhs
new file mode 100644
--- /dev/null
+++ b/src/Main.lhs
@@ -0,0 +1,78 @@
+|This is the main module for the eros client. This is not the meat &
+potatoes of the program, but this is the bread & butter.
+
+> module Main where
+
+
+So, here are our imports. I would like to only have IO inputs, however
+the import of 'Data.Aeson' is needed in order to keep the
+'Erosc.Processor' module pure.
+
+Essentially, I was faced with either making this module be tainted by
+purity, or have the other module be pure.
+
+My qualified imports are a bit obnoxious. Even though they aren't
+needed, I find that using qualified names makes the code a bit less
+confusing. That is, @LzByte.hGetContents@ is a lot more informative
+than just @hGetContents@.
+
+> import           Data.Aeson             as Aeson
+> import qualified Data.ByteString.Lazy   as LzByte
+> import           Erosc.Processor        as Erosc
+> import qualified System.IO              as StdIO
+
+
+|Eventually, I'll need this data type when I use command line
+arguments. For the moment, it's just a dummy type. So, enjoy it.
+
+> data EroscOpts = EroscOpts
+
+|So, this is the main function. Whoop de doo.  It sends the contents
+of 'StdIO.stdin' to runBtStr.
+
+Eventually, I'll add in command line argument parsing, and then we'll
+have a use for the 'EroscOptions' type.
+
+> main :: IO ()
+> main = runBtStr =<< LzByte.hGetContents StdIO.stdin
+
+|This function takes the input (presumably 'StdIO.stdin'), and tries
+to decode it.
+
+If it successfully decodes the input into the 'Erosc.Input' type,
+it sends the newfound decoded input to 'runInput', which sends it to
+the processor.
+
+If it can't, the program will throw a tantrum and shit itself.
+
+> runBtStr :: LzByte.ByteString -> IO ()
+> runBtStr inputBt = do
+>   let eitherJson = (Aeson.eitherDecode inputBt) :: Either String Erosc.Input
+>   case eitherJson of
+>     Left msg      -> fail msg
+>     Right ecInput -> runInput ecInput
+
+
+There is an astonishing quantity of bureaucracy in this program. You
+have to go through like 5 functions before you get to a function that
+actually does something useful.
+
+|Okay, so, we're getting closer to the part of the program that
+actually does stuff (or further away, depending on the location from
+whence you come).
+
+'runInput' takes the 'Erosc.Input' object (I do hate that word), and
+sends it to some function in 'Erosc' that actually mutates the
+data. Well, it doesn't mutate it, obviously, because this is Haskell,
+but you get the idea.
+
+@result@ needs to be '(<-)'d because 'Erosc.processInput' needs to
+read the phraselist JSON file. This is a result of poor library design
+on my part. I will fix this in a future release.
+
+> runInput :: Erosc.Input -> IO ()
+> runInput ipt = do
+>   result <- Erosc.processInput ipt
+>   let jsonText = Erosc.encode result
+>   LzByte.hPutStr StdIO.stdout jsonText
+
