diff --git a/doc/manual-src/en/aria2c.rst b/doc/manual-src/en/aria2c.rst
index ef86bd93..d5ef8485 100644
--- a/doc/manual-src/en/aria2c.rst
+++ b/doc/manual-src/en/aria2c.rst
@@ -2228,6 +2228,10 @@ to provide the token as the first parameter as described above.
   interface. Therefore it is recommended to prefer Batch or `system.multicall`
   requests when appropriate.
 
+  `system.listMethods` can be executed without token.  Since it just
+  returns the all available methods, and does not alter anything, it
+  is safe without secret token.
+
 Methods
 ~~~~~~~
 
@@ -3429,6 +3433,36 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
     >>> tuple(r)
     ('2089b05ecca3d829', 'd2703803b52216d1')
 
+.. function:: system.listMethods()
+
+  This method returns the all available RPC methods in an array of
+  string.  Unlike other methods, this method does not require secret
+  token.  This is safe because this method jsut returns the available
+  method names.
+
+  **JSON-RPC Example**
+  ::
+
+    >>> import urllib2, json
+    >>> from pprint import pprint
+    >>> jsonreq = json.dumps({'jsonrpc':'2.0', 'id':'qwer',
+    ...                       'method':'system.listMethods'})
+    >>> c = urllib2.urlopen('http://localhost:6800/jsonrpc', jsonreq)
+    >>> pprint(json.loads(c.read()))
+    {u'id': u'qwer',
+     u'jsonrpc': u'2.0',
+     u'result': [u'aria2.addUri',
+                 u'aria2.addTorrent',
+    ...
+
+  **XML-RPC Example**
+  ::
+
+    >>> import xmlrpclib
+    >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
+    >>> s.system.listMethods()
+    ['aria2.addUri', 'aria2.addTorrent', ...
+
 Error Handling
 ~~~~~~~~~~~~~~
 
diff --git a/src/RpcMethodFactory.cc b/src/RpcMethodFactory.cc
index 1e505cf5..2b1ce98c 100644
--- a/src/RpcMethodFactory.cc
+++ b/src/RpcMethodFactory.cc
@@ -49,6 +49,30 @@ namespace {
 std::unique_ptr<RpcMethod> noSuchRpcMethod;
 } // namespace
 
+namespace {
+std::vector<std::string> rpcMethodNames = {
+    "aria2.addUri",
+#ifdef ENABLE_BITTORRENT
+    "aria2.addTorrent", "aria2.getPeers",
+#endif // ENABLE_BITTORRENT
+#ifdef ENABLE_METALINK
+    "aria2.addMetalink",
+#endif // ENABLE_METALINK
+    "aria2.remove", "aria2.pause", "aria2.forcePause", "aria2.pauseAll",
+    "aria2.forcePauseAll", "aria2.unpause", "aria2.unpauseAll",
+    "aria2.forceRemove", "aria2.changePosition", "aria2.tellStatus",
+    "aria2.getUris", "aria2.getFiles", "aria2.getServers", "aria2.tellActive",
+    "aria2.tellWaiting", "aria2.tellStopped", "aria2.getOption",
+    "aria2.changeUri", "aria2.changeOption", "aria2.getGlobalOption",
+    "aria2.changeGlobalOption", "aria2.purgeDownloadResult",
+    "aria2.removeDownloadResult", "aria2.getVersion", "aria2.getSessionInfo",
+    "aria2.shutdown", "aria2.forceShutdown", "aria2.getGlobalStat",
+    "aria2.saveSession", "system.multicall", "system.listMethods",
+};
+} // namespace
+
+const std::vector<std::string>& allMethodNames() { return rpcMethodNames; }
+
 namespace {
 std::unique_ptr<RpcMethod> createMethod(const std::string& methodName)
 {
@@ -192,6 +216,10 @@ std::unique_ptr<RpcMethod> createMethod(const std::string& methodName)
     return make_unique<SystemMulticallRpcMethod>();
   }
 
+  if (methodName == SystemListMethodsRpcMethod::getMethodName()) {
+    return make_unique<SystemListMethodsRpcMethod>();
+  }
+
   return nullptr;
 }
 } // namespace
diff --git a/src/RpcMethodFactory.h b/src/RpcMethodFactory.h
index 07f83c58..ebd4a479 100644
--- a/src/RpcMethodFactory.h
+++ b/src/RpcMethodFactory.h
@@ -39,6 +39,7 @@
 
 #include <string>
 #include <memory>
+#include <vector>
 
 namespace aria2 {
 
@@ -46,6 +47,8 @@ namespace rpc {
 
 class RpcMethod;
 
+const std::vector<std::string>& allMethodNames();
+
 RpcMethod* getMethod(const std::string& methodName);
 
 } // namespace rpc
diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc
index 7b1b8fbd..8dad61c3 100644
--- a/src/RpcMethodImpl.cc
+++ b/src/RpcMethodImpl.cc
@@ -1429,6 +1429,24 @@ RpcResponse SystemMulticallRpcMethod::execute(RpcRequest req, DownloadEngine *e)
   }
 }
 
+std::unique_ptr<ValueBase> SystemListMethodsRpcMethod::process
+(const RpcRequest&req, DownloadEngine *e) {
+  auto list = List::g();
+  for (auto &s : allMethodNames()) {
+    list->append(s);
+  }
+
+  return list;
+}
+
+RpcResponse SystemListMethodsRpcMethod::execute(RpcRequest req,
+                                                DownloadEngine* e)
+{
+  auto r = process(req, e);
+  return RpcResponse(0, RpcResponse::AUTHORIZED, std::move(r),
+                     std::move(req.id));
+}
+
 std::unique_ptr<ValueBase> NoSuchMethodRpcMethod::process
 (const RpcRequest& req, DownloadEngine* e)
 {
diff --git a/src/RpcMethodImpl.h b/src/RpcMethodImpl.h
index 442303fe..a5f562b1 100644
--- a/src/RpcMethodImpl.h
+++ b/src/RpcMethodImpl.h
@@ -596,6 +596,17 @@ public:
   }
 };
 
+class SystemListMethodsRpcMethod : public RpcMethod {
+protected:
+  virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
+                                             DownloadEngine* e) CXX11_OVERRIDE;
+
+public:
+  virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE;
+
+  static const char* getMethodName() { return "system.listMethods"; }
+};
+
 class NoSuchMethodRpcMethod:public RpcMethod {
 protected:
   virtual std::unique_ptr<ValueBase> process
diff --git a/test/RpcMethodTest.cc b/test/RpcMethodTest.cc
index eddc1651..e975dd09 100644
--- a/test/RpcMethodTest.cc
+++ b/test/RpcMethodTest.cc
@@ -20,6 +20,7 @@
 #include "array_fun.h"
 #include "download_helper.h"
 #include "FileEntry.h"
+#include "RpcMethodFactory.h"
 #ifdef ENABLE_BITTORRENT
 # include "BtRegistry.h"
 # include "BtRuntime.h"
@@ -78,6 +79,7 @@ class RpcMethodTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testPause);
   CPPUNIT_TEST(testSystemMulticall);
   CPPUNIT_TEST(testSystemMulticall_fail);
+  CPPUNIT_TEST(testSystemListMethods);
   CPPUNIT_TEST_SUITE_END();
 private:
   std::shared_ptr<DownloadEngine> e_;
@@ -142,6 +144,7 @@ public:
   void testPause();
   void testSystemMulticall();
   void testSystemMulticall_fail();
+  void testSystemListMethods();
 };
 
 
@@ -1363,6 +1366,24 @@ void RpcMethodTest::testSystemMulticall_fail()
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
 
+void RpcMethodTest::testSystemListMethods()
+{
+  SystemListMethodsRpcMethod m;
+  auto res = m.execute(createReq("system.listMethods"), e_.get());
+  CPPUNIT_ASSERT_EQUAL(0, res.code);
+
+  const auto resParams = downcast<List>(res.param);
+  auto &allNames = allMethodNames();
+
+  CPPUNIT_ASSERT_EQUAL(allNames.size(), resParams->size());
+
+  for (size_t i = 0; i < allNames.size(); ++i) {
+    const auto s = downcast<String>(resParams->get(i));
+    CPPUNIT_ASSERT(s);
+    CPPUNIT_ASSERT_EQUAL(allNames[i], s->s());
+  }
+}
+
 } // namespace rpc
 
 } // namespace aria2