diff --git a/src/index.ts b/src/index.ts
index 83c251d..852ee0e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,4 @@
-import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
+import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
 import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
 import FormData from "form-data";
 import axios, { AxiosInstance } from "axios";
@@ -130,10 +130,18 @@ class DocmostClient {
     return groups.map((group) => filterGroup(group));
   }
 
-  async listPages(spaceId?: string) {
-    const payload = spaceId ? { spaceId } : {};
-    const pages = await this.paginateAll("/pages/recent", payload);
-    return pages.map((page) => filterPage(page));
+  async listPages(spaceId?: string, page: number = 1, limit: number = 50) {
+    await this.ensureAuthenticated();
+    const clampedLimit = Math.max(1, Math.min(100, limit));
+    const payload: Record<string, any> = { page, limit: clampedLimit };
+    if (spaceId) payload.spaceId = spaceId;
+    const response = await this.client.post("/pages/recent", payload);
+    const data = response.data;
+    const items = data.data?.items || data.items || [];
+    return {
+      pages: items.map((p: any) => filterPage(p)),
+      meta: data.data?.meta || data.meta || {},
+    };
   }
 
   async listSidebarPages(spaceId: string, pageId: string) {
@@ -283,8 +291,9 @@ class DocmostClient {
       spaceId,
     });
 
-    // Filter search results (data is directly an array)
-    const items = response.data?.data || [];
+    // Handle both array and {items: [...]} response formats
+    const rawData = response.data?.data;
+    const items = Array.isArray(rawData) ? rawData : (rawData?.items || []);
     const filteredItems = items.map((item: any) => filterSearchResult(item));
 
     return {
@@ -384,13 +393,15 @@ server.registerTool(
 server.registerTool(
   "list_pages",
   {
-    description: "List pages in a space ordered by updatedAt (descending).",
+    description: "List pages in a space ordered by updatedAt (descending). Returns one page of results.",
     inputSchema: {
       spaceId: z.string().optional(),
+      page: z.number().optional().describe("Page number (default: 1)"),
+      limit: z.number().optional().describe("Items per page, 1-100 (default: 50)"),
     },
   },
-  async ({ spaceId }) => {
-    const result = await docmostClient.listPages(spaceId);
+  async ({ spaceId, page, limit }) => {
+    const result = await docmostClient.listPages(spaceId, page, limit);
     return jsonContent(result);
   },
 );
@@ -544,6 +555,41 @@ server.registerTool(
   },
 );
 
+// Resource template: docmost://pages/{pageId}
+// Allows MCP clients to read page content as resources
+server.resource(
+  "page",
+  new ResourceTemplate("docmost://pages/{pageId}", {
+    list: async () => {
+      // List recent pages as browsable resources
+      try {
+        const result = await docmostClient.listPages(undefined, 1, 100);
+        return result.pages.map((page: any) => ({
+          uri: `docmost://pages/${page.id}`,
+          name: page.title || page.id,
+          mimeType: "text/markdown",
+        }));
+      } catch {
+        return [];
+      }
+    },
+  }),
+  { description: "A Docmost wiki page", mimeType: "text/markdown" },
+  async (uri: URL, variables: Record<string, string | string[]>) => {
+    const pageId = Array.isArray(variables.pageId) ? variables.pageId[0]! : variables.pageId!;
+    const page = await docmostClient.getPage(pageId);
+    return {
+      contents: [
+        {
+          uri: uri.href,
+          text: page.data.content || `# ${page.data.title || "Untitled"}\n\n(No content)`,
+          mimeType: "text/markdown",
+        },
+      ],
+    };
+  },
+);
+
 async function run() {
   const transport = new StdioServerTransport();
   await server.connect(transport);
