diff --git a/gql/parser.go b/gql/parser.go
index 39f5ddc7c29d4f27368b07ea349a7c21e7411d73..7892595072a48b3b1220892a9618df0d4f24a917 100644
--- a/gql/parser.go
+++ b/gql/parser.go
@@ -36,6 +36,11 @@ type GraphQuery struct {
 	Children []*GraphQuery
 }
 
+type Mutation struct {
+	Set string
+	Del string
+}
+
 func run(l *lex.Lexer) {
 	for state := lexText; state != nil; {
 		state = state(l)
@@ -43,10 +48,11 @@ func run(l *lex.Lexer) {
 	close(l.Items) // No more tokens.
 }
 
-func Parse(input string) (gq *GraphQuery, rerr error) {
+func Parse(input string) (gq *GraphQuery, mu *Mutation, rerr error) {
 	l := lex.NewLexer(input)
 	go run(l)
 
+	mu = nil
 	gq = nil
 	for item := range l.Items {
 		if item.Typ == itemText {
@@ -54,7 +60,13 @@ func Parse(input string) (gq *GraphQuery, rerr error) {
 		}
 		if item.Typ == itemOpType {
 			if item.Val == "mutation" {
-				return nil, errors.New("Mutations not supported")
+				if mu != nil {
+					return nil, nil, errors.New("Only one mutation block allowed.")
+				}
+				mu, rerr = getMutation(l)
+				if rerr != nil {
+					return nil, nil, rerr
+				}
 			}
 		}
 		if item.Typ == itemLeftCurl {
@@ -62,16 +74,71 @@ func Parse(input string) (gq *GraphQuery, rerr error) {
 				gq, rerr = getRoot(l)
 				if rerr != nil {
 					x.Err(glog, rerr).Error("While retrieving subgraph root")
-					return nil, rerr
+					return nil, nil, rerr
 				}
 			} else {
 				if err := godeep(l, gq); err != nil {
-					return gq, err
+					return nil, nil, err
 				}
 			}
 		}
 	}
-	return gq, nil
+	return gq, mu, nil
+}
+
+func getMutation(l *lex.Lexer) (mu *Mutation, rerr error) {
+	for item := range l.Items {
+		if item.Typ == itemText {
+			continue
+		}
+		if item.Typ == itemLeftCurl {
+			mu = new(Mutation)
+		}
+		if item.Typ == itemRightCurl {
+			return mu, nil
+		}
+		if item.Typ == itemMutationOp {
+			if err := parseMutationOp(l, item.Val, mu); err != nil {
+				return nil, err
+			}
+		}
+	}
+	return nil, errors.New("Invalid mutation.")
+}
+
+func parseMutationOp(l *lex.Lexer, op string, mu *Mutation) error {
+	if mu == nil {
+		return errors.New("Mutation is nil.")
+	}
+
+	parse := false
+	for item := range l.Items {
+		if item.Typ == itemText {
+			continue
+		}
+		if item.Typ == itemLeftCurl {
+			if parse {
+				return errors.New("Too many left curls in set mutation.")
+			}
+			parse = true
+		}
+		if item.Typ == itemMutationContent {
+			if !parse {
+				return errors.New("Mutation syntax invalid.")
+			}
+			if op == "set" {
+				mu.Set = item.Val
+			} else if op == "delete" {
+				mu.Del = item.Val
+			} else {
+				return errors.New("Invalid mutation operation.")
+			}
+		}
+		if item.Typ == itemRightCurl {
+			return nil
+		}
+	}
+	return errors.New("Invalid mutation formatting.")
 }
 
 func getRoot(l *lex.Lexer) (gq *GraphQuery, rerr error) {
diff --git a/gql/parser_test.go b/gql/parser_test.go
index d8be58c5c029197a6605607154efd9194ee3126d..c1c00ddaa60fe574e6f70608c19e10ca7825dbfb 100644
--- a/gql/parser_test.go
+++ b/gql/parser_test.go
@@ -18,6 +18,7 @@ package gql
 
 import (
 	"fmt"
+	"strings"
 	"testing"
 )
 
@@ -41,7 +42,7 @@ func TestParse(t *testing.T) {
 	}
 `
 
-	gq, err := Parse(query)
+	gq, _, err := Parse(query)
 	if err != nil {
 		t.Error(err)
 	}
@@ -82,7 +83,7 @@ func TestParseXid(t *testing.T) {
 			type.object.name
 		}
 	}`
-	gq, err := Parse(query)
+	gq, _, err := Parse(query)
 	if err != nil {
 		t.Error(err)
 		return
@@ -99,22 +100,6 @@ func TestParseXid(t *testing.T) {
 	}
 }
 
-func TestParse_error1(t *testing.T) {
-	query := `
-		mutation {
-			me(_uid_:0x0a) {
-				name
-			}
-		}
-	`
-	var err error
-	_, err = Parse(query)
-	t.Log(err)
-	if err == nil {
-		t.Error("Expected error")
-	}
-}
-
 func TestParse_error2(t *testing.T) {
 	query := `
 		query {
@@ -124,7 +109,7 @@ func TestParse_error2(t *testing.T) {
 		}
 	`
 	var err error
-	_, err = Parse(query)
+	_, _, err = Parse(query)
 	t.Log(err)
 	if err == nil {
 		t.Error("Expected error")
@@ -141,7 +126,7 @@ func TestParse_pass1(t *testing.T) {
 			}
 		}
 	`
-	gq, err := Parse(query)
+	gq, _, err := Parse(query)
 	if err != nil {
 		t.Error(err)
 	}
@@ -168,7 +153,7 @@ func TestParse_block(t *testing.T) {
 			}
 		}
 	`
-	gq, err := Parse(query)
+	gq, _, err := Parse(query)
 	if err != nil {
 		t.Error(err)
 	}
@@ -179,3 +164,134 @@ func TestParse_block(t *testing.T) {
 		t.Error(err)
 	}
 }
+
+func TestParseMutation(t *testing.T) {
+	query := `
+		mutation {
+			set {
+				<name> <is> <something> .
+				<hometown> <is> <san francisco> .
+			}
+			delete {
+				<name> <is> <something-else> .
+			}
+		}
+	`
+	_, mu, err := Parse(query)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if strings.Index(mu.Set, "<name> <is> <something> .") == -1 {
+		t.Error("Unable to find mutation content.")
+	}
+	if strings.Index(mu.Set, "<hometown> <is> <san francisco> .") == -1 {
+		t.Error("Unable to find mutation content.")
+	}
+	if strings.Index(mu.Del, "<name> <is> <something-else> .") == -1 {
+		t.Error("Unable to find mutation content.")
+	}
+}
+
+func TestParseMutation_error(t *testing.T) {
+	query := `
+		mutation {
+			set {
+				<name> <is> <something> .
+				<hometown> <is> <san francisco> .
+			}
+			delete {
+				<name> <is> <something-else> .
+		}
+	`
+	_, _, err := Parse(query)
+	if err == nil {
+		t.Error(err)
+		return
+	}
+	t.Log(err)
+}
+
+func TestParseMutation_error2(t *testing.T) {
+	query := `
+		mutation {
+			set {
+				<name> <is> <something> .
+				<hometown> <is> <san francisco> .
+			}
+			delete {
+				<name> <is> <something-else> .
+			}
+		}
+		mutation {
+			set {
+				another one?
+			}
+		}
+
+	`
+	_, _, err := Parse(query)
+	if err == nil {
+		t.Error(err)
+		return
+	}
+	t.Log(err)
+}
+
+func TestParseMutationAndQuery(t *testing.T) {
+	query := `
+		mutation {
+			set {
+				<name> <is> <something> .
+				<hometown> <is> <san francisco> .
+			}
+			delete {
+				<name> <is> <something-else> .
+			}
+		}
+		query {
+			me(_xid_: tomhanks) {
+				name
+				hometown
+			}
+		}
+	`
+	gq, mu, err := Parse(query)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	if mu == nil {
+		t.Error("mutation is nil")
+		return
+	}
+	if strings.Index(mu.Set, "<name> <is> <something> .") == -1 {
+		t.Error("Unable to find mutation content.")
+	}
+	if strings.Index(mu.Set, "<hometown> <is> <san francisco> .") == -1 {
+		t.Error("Unable to find mutation content.")
+	}
+	if strings.Index(mu.Del, "<name> <is> <something-else> .") == -1 {
+		t.Error("Unable to find mutation content.")
+	}
+
+	if gq == nil {
+		t.Error("subgraph is nil")
+		return
+	}
+	if gq.XID != "tomhanks" {
+		t.Error("Expected: tomhanks. Got: %v", gq.XID)
+		return
+	}
+	if len(gq.Children) != 2 {
+		t.Errorf("Expected 2 children. Got: %v", len(gq.Children))
+		return
+	}
+	if err := checkAttr(gq.Children[0], "name"); err != nil {
+		t.Error(err)
+	}
+	if err := checkAttr(gq.Children[1], "hometown"); err != nil {
+		t.Error(err)
+	}
+}
diff --git a/gql/state.go b/gql/state.go
index 9313671b021fc2f8ff01e63c7732f232a80c6226..2370108d8f51fd21e3b8f9654f3b4756d0750b22 100644
--- a/gql/state.go
+++ b/gql/state.go
@@ -19,22 +19,26 @@ package gql
 import "github.com/dgraph-io/dgraph/lex"
 
 const (
-	leftCurl  = '{'
-	rightCurl = '}'
+	leftCurl     = '{'
+	rightCurl    = '}'
+	queryMode    = 1
+	mutationMode = 2
 )
 
 const (
-	itemText       lex.ItemType = 5 + iota // plain text
-	itemLeftCurl                           // left curly bracket
-	itemRightCurl                          // right curly bracket
-	itemComment                            // comment
-	itemName                               // [9] names
-	itemOpType                             // operation type
-	itemString                             // quoted string
-	itemLeftRound                          // left round bracket
-	itemRightRound                         // right round bracket
-	itemArgName                            // argument name
-	itemArgVal                             // argument val
+	itemText            lex.ItemType = 5 + iota // plain text
+	itemLeftCurl                                // left curly bracket
+	itemRightCurl                               // right curly bracket
+	itemComment                                 // comment
+	itemName                                    // [9] names
+	itemOpType                                  // operation type
+	itemString                                  // quoted string
+	itemLeftRound                               // left round bracket
+	itemRightRound                              // right round bracket
+	itemArgName                                 // argument name
+	itemArgVal                                  // argument val
+	itemMutationOp                              // mutation operation
+	itemMutationContent                         // mutation content
 )
 
 func lexText(l *lex.Lexer) lex.StateFn {
@@ -47,7 +51,11 @@ Loop:
 			l.Next()         // advance one to get back to where we saw leftCurl.
 			l.Depth += 1     // one level down.
 			l.Emit(itemLeftCurl)
-			return lexInside // we're in.
+			if l.Mode == mutationMode {
+				return lexInsideMutation
+			} else {
+				return lexInside
+			}
 
 		case r == rightCurl:
 			return l.Errorf("Too many right characters")
@@ -79,7 +87,7 @@ func lexInside(l *lex.Lexer) lex.StateFn {
 			l.Depth += 1
 			l.Emit(itemLeftCurl)
 		case r == lex.EOF:
-			return l.Errorf("unclosed action")
+			return l.Errorf("Unclosed action")
 		case isSpace(r) || isEndOfLine(r) || r == ',':
 			l.Ignore()
 		case isNameBegin(r):
@@ -128,6 +136,64 @@ func lexComment(l *lex.Lexer) lex.StateFn {
 	return nil // Stop the run loop.
 }
 
+func lexInsideMutation(l *lex.Lexer) lex.StateFn {
+	for {
+		switch r := l.Next(); {
+		case r == rightCurl:
+			l.Depth -= 1
+			l.Emit(itemRightCurl)
+			if l.Depth == 0 {
+				return lexText
+			}
+		case r == leftCurl:
+			l.Depth += 1
+			l.Emit(itemLeftCurl)
+			if l.Depth >= 2 {
+				return lexTextMutation
+			}
+		case r == lex.EOF:
+			return l.Errorf("Unclosed mutation action")
+		case isSpace(r) || isEndOfLine(r):
+			l.Ignore()
+		case isNameBegin(r):
+			return lexNameMutation
+		default:
+			return l.Errorf("Unrecognized character in lexInsideMutation: %#U", r)
+		}
+	}
+}
+
+func lexNameMutation(l *lex.Lexer) lex.StateFn {
+	for {
+		// The caller already checked isNameBegin, and absorbed one rune.
+		r := l.Next()
+		if isNameBegin(r) {
+			continue
+		}
+		l.Backup()
+		l.Emit(itemMutationOp)
+		break
+	}
+	return lexInsideMutation
+}
+
+func lexTextMutation(l *lex.Lexer) lex.StateFn {
+	for {
+		r := l.Next()
+		if r == lex.EOF {
+			return l.Errorf("Unclosed mutation text")
+		}
+		if r != rightCurl {
+			// Absorb everything until we find '}'.
+			continue
+		}
+		l.Backup()
+		l.Emit(itemMutationContent)
+		break
+	}
+	return lexInsideMutation
+}
+
 func lexOperationType(l *lex.Lexer) lex.StateFn {
 	for {
 		r := l.Next()
@@ -136,8 +202,13 @@ func lexOperationType(l *lex.Lexer) lex.StateFn {
 		}
 		l.Backup()
 		word := l.Input[l.Start:l.Pos]
-		if word == "query" || word == "mutation" {
+		if word == "mutation" {
+			l.Emit(itemOpType)
+			l.Mode = mutationMode
+
+		} else if word == "query" {
 			l.Emit(itemOpType)
+			l.Mode = queryMode
 		}
 		break
 	}
diff --git a/gql/state_test.go b/gql/state_test.go
index a1ce13d61805ea6f4c56a8acac731792f76c2da8..69ff92730141c52d6282dc956dd4dc359fc9bd39 100644
--- a/gql/state_test.go
+++ b/gql/state_test.go
@@ -17,7 +17,6 @@
 package gql
 
 import (
-	"fmt"
 	"testing"
 
 	"github.com/dgraph-io/dgraph/lex"
@@ -25,7 +24,7 @@ import (
 
 func TestNewLexer(t *testing.T) {
 	input := `
-	mutation {
+	query {
 		me( id: 10, xid: rick ) {
 			name0 # my name
 			_city, # 0what would fail lex.
@@ -38,6 +37,56 @@ func TestNewLexer(t *testing.T) {
 	l := lex.NewLexer(input)
 	go run(l)
 	for item := range l.Items {
-		fmt.Println(item.String())
+		if item.Typ == lex.ItemError {
+			t.Error(item.String())
+		}
+		t.Log(item.String())
+	}
+}
+
+func TestNewLexerMutation(t *testing.T) {
+	input := `
+	mutation {
+		set {
+			What is <this> .
+			Why is this #!!?
+			How is this?
+		}
+		delete {
+			Why is this
+		}
+	}
+	query {
+		me(xid: rick) {
+			_city
+		}
+	}`
+	l := lex.NewLexer(input)
+	go run(l)
+	for item := range l.Items {
+		if item.Typ == lex.ItemError {
+			t.Error(item.String())
+		}
+		t.Log(item.String())
+	}
+}
+
+func TestAbruptMutation(t *testing.T) {
+	input := `
+	mutation {
+		set {
+			What is <this> .
+			Why is this #!!?
+			How is this?
+	}`
+	l := lex.NewLexer(input)
+	go run(l)
+	var typ lex.ItemType
+	for item := range l.Items {
+		t.Log(item.String())
+		typ = item.Typ
+	}
+	if typ != lex.ItemError {
+		t.Error("This should fail.")
 	}
 }
diff --git a/lex/lexer.go b/lex/lexer.go
index 2b4b3cabd56b4b5e1f2df588a1f6a0f37da7bd03..9027e11044c0e08449a18179af0902d37abe3702 100644
--- a/lex/lexer.go
+++ b/lex/lexer.go
@@ -63,6 +63,7 @@ type Lexer struct {
 	Width int       // width of last rune read from input.
 	Items chan item // channel of scanned items.
 	Depth int       // nesting of {}
+	Mode  int       // mode based on information so far.
 }
 
 func NewLexer(input string) *Lexer {
diff --git a/query/query_test.go b/query/query_test.go
index c11f2b1aadc82909754b429757a1b9fc8856a8a7..44bbbd07c93bf4403f9ee393bdb913b7f6dcf999 100644
--- a/query/query_test.go
+++ b/query/query_test.go
@@ -190,7 +190,7 @@ func TestProcessGraph(t *testing.T) {
 			}
 		}
 	`
-	gq, err := gql.Parse(query)
+	gq, _, err := gql.Parse(query)
 	if err != nil {
 		t.Error(err)
 	}
@@ -282,7 +282,7 @@ func TestToJson(t *testing.T) {
 		}
 	`
 
-	gq, err := gql.Parse(query)
+	gq, _, err := gql.Parse(query)
 	if err != nil {
 		t.Error(err)
 	}
diff --git a/server/main.go b/server/main.go
index 5085ff9fdef228fa478b87c3cd792cd117d2008f..11c240aa6ed1d08e2132f0e86ab63faac5e92bd4 100644
--- a/server/main.go
+++ b/server/main.go
@@ -72,7 +72,7 @@ func queryHandler(w http.ResponseWriter, r *http.Request) {
 	}
 
 	glog.WithField("q", string(q)).Debug("Query received.")
-	gq, err := gql.Parse(string(q))
+	gq, _, err := gql.Parse(string(q))
 	if err != nil {
 		x.Err(glog, err).Error("While parsing query")
 		x.SetStatus(w, x.E_INVALID_REQUEST, err.Error())
diff --git a/server/main_test.go b/server/main_test.go
index 0c384f160c57d5b934f2ee43921a92b82295f601..010195130e0932fbebc2c57546c2476276643fe9 100644
--- a/server/main_test.go
+++ b/server/main_test.go
@@ -88,7 +88,7 @@ func TestQuery(t *testing.T) {
 	defer closeAll(dir1, dir2, clog)
 
 	// Parse GQL into internal query representation.
-	gq, err := gql.Parse(q0)
+	gq, _, err := gql.Parse(q0)
 	if err != nil {
 		t.Error(err)
 		return
@@ -184,7 +184,7 @@ func BenchmarkQuery(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		gq, err := gql.Parse(q1)
+		gq, _, err := gql.Parse(q1)
 		if err != nil {
 			b.Error(err)
 			return