diff --git a/src/query/__tests__/RelayQueryRoot-test.js b/src/query/__tests__/RelayQueryRoot-test.js
index fa1e2c0bd9007..0ccc9406afcc3 100644
--- a/src/query/__tests__/RelayQueryRoot-test.js
+++ b/src/query/__tests__/RelayQueryRoot-test.js
@@ -159,7 +159,7 @@ describe('RelayQueryRoot', () => {
     expect(me.getIdentifyingArg()).toEqual(undefined);
 
     expect(usernames.getIdentifyingArg()).toEqual(
-      {name: 'names', value: 'mroch'}
+      {name: 'names', type: '[String!]!', value: 'mroch'}
     );
 
     expect(getNode(Relay.QL`
diff --git a/src/query/__tests__/callsToGraphQL-test.js b/src/query/__tests__/callsToGraphQL-test.js
index bb047d14b7469..fb5db407adf11 100644
--- a/src/query/__tests__/callsToGraphQL-test.js
+++ b/src/query/__tests__/callsToGraphQL-test.js
@@ -22,9 +22,10 @@ describe('callsToGraphQL', function() {
   it('converts array calls with null values', () => {
     const relayCalls = [{
       name: 'size',
+      type: 'Int',
       value: null,
     }];
-    const graphqlCalls = [RelayTestUtils.createCall('size', null)];
+    const graphqlCalls = [RelayTestUtils.createCall('size', null, 'Int')];
     expect(callsFromGraphQL(graphqlCalls)).toEqual(relayCalls);
     expect(callsToGraphQL(relayCalls)).toEqual(graphqlCalls);
   });
@@ -32,9 +33,10 @@ describe('callsToGraphQL', function() {
   it('converts array calls without values', () => {
     const relayCalls = [{
       name: 'size',
+      type: '[Int]',
       value: [],
     }];
-    const graphqlCalls = [RelayTestUtils.createCall('size', [])];
+    const graphqlCalls = [RelayTestUtils.createCall('size', [], '[Int]')];
     expect(callsFromGraphQL(graphqlCalls)).toEqual(relayCalls);
     expect(callsToGraphQL(relayCalls)).toEqual(graphqlCalls);
   });
@@ -42,9 +44,10 @@ describe('callsToGraphQL', function() {
   it('converts calls with array values', () => {
     const relayCalls = [{
       name: 'size',
+      type: '[Int]',
       value: [32, 64],
     }];
-    const graphqlCalls = [RelayTestUtils.createCall('size', [32, 64])];
+    const graphqlCalls = [RelayTestUtils.createCall('size', [32, 64], '[Int]')];
     expect(callsFromGraphQL(graphqlCalls)).toEqual(relayCalls);
     expect(callsToGraphQL(relayCalls)).toEqual(graphqlCalls);
   });
@@ -52,9 +55,10 @@ describe('callsToGraphQL', function() {
   it('converts singular calls with null values', () => {
     const relayCalls = [{
       name: 'size',
+      type: 'Int',
       value: 32,
     }];
-    const graphqlCalls = [RelayTestUtils.createCall('size', 32)];
+    const graphqlCalls = [RelayTestUtils.createCall('size', 32, 'Int')];
     expect(callsFromGraphQL(graphqlCalls)).toEqual(relayCalls);
     expect(callsToGraphQL(relayCalls)).toEqual(graphqlCalls);
   });
diff --git a/src/query/callsFromGraphQL.js b/src/query/callsFromGraphQL.js
index a175260a49fab..fdfee595f1e0b 100644
--- a/src/query/callsFromGraphQL.js
+++ b/src/query/callsFromGraphQL.js
@@ -25,6 +25,9 @@ const invariant = require('invariant');
 
 type CallOrDirective = {
   name: string,
+  metadata?: {
+    type?: ?string,
+  },
   value: ?ConcreteValue,
 };
 
@@ -53,7 +56,12 @@ function callsFromGraphQL(
         value = getCallValue(value, variables);
       }
     }
-    orderedCalls.push({name: callOrDirective.name, value});
+    const {metadata, name} = callOrDirective;
+    const orderedCall: Call = {name, value};
+    if (metadata && metadata.type) {
+      orderedCall.type = metadata.type;
+    }
+    orderedCalls.push(orderedCall);
   }
   return orderedCalls;
 }
diff --git a/src/query/callsToGraphQL.js b/src/query/callsToGraphQL.js
index e029d24884588..c4efb7d31cce8 100644
--- a/src/query/callsToGraphQL.js
+++ b/src/query/callsToGraphQL.js
@@ -22,14 +22,14 @@ const QueryBuilder = require('QueryBuilder');
  * Convert from plain object `{name, value}` calls to GraphQL call nodes.
  */
 function callsToGraphQL(calls: Array<Call>): Array<ConcreteCall> {
-  return calls.map(({name, value}) => {
+  return calls.map(({name, type, value}) => {
     let concreteValue = null;
     if (Array.isArray(value)) {
       concreteValue = value.map(QueryBuilder.createCallValue);
     } else if (value != null)  {
       concreteValue = QueryBuilder.createCallValue(value);
     }
-    return QueryBuilder.createCall(name, concreteValue);
+    return QueryBuilder.createCall(name, concreteValue, type);
   });
 }
 
diff --git a/src/tools/__mocks__/RelayTestUtils.js b/src/tools/__mocks__/RelayTestUtils.js
index 15d6c8304336e..be3e3e1fe7dda 100644
--- a/src/tools/__mocks__/RelayTestUtils.js
+++ b/src/tools/__mocks__/RelayTestUtils.js
@@ -121,7 +121,7 @@ const RelayTestUtils = {
     return reference;
   },
 
-  createCall(name, value) {
+  createCall(name, value, type) {
     const QueryBuilder = require('QueryBuilder');
 
     if (Array.isArray(value)) {
@@ -129,7 +129,7 @@ const RelayTestUtils = {
     } else if (value != null) {
       value = QueryBuilder.createCallValue(value);
     }
-    return QueryBuilder.createCall(name, value);
+    return QueryBuilder.createCall(name, value, type);
   },
 
   createContainerFragment(fragment) {