diff --git a/packages/language-server/completions/sails-completions.js b/packages/language-server/completions/sails-completions.js
new file mode 100644
index 0000000..3a168c2
--- /dev/null
+++ b/packages/language-server/completions/sails-completions.js
@@ -0,0 +1,63 @@
+const lsp = require('vscode-languageserver/node')
+const loadSails = require('../helpers/load-sails')
+
+module.exports = async function sailsCompletions(document, position) {
+  const text = document.getText()
+  const offset = document.offsetAt(position)
+  const line = text.substring(0, offset).split('\n').pop()
+
+  const match = line.match(/sails((?:\.[a-zA-Z_$][0-9a-zA-Z_$]*)*)\.$/)
+  if (match) {
+    try {
+      return await loadSails(document.uri, (sailsApp) => {
+        const path = match[1].split('.').filter(Boolean)
+        return getNestedCompletions(sailsApp, path)
+      })
+    } catch (error) {
+      return []
+    }
+  }
+
+  return null
+}
+
+function getNestedCompletions(obj, path) {
+  let current = obj
+  for (const key of path) {
+    if (current && typeof current === 'object' && key in current) {
+      current = current[key]
+    } else {
+      return []
+    }
+  }
+
+  if (typeof current !== 'object' || current === null) {
+    return []
+  }
+
+  const completions = Object.keys(current).map((key) => {
+    const value = current[key]
+    let kind = lsp.CompletionItemKind.Property
+    let detail = 'Property'
+
+    if (typeof value === 'function') {
+      kind = lsp.CompletionItemKind.Method
+      detail = 'Method'
+    } else if (typeof value === 'object' && value !== null) {
+      detail = 'Object'
+    }
+
+    return {
+      label: key,
+      kind: kind,
+      detail: detail,
+      documentation: `Access to sails${path.length ? '.' + path.join('.') : ''}.${key}`,
+      sortText: key.startsWith('_') ? `z${key}` : key // Add this line
+    }
+  })
+
+  // Sort the completions
+  completions.sort((a, b) => a.sortText.localeCompare(b.sortText))
+
+  return completions
+}
diff --git a/packages/language-server/go-to-definitions/go-to-view.js b/packages/language-server/go-to-definitions/go-to-view.js
index 4d4159e..598041d 100644
--- a/packages/language-server/go-to-definitions/go-to-view.js
+++ b/packages/language-server/go-to-definitions/go-to-view.js
@@ -1,7 +1,8 @@
 const lsp = require('vscode-languageserver/node')
 const path = require('path')
 const fs = require('fs').promises
-const url = require('url')
+
+const findProjectRoot = require('../helpers/find-project-root')
 
 module.exports = async function goToView(document, position) {
   const viewInfo = extractViewInfo(document, position)
@@ -67,18 +68,3 @@ function extractViewInfo(document, position) {
 function resolveViewPath(projectRoot, viewPath) {
   return path.join(projectRoot, 'views', `${viewPath}.ejs`)
 }
-
-async function findProjectRoot(uri) {
-  let currentPath = path.dirname(url.fileURLToPath(uri))
-  const root = path.parse(currentPath).root
-
-  while (currentPath !== root) {
-    try {
-      await fs.access(path.join(currentPath, 'package.json'))
-      return currentPath
-    } catch (error) {
-      currentPath = path.dirname(currentPath)
-    }
-  }
-  throw new Error('Could not find project root')
-}
diff --git a/packages/language-server/helpers/find-project-root.js b/packages/language-server/helpers/find-project-root.js
new file mode 100644
index 0000000..d92a316
--- /dev/null
+++ b/packages/language-server/helpers/find-project-root.js
@@ -0,0 +1,18 @@
+const path = require('path')
+const url = require('url')
+const fs = require('fs').promises
+
+module.exports = async function findProjectRoot(uri) {
+  let currentPath = path.dirname(url.fileURLToPath(uri))
+  const root = path.parse(currentPath).root
+
+  while (currentPath !== root) {
+    try {
+      await fs.access(path.join(currentPath, 'package.json'))
+      return currentPath
+    } catch (error) {
+      currentPath = path.dirname(currentPath)
+    }
+  }
+  throw new Error('Could not find project root')
+}
diff --git a/packages/language-server/helpers/find-sails.js b/packages/language-server/helpers/find-sails.js
new file mode 100644
index 0000000..12c3517
--- /dev/null
+++ b/packages/language-server/helpers/find-sails.js
@@ -0,0 +1,12 @@
+const path = require('path')
+const fs = require('fs')
+const findProjectRoot = require('./find-project-root')
+
+module.exports = async function findSails(workspaceUri) {
+  const projectRoot = await findProjectRoot(workspaceUri)
+  const sailsPath = path.join(projectRoot, 'node_modules', 'sails')
+  if (fs.existsSync(sailsPath)) {
+    return { sailsPath, projectRoot }
+  }
+  throw new Error('Sails not found in node_modules')
+}
diff --git a/packages/language-server/helpers/load-sails.js b/packages/language-server/helpers/load-sails.js
new file mode 100644
index 0000000..7d3a4f1
--- /dev/null
+++ b/packages/language-server/helpers/load-sails.js
@@ -0,0 +1,38 @@
+const findSails = require('./find-sails')
+
+module.exports = async function loadSails(workspaceUri, operation) {
+  let Sails
+  let sailsApp
+
+  try {
+    const { sailsPath } = await findSails(workspaceUri)
+    Sails = require(sailsPath).constructor
+
+    sailsApp = await new Promise((resolve, reject) => {
+      new Sails().load(
+        {
+          hooks: { shipwright: false },
+          log: { level: 'silent' }
+        },
+        (err, sails) => {
+          if (err) {
+            console.error('Failed to load Sails app:', err)
+            return reject(err)
+          }
+          resolve(sails)
+        }
+      )
+    })
+
+    // Execute the operation with the loaded Sails app
+    return await operation(sailsApp)
+  } catch (error) {
+    console.error('Error loading or working with Sails app:', error)
+    throw error
+  } finally {
+    // Ensure Sails is lowered even if an error occurred
+    if (sailsApp && typeof sailsApp.lower === 'function') {
+      await new Promise((resolve) => sailsApp.lower(resolve))
+    }
+  }
+}
diff --git a/packages/language-server/index.js b/packages/language-server/index.js
index e02f649..18d3af2 100644
--- a/packages/language-server/index.js
+++ b/packages/language-server/index.js
@@ -4,6 +4,7 @@ const validateDocument = require('./validators/validate-document')
 const goToAction = require('./go-to-definitions/go-to-action')
 const goToPolicy = require('./go-to-definitions/go-to-policy')
 const goToView = require('./go-to-definitions/go-to-view')
+const sailsCompletions = require('./completions/sails-completions')
 
 const connection = lsp.createConnection(lsp.ProposedFeatures.all)
 const documents = new lsp.TextDocuments(TextDocument)
@@ -12,11 +13,10 @@ connection.onInitialize((params) => {
   return {
     capabilities: {
       textDocumentSync: lsp.TextDocumentSyncKind.Incremental,
-      definitionProvider: true
-      // completionProvider: {
-      //   resolveProvider: true,
-      //   triggerCharacters: ['"', "'", '.']
-      // }
+      definitionProvider: true,
+      completionProvider: {
+        triggerCharacters: ['"', "'", '.']
+      }
     }
   }
 })
@@ -48,6 +48,24 @@ connection.onDefinition(async (params) => {
   return definitions.length > 0 ? definitions : null
 })
 
+connection.onCompletion(async (params) => {
+  const document = documents.get(params.textDocument.uri)
+  if (!document) {
+    return null
+  }
+
+  const completions = await sailsCompletions(document, params.position)
+
+  if (completions) {
+    return {
+      isIncomplete: false,
+      items: completions
+    }
+  }
+
+  return null
+})
+
 documents.listen(connection)
 connection.listen()