diff --git a/client/stylesheets/base.less b/client/stylesheets/base.less
index d0ebc85734003d2ebd504c83758be28f25946950..ea8e2c77dea9ab63963ecd7a2dd6df1083af3ee4 100644
--- a/client/stylesheets/base.less
+++ b/client/stylesheets/base.less
@@ -2259,6 +2259,9 @@ a.github-fork {
 	.popup-user-status-busy {
 		background-color: @status-busy;
 	}
+	.popup-slash-command-description {
+		float: right;
+	}
 	.message-form {
 		> div {
 			position: relative;
diff --git a/client/views/app/messagePopup.coffee b/client/views/app/messagePopup.coffee
index 7fc9a96c6c839d50fa87f5bca5928dc405f6ba82..c47cf859200a94d3f1931be43c48e0ed4c3e37cc 100644
--- a/client/views/app/messagePopup.coffee
+++ b/client/views/app/messagePopup.coffee
@@ -37,11 +37,16 @@ Template.messagePopup.onCreated ->
 
 	template.trigger = val(template.data.trigger, '@')
 
+	template.triggerAnywhere = val(template.data.triggerAnywhere, true)
+
 	template.prefix = val(template.data.prefix, template.trigger)
 
 	template.suffix = val(template.data.suffix, ' ')
 
-	template.matchSelectorRegex = val(template.data.matchSelectorRegex, new RegExp "(?:^| )#{template.trigger}[A-Za-z0-9-_.]*$")
+	if template.triggerAnywhere is true
+		template.matchSelectorRegex = val(template.data.matchSelectorRegex, new RegExp "(?:^| )#{template.trigger}[A-Za-z0-9-_.]*$")
+	else
+		template.matchSelectorRegex = val(template.data.matchSelectorRegex, new RegExp "(?:^)#{template.trigger}[A-Za-z0-9-_.]*$")
 
 	template.selectorRegex = val(template.data.selectorRegex, new RegExp "#{template.trigger}([A-Za-z0-9-_.]*)$")
 
diff --git a/client/views/app/messagePopupConfig.coffee b/client/views/app/messagePopupConfig.coffee
index a99983297b42f2a616af481ae00f38ef513e90f1..268d5b2a0d9b098d46df07267a7f54a607000ff0 100644
--- a/client/views/app/messagePopupConfig.coffee
+++ b/client/views/app/messagePopupConfig.coffee
@@ -60,6 +60,36 @@ Template.messagePopupConfig.helpers
 
 		return config
 
+	popupSlashCommandsConfig: ->
+		self = this
+		template = Template.instance()
+
+		config =
+			title: 'Commands'
+			collection: RocketChat.slashCommands.commands
+			trigger: '/'
+			triggerAnywhere: false
+			template: 'messagePopupSlashCommand'
+			getInput: self.getInput
+			getFilter: (collection, filter) ->
+				commands = []
+				for command, item of collection
+					if command.indexOf(filter) > -1
+						commands.push
+							_id: command
+							params: item.params
+							description: item.description
+
+					if commands.length > 10
+						break
+
+				commands = commands.sort (a, b) ->
+					return a._id > b._id
+
+				return commands
+
+		return config
+
 	emojiEnabled: ->
 		return RocketChat.emoji?
 
diff --git a/client/views/app/messagePopupConfig.html b/client/views/app/messagePopupConfig.html
index 8e69998e5b1424abec44e872563b4bf5e93a1d2a..3f0cb17d314fc5db1e400b714c3cd7b29622b94e 100644
--- a/client/views/app/messagePopupConfig.html
+++ b/client/views/app/messagePopupConfig.html
@@ -2,4 +2,5 @@
 	{{#if emojiEnabled}}{{> messagePopup popupEmojiConfig}}{{/if}}
 	{{> messagePopup popupChannelConfig}}
 	{{> messagePopup popupUserConfig}}
+	{{> messagePopup popupSlashCommandsConfig}}
 </template>
\ No newline at end of file
diff --git a/client/views/app/messagePopupSlashCommand.html b/client/views/app/messagePopupSlashCommand.html
new file mode 100644
index 0000000000000000000000000000000000000000..c1f1ec4dd8133ad747cd54635630ea2e23b68595
--- /dev/null
+++ b/client/views/app/messagePopupSlashCommand.html
@@ -0,0 +1,4 @@
+<template name="messagePopupSlashCommand">
+	<strong>/{{_id}}</strong>{{#if params}} {{params}}{{/if}}
+	<div class="popup-slash-command-description"><i>{{description}}</i></div>
+</template>
\ No newline at end of file
diff --git a/packages/rocketchat-lib/client/slashCommand.coffee b/packages/rocketchat-lib/client/slashCommand.coffee
deleted file mode 100644
index f1be087062c97e0c94fe54d4c51eb6b837d6202f..0000000000000000000000000000000000000000
--- a/packages/rocketchat-lib/client/slashCommand.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-RocketChat.slashCommands = {}
-
-RocketChat.slashCommands.add = (command, callback) ->
-	if !RocketChat.slashCommands[command]?
-		RocketChat.slashCommands[command] = callback
-	return
-
-RocketChat.slashCommands.run = (command, params, item) ->
-	if RocketChat.slashCommands[command]?
-		callback = RocketChat.slashCommands[command]
-		callback command, params, item
-
-
-Meteor.methods
-	slashCommand: (command) ->
-		if not Meteor.userId()
-			throw new Meteor.Error 203, t('User_logged_out')
-
-		RocketChat.slashCommands.run command.cmd, command.params, command.msg
-
diff --git a/packages/rocketchat-lib/lib/slashCommand.coffee b/packages/rocketchat-lib/lib/slashCommand.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..e920e59693911b99b65f01d26d53a8c65a14c4bc
--- /dev/null
+++ b/packages/rocketchat-lib/lib/slashCommand.coffee
@@ -0,0 +1,26 @@
+RocketChat.slashCommands =
+	commands: {}
+
+RocketChat.slashCommands.add = (command, callback, options) ->
+	if not RocketChat.slashCommands.commands[command]?
+		RocketChat.slashCommands.commands[command] =
+			command: command
+			callback: callback
+			params: options?.params
+			description: options?.description
+
+	return
+
+RocketChat.slashCommands.run = (command, params, item) ->
+	if RocketChat.slashCommands.commands[command]?.callback?
+		callback = RocketChat.slashCommands.commands[command].callback
+		callback command, params, item
+
+
+Meteor.methods
+	slashCommand: (command) ->
+		if not Meteor.userId()
+			throw new Meteor.Error 203, t('User_logged_out')
+
+		RocketChat.slashCommands.run command.cmd, command.params, command.msg
+
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index 4aa1ae6af4d88228f8367d8f06f1f7f137def72c..f3c00ecfb2e74057b4220e64c8dc8bcf9b17cc8b 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -17,6 +17,7 @@ Package.onUse(function(api) {
 
 	api.addFiles('lib/core.coffee', ['server', 'client']);
 	api.addFiles('lib/callbacks.coffee', ['server', 'client']);
+	api.addFiles('lib/slashCommand.coffee', ['server', 'client']);
 	
 	api.addFiles([
 		'server/functions/checkUsernameAvailability.coffee',
@@ -31,8 +32,6 @@ Package.onUse(function(api) {
 	], ['server']);
 
 	api.addFiles('server/sendMessage.coffee', ['server']);
-	api.addFiles('server/slashCommand.coffee', ['server']);
-	api.addFiles('client/slashCommand.coffee', ['client']);
 
 	api.addFiles([
 		'settings/lib/settings.coffee',
diff --git a/packages/rocketchat-lib/server/slashCommand.coffee b/packages/rocketchat-lib/server/slashCommand.coffee
deleted file mode 100644
index f1be087062c97e0c94fe54d4c51eb6b837d6202f..0000000000000000000000000000000000000000
--- a/packages/rocketchat-lib/server/slashCommand.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-RocketChat.slashCommands = {}
-
-RocketChat.slashCommands.add = (command, callback) ->
-	if !RocketChat.slashCommands[command]?
-		RocketChat.slashCommands[command] = callback
-	return
-
-RocketChat.slashCommands.run = (command, params, item) ->
-	if RocketChat.slashCommands[command]?
-		callback = RocketChat.slashCommands[command]
-		callback command, params, item
-
-
-Meteor.methods
-	slashCommand: (command) ->
-		if not Meteor.userId()
-			throw new Meteor.Error 203, t('User_logged_out')
-
-		RocketChat.slashCommands.run command.cmd, command.params, command.msg
-
diff --git a/packages/rocketchat-slashcommands-invite/invite.coffee b/packages/rocketchat-slashcommands-invite/invite.coffee
index 1e486752b331fe57db63f530da93524d16d84295..9d0f72126a0c5b7c9732a6f03f5d486403f7cdb1 100644
--- a/packages/rocketchat-slashcommands-invite/invite.coffee
+++ b/packages/rocketchat-slashcommands-invite/invite.coffee
@@ -3,24 +3,29 @@
 # @param {Object} message - The message object
 ###
 
-class Invite
-	constructor: (command, params, item) ->
-		if command isnt 'invite' or not Match.test params, String
-			return
+if Meteor.isClient
+	RocketChat.slashCommands.add 'invite', undefined,
+		description: 'Invite one user to join this channel'
+		params: '@username'
+else
+	class Invite
+		constructor: (command, params, item) ->
+			if command isnt 'invite' or not Match.test params, String
+				return
 
-		username = params.trim()
-		if username is ''
-			return
+			username = params.trim()
+			if username is ''
+				return
 
-		username = username.replace('@', '')
+			username = username.replace('@', '')
 
-		user = Meteor.users.findOne({ username: username })
+			user = Meteor.users.findOne({ username: username })
 
-		if not user?
-			return
+			if not user?
+				return
 
-		Meteor.runAsUser user._id, ->
-			Meteor.call 'joinRoom', item.rid
+			Meteor.runAsUser user._id, ->
+				Meteor.call 'joinRoom', item.rid
 
 
-RocketChat.slashCommands.add 'invite', Invite
+	RocketChat.slashCommands.add 'invite', Invite
diff --git a/packages/rocketchat-slashcommands-invite/package.js b/packages/rocketchat-slashcommands-invite/package.js
index 10431bab88d067c9da235fcf25979c8017b0d638..ba4cf0bdeb8120e89c194919d153d0af9aa15f6e 100644
--- a/packages/rocketchat-slashcommands-invite/package.js
+++ b/packages/rocketchat-slashcommands-invite/package.js
@@ -14,7 +14,7 @@ Package.onUse(function(api) {
 		'rocketchat:lib@0.0.1'
 	]);
 
-	api.addFiles('invite.coffee', 'server');
+	api.addFiles('invite.coffee');
 });
 
 Package.onTest(function(api) {