diff --git a/doc/protocol.xml b/doc/protocol.xml
index 1ddbc016c..56ff33b1e 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -1556,6 +1556,11 @@ OK
               the list of stored playlists.  This behavior is
               deprecated; use "listplaylists" instead.
             </para>
+            <para>
+              Clients that are connected via UNIX domain socket may
+              use this command to read the tags of an arbitrary local
+              file (URI beginning with "file:///").
+            </para>
           </listitem>
         </varlistentry>
         <varlistentry id="command_search">
diff --git a/src/command.c b/src/command.c
index 793737964..7d4403399 100644
--- a/src/command.c
+++ b/src/command.c
@@ -59,12 +59,13 @@
 #include "replay_gain_config.h"
 #include "idle.h"
 #include "mapper.h"
+#include "song.h"
+#include "song_print.h"
 
 #ifdef ENABLE_SQLITE
 #include "sticker.h"
 #include "sticker_print.h"
 #include "song_sticker.h"
-#include "song_print.h"
 #endif
 
 #include <assert.h>
@@ -664,6 +665,26 @@ handle_lsinfo(struct client *client, int argc, char *argv[])
 		/* default is root directory */
 		uri = "";
 
+	if (strncmp(uri, "file:///", 8) == 0) {
+		/* print information about an arbitrary local file */
+		const char *path = uri + 7;
+
+		GError *error = NULL;
+		if (!client_allow_file(client, path, &error))
+			return print_error(client, error);
+
+		struct song *song = song_file_load(path, NULL);
+		if (song == NULL) {
+			command_error(client, ACK_ERROR_NO_EXIST,
+				      "No such file");
+			return COMMAND_RETURN_ERROR;
+		}
+
+		song_print_info(client, song);
+		song_free(song);
+		return COMMAND_RETURN_OK;
+	}
+
 	struct db_selection selection;
 	db_selection_init(&selection, uri, false);