diff --git a/src/Entity.js b/src/Entity.js
new file mode 100644
index 0000000000000000000000000000000000000000..13f88ffc864a91bf5d658a78264bdb3d26f32647
--- /dev/null
+++ b/src/Entity.js
@@ -0,0 +1,96 @@
+/*
+ * ** header v3.0
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Affero General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * ** end header
+ */
+import {
+    api
+} from "./EntityApi";
+
+import {
+    Property
+} from "./Property";
+
+function _getRoleString(role) {
+    const roles = api.v1.EntityRole;
+    switch (role) {
+    case roles.ENTITY_ROLE_UNSPECIFIED:
+        return undefined;
+    case roles.ENTITY_ROLE_RECORD_TYPE:
+        return "RECORD_TYPE";
+    case roles.ENTITY_ROLE_RECORD:
+        return "RECORD";
+    case roles.ENTITY_ROLE_PROPERTY:
+        return "PROPERTY";
+    case roles.ENTITY_ROLE_FILE:
+        return "FILE";
+    default:
+        throw `Unknown role ${role}.`;
+    }
+}
+
+export class Entity {
+
+    constructor(protoEntity) {
+        this.wrappedEntity = protoEntity;
+    }
+
+    getDescription() {
+        return this.wrappedEntity.getDescription();
+    }
+
+    getId() {
+        return this.wrappedEntity.getId();
+    }
+
+    getName() {
+        return this.wrappedEntity.getName();
+    }
+
+    getParents() {
+        // TODO(fspreck): Use Parent objects here in the future.
+        return this.wrappedEntity.getParentsList();
+    }
+
+    getProperties() {
+        const protoProperties = this.wrappedEntity.getPropertiesList();
+        return protoProperties.map(prop => new Property(prop));
+    }
+
+    getProperty(name) {
+        const properties = this.getProperties();
+        if (properties) {
+            for (let prop of properties) {
+                if (prop.getName().toLowerCase() === name.toLowerCase()) {
+                    return prop;
+                }
+            }
+        }
+        return undefined;
+    }
+
+    getRole() {
+        return _getRoleString(this.wrappedEntity.getRole());
+    }
+
+    isRecord() {
+        return this.wrappedEntity.getRole() === api.v1.EntityRole.ENTITY_ROLE_RECORD;
+    }
+}
diff --git a/src/index.js b/src/index.js
index bce5b757a77aafea1941111f46d8347101bbd743..979dfc1ff4cfca8add6edd8cf7f4eb997cf73f03 100644
--- a/src/index.js
+++ b/src/index.js
@@ -20,6 +20,11 @@
  *
  * ** end header
  */
+export {
+    Entity
+}
+from "./Entity";
+
 export {
     Property
 }