@screenest/mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ScreeNest Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,323 @@
1
+ # @screenest/mcp-server
2
+
3
+ MCP (Model Context Protocol) server for [ScreeNest](https://screenest.app) — Access your activity tracking data and Long-Term Memory from Claude Desktop, Cursor, and other MCP-compatible clients.
4
+
5
+ ## Prerequisites
6
+
7
+ - **ScreeNest** installed and running (Windows only — ScreeNest is a WPF desktop app)
8
+ - **Node.js 18** or higher
9
+
10
+ ## Setup
11
+
12
+ ### Step 1 — Get your API token from ScreeNest
13
+
14
+ 1. Open the **ScreeNest** desktop app
15
+ 2. Go to the **Export** tab
16
+ 3. Locate the **API Token** field (it's masked by default — click the eye icon to reveal)
17
+ 4. Click the **Copy** button to copy the token to your clipboard
18
+
19
+ > **Why is a token needed?** The MCP server connects to ScreeNest's local HTTP API on `localhost:18080`. The token authenticates every request so that only your MCP client — not other processes on your machine — can read your activity data and Long-Term Memory. If you regenerate the token in ScreeNest, update your MCP client config with the new value and restart the client.
20
+
21
+ ### Step 2 — Add the MCP server to your client config
22
+
23
+ #### Claude Desktop
24
+
25
+ Edit `claude_desktop_config.json`:
26
+
27
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
28
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` *(Note: ScreeNest itself is Windows-only)*
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "screenest": {
34
+ "command": "npx",
35
+ "args": ["-y", "@screenest/mcp-server"],
36
+ "env": {
37
+ "SCREENEST_API_TOKEN": "<paste-your-token-here>"
38
+ }
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ Replace `<paste-your-token-here>` with the token you copied in Step 1. Then **completely quit and restart Claude Desktop** (closing the window is not enough — also exit from the system tray).
45
+
46
+ #### Cursor IDE
47
+
48
+ Edit `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for global):
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "screenest": {
54
+ "command": "npx",
55
+ "args": ["-y", "@screenest/mcp-server"],
56
+ "env": {
57
+ "SCREENEST_API_TOKEN": "<paste-your-token-here>"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ Then restart Cursor completely.
65
+
66
+ ## Alternative: Global Installation
67
+
68
+ For faster startup (no download on each launch):
69
+
70
+ ```bash
71
+ npm install -g @screenest/mcp-server
72
+ ```
73
+
74
+ Then configure with the binary name instead of `npx`:
75
+
76
+ ```json
77
+ {
78
+ "mcpServers": {
79
+ "screenest": {
80
+ "command": "screenest-mcp",
81
+ "env": {
82
+ "SCREENEST_API_TOKEN": "<paste-your-token-here>"
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Windows Troubleshooting
90
+
91
+ If `npx` doesn't work on Windows, use the full path to node:
92
+
93
+ ```json
94
+ {
95
+ "mcpServers": {
96
+ "screenest": {
97
+ "command": "C:\\Program Files\\nodejs\\node.exe",
98
+ "args": [
99
+ "C:\\Users\\<username>\\AppData\\Roaming\\npm\\node_modules\\@screenest\\mcp-server\\build\\index.js"
100
+ ],
101
+ "env": {
102
+ "SCREENEST_API_TOKEN": "<paste-your-token-here>"
103
+ }
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ Replace `<username>` with your actual Windows username.
110
+
111
+ ## Available Tools
112
+
113
+ | Tool | Purpose |
114
+ |------|---------|
115
+ | `get_daily_memory` | AI-generated daily/hourly reports for a given date |
116
+ | `get_weekly_memory` | Weekly summary: daily reports, app breakdown, trends |
117
+ | `get_activity` | Raw activity data: app timeline, keystrokes, clipboard, browser visits |
118
+ | `read_ltm` | Read the user's Long-Term Memory (optionally a single section) |
119
+ | `update_ltm` | Append or replace a section of the Long-Term Memory |
120
+
121
+ ### `get_daily_memory`
122
+
123
+ Returns AI-analyzed hourly and daily reports for a specific date. Use this for questions like "What did I do today?" or "Summarize yesterday's work".
124
+
125
+ | Parameter | Type | Default | Description |
126
+ |-----------|------|---------|-------------|
127
+ | `date` | string | today | Target date in `YYYY-MM-DD` format (local timezone) |
128
+
129
+ **Returns:** Markdown text listing each AI report with title, type, timestamp, and formatted content.
130
+
131
+ ---
132
+
133
+ ### `get_weekly_memory`
134
+
135
+ Returns a weekly summary — daily AI reports, daily breakdown, top apps, and trends. Does NOT include raw per-entry logs (optimized for efficient context usage over longer ranges).
136
+
137
+ | Parameter | Type | Default | Description |
138
+ |-----------|------|---------|-------------|
139
+ | `end_date` | string | today | End date in `YYYY-MM-DD` format (local timezone) |
140
+ | `days` | number | 7 | Number of days to look back (1–30) |
141
+ | `include` | array | all | Sections: `daily_reports`, `daily_breakdown`, `top_apps`, `trends` |
142
+
143
+ **Returns:** Text summary.
144
+
145
+ ---
146
+
147
+ ### `get_activity`
148
+
149
+ Returns the raw activity timeline for a given date — app usage, keystrokes per region (editor / terminal / AI sidebar), clipboard history, and browser visits. Use this when you need granular per-app data.
150
+
151
+ | Parameter | Type | Default | Description |
152
+ |-----------|------|---------|-------------|
153
+ | `date` | string | today | Target date in `YYYY-MM-DD` format (local timezone) |
154
+ | `app_filter` | string | — | Filter to a specific application name |
155
+
156
+ **Returns:** Markdown text with an activity timeline, clipboard, and browser sections.
157
+
158
+ ---
159
+
160
+ ### `read_ltm`
161
+
162
+ Reads the user's Long-Term Memory (LTM) — persistent context that the ScreeNest app maintains about the user's work style, tools, expertise, and current context.
163
+
164
+ | Parameter | Type | Default | Description |
165
+ |-----------|------|---------|-------------|
166
+ | `section` | string | — | Section name to read. Omit for full content. |
167
+
168
+ Common sections: `Work Style`, `Toolbox & Stack`, `Expertise`, `Communication`, `Interests`, `Current Context`.
169
+
170
+ **Returns:** The requested LTM content as Markdown.
171
+
172
+ ---
173
+
174
+ ### `update_ltm`
175
+
176
+ Updates the user's Long-Term Memory. Appends to a section by default, or replaces it entirely when `replace: true`. Importance tags like `[Priority: High] [Weight: 5]` can be included in the content.
177
+
178
+ | Parameter | Type | Default | Description |
179
+ |-----------|------|---------|-------------|
180
+ | `section` | string | required | Section name to update |
181
+ | `content` | string | required | Markdown content to write |
182
+ | `replace` | boolean | `false` | `true` to replace the section, `false` to append |
183
+
184
+ **Returns:** Confirmation message with action type and total character count.
185
+
186
+ ---
187
+
188
+ ## Response Size Limit
189
+
190
+ To avoid context overflow in the calling AI, responses are truncated at ~80,000 characters. If a response is truncated, narrow the query with `app_filter` or a more specific date.
191
+
192
+ ## Example Usage
193
+
194
+ After setup, ask Claude or Cursor:
195
+
196
+ - "What did I work on today?"
197
+ - "Summarize my last week"
198
+ - "Which apps did I use most yesterday?"
199
+ - "What was I typing in VS Code this morning?"
200
+ - "Read my Long-Term Memory current context"
201
+ - "Update my LTM: I started working on the MCP server today"
202
+
203
+ ## Timezone Note
204
+
205
+ ScreeNest stores all timestamps in **UTC** internally. Date parameters (`date`, `end_date`) should be specified in your **local timezone** (e.g., `2026-02-22`). The ScreeNest app handles UTC conversion automatically on the server side.
206
+
207
+ ## Privacy & Data Handling
208
+
209
+ This MCP server exposes sensitive local data from the ScreeNest desktop app to your connected AI client. Before using it, please understand what is shared and with whom.
210
+
211
+ ### What data can be accessed
212
+
213
+ Depending on which tool is invoked, the server can read:
214
+
215
+ - **Activity data** (`get_activity`): app usage timeline, keystrokes grouped by application, clipboard history, browser visit URLs
216
+ - **AI memory** (`get_daily_memory`, `get_weekly_memory`): daily / weekly reports generated by ScreeNest, including titles and summaries of your work
217
+ - **Long-Term Memory** (`read_ltm`, `update_ltm`): your work style, tools, expertise, current context — and the ability to modify it
218
+
219
+ ### How the data flows
220
+
221
+ ```
222
+ ScreeNest app (local SQLite DB)
223
+
224
+ localhost:18080 (Bearer token auth)
225
+
226
+ @screenest/mcp-server ← this package
227
+
228
+ stdio (Claude Desktop / Cursor / other MCP client)
229
+
230
+ the client's backing LLM provider (Anthropic, OpenAI, etc.)
231
+ ```
232
+
233
+ When you invoke a tool from your MCP client, the requested data is handed to the client over stdio, and the client may forward it to its configured LLM provider as conversation context. That forwarding is governed by the privacy policy of the MCP client and its LLM provider — **not** by this package.
234
+
235
+ ### What this server does NOT do
236
+
237
+ - **No telemetry**: the server makes no network calls except to `localhost:18080` (the ScreeNest app) and to its stdio parent (the MCP client). No analytics, no phone-home, no crash reporting.
238
+ - **No third-party services**: no external APIs are contacted directly from this package.
239
+ - **No persistent logging of your data**: nothing is written to disk by this package. Log messages (if enabled) are emitted to stderr only for the lifetime of the process.
240
+
241
+ You can verify these claims by reading `build/index.js` after `npm install` — the compiled source is not minified.
242
+
243
+ ### Recommendations
244
+
245
+ - Treat `update_ltm` carefully: anything you pass to this tool is persisted in ScreeNest's Long-Term Memory and becomes part of future AI reports.
246
+ - Before sharing activity data via chat, remember that the LLM provider your client uses may log or retain the input per its own terms.
247
+ - If your MCP client supports per-tool approval prompts, consider enabling them so you can review what's being sent for each call.
248
+
249
+ ## Environment Variables
250
+
251
+ `SCREENEST_API_TOKEN` is **required**. All other variables are optional and rarely need changing. Pass them via the `env` block of your MCP client config:
252
+
253
+ ```json
254
+ {
255
+ "mcpServers": {
256
+ "screenest": {
257
+ "command": "npx",
258
+ "args": ["-y", "@screenest/mcp-server"],
259
+ "env": {
260
+ "SCREENEST_API_TOKEN": "<paste-your-token-here>",
261
+ "SCREENEST_LOG_LEVEL": "debug",
262
+ "SCREENEST_TIMEOUT_MS": "120000"
263
+ }
264
+ }
265
+ }
266
+ }
267
+ ```
268
+
269
+ | Variable | Required | Default | Description |
270
+ |----------|----------|---------|-------------|
271
+ | `SCREENEST_API_TOKEN` | **Yes** | — | Bearer token for the ScreeNest local API. Copy it from the ScreeNest app's **Export** tab (see [Setup](#setup)). The server exits immediately if this is not set. |
272
+ | `SCREENEST_API_URL` | No | `http://localhost:18080` | ScreeNest local API endpoint. Change this only if ScreeNest is running on a non-default port. |
273
+ | `SCREENEST_LOG_LEVEL` | No | `info` | Logger verbosity. One of `debug`, `info`, `warn`, `error`. Logs go to stderr only (stdout is reserved for the MCP protocol). |
274
+ | `SCREENEST_TIMEOUT_MS` | No | `60000` | HTTP request timeout in milliseconds. Increase for very large weekly reports over slow disks. |
275
+
276
+ ### Platform support
277
+
278
+ This package ships with `"os": ["win32"]` because the ScreeNest desktop application is Windows-only (WPF). `npm install` / `npx` will refuse to install on macOS or Linux.
279
+
280
+ ## Development
281
+
282
+ ```bash
283
+ # Install dependencies
284
+ npm install
285
+
286
+ # Build
287
+ npm run build
288
+
289
+ # Run locally (for testing)
290
+ npm start
291
+ ```
292
+
293
+ ## Troubleshooting
294
+
295
+ ### "ScreeNest is not running"
296
+
297
+ The MCP server requires the **ScreeNest desktop application** to be running. Start ScreeNest first, then retry the MCP tool call.
298
+
299
+ ### MCP server not showing in Claude / Cursor
300
+
301
+ 1. Check JSON syntax in your config file
302
+ 2. Restart the application completely (not just close window)
303
+ 3. Check logs:
304
+ - Claude Desktop (Mac): `~/Library/Logs/Claude/mcp*.log`
305
+ - Claude Desktop (Windows): `%APPDATA%\Claude\logs\`
306
+ - Cursor: Output panel → MCP
307
+
308
+ ### Server exits with "SCREENEST_API_TOKEN is not set"
309
+
310
+ You haven't configured the token in your MCP client config. Follow [Step 1 of the Setup section](#step-1--get-your-api-token-from-screenest) to copy the token from the ScreeNest Export tab, then paste it into the `env.SCREENEST_API_TOKEN` field of your client config and restart the client.
311
+
312
+ ### Authentication errors (401 / 403)
313
+
314
+ The token in your config is no longer valid. This usually means you clicked **Regenerate** or **Revoke** in the ScreeNest Export tab. To fix:
315
+
316
+ 1. Open the ScreeNest app → Export tab
317
+ 2. Copy the current API Token
318
+ 3. Update `env.SCREENEST_API_TOKEN` in your MCP client config
319
+ 4. Restart your MCP client completely
320
+
321
+ ## License
322
+
323
+ MIT
@@ -0,0 +1,17 @@
1
+ /**
2
+ * ScreeNest MCP Server
3
+ *
4
+ * 5-tool architecture (same tool types as Chat FC tools):
5
+ * - get_daily_memory: AI-generated daily reports
6
+ * - get_weekly_memory: Weekly summary and trends
7
+ * - get_activity: Raw activity data (filterable by date + app)
8
+ * - read_ltm: Read Long-Term Memory
9
+ * - update_ltm: Update Long-Term Memory
10
+ *
11
+ * Design principles:
12
+ * - Unified tool set across Chat FC and MCP
13
+ * - Date-based queries for flexibility
14
+ * - Zero-config on Windows (auto-loads API token from ScreeNest app)
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
package/build/index.js ADDED
@@ -0,0 +1,452 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ScreeNest MCP Server
4
+ *
5
+ * 5-tool architecture (same tool types as Chat FC tools):
6
+ * - get_daily_memory: AI-generated daily reports
7
+ * - get_weekly_memory: Weekly summary and trends
8
+ * - get_activity: Raw activity data (filterable by date + app)
9
+ * - read_ltm: Read Long-Term Memory
10
+ * - update_ltm: Update Long-Term Memory
11
+ *
12
+ * Design principles:
13
+ * - Unified tool set across Chat FC and MCP
14
+ * - Date-based queries for flexibility
15
+ * - Zero-config on Windows (auto-loads API token from ScreeNest app)
16
+ */
17
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
18
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
19
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
20
+ // =====================
21
+ // Configuration (from environment variables)
22
+ // =====================
23
+ const SCREENEST_API_BASE = process.env.SCREENEST_API_URL || "http://localhost:18080";
24
+ const SCREENEST_API_TOKEN = process.env.SCREENEST_API_TOKEN || "";
25
+ const SCREENEST_LOG_LEVEL = (process.env.SCREENEST_LOG_LEVEL || "info").toLowerCase();
26
+ const SCREENEST_TIMEOUT_MS = (() => {
27
+ const raw = Number(process.env.SCREENEST_TIMEOUT_MS);
28
+ return Number.isFinite(raw) && raw > 0 ? raw : 60_000;
29
+ })();
30
+ const SERVER_NAME = "screenest-mcp-server";
31
+ const SERVER_VERSION = "1.0.0";
32
+ const LOG_PRIORITY = {
33
+ debug: 0,
34
+ info: 1,
35
+ warn: 2,
36
+ error: 3,
37
+ };
38
+ const activeLogPriority = LOG_PRIORITY[SCREENEST_LOG_LEVEL] ?? LOG_PRIORITY.info;
39
+ function log(level, message) {
40
+ if (LOG_PRIORITY[level] >= activeLogPriority) {
41
+ console.error(`[${level}] ${message}`);
42
+ }
43
+ }
44
+ // =====================
45
+ // Helper Functions
46
+ // =====================
47
+ /**
48
+ * Validate that the API token is set. The token must be obtained from the
49
+ * ScreeNest desktop app (Export tab → API Token → Copy) and passed via the
50
+ * SCREENEST_API_TOKEN environment variable in the MCP client config.
51
+ *
52
+ * Exits immediately if the token is missing so the MCP client surfaces a
53
+ * clear configuration error to the user instead of a stream of 401s.
54
+ */
55
+ function requireApiToken() {
56
+ if (SCREENEST_API_TOKEN) {
57
+ return SCREENEST_API_TOKEN;
58
+ }
59
+ const message = [
60
+ "SCREENEST_API_TOKEN is not set.",
61
+ "",
62
+ "To fix this:",
63
+ " 1. Open the ScreeNest desktop app",
64
+ " 2. Go to the Export tab",
65
+ " 3. Click the Copy button next to the API Token",
66
+ " 4. Paste the token into your MCP client config under env.SCREENEST_API_TOKEN",
67
+ "",
68
+ "Example (claude_desktop_config.json):",
69
+ ' "screenest": {',
70
+ ' "command": "npx",',
71
+ ' "args": ["-y", "@screenest/mcp-server"],',
72
+ ' "env": {',
73
+ ' "SCREENEST_API_TOKEN": "<paste-token-here>"',
74
+ " }",
75
+ " }",
76
+ ].join("\n");
77
+ log("error", message);
78
+ process.exit(1);
79
+ }
80
+ const apiToken = requireApiToken();
81
+ /**
82
+ * Wrap fetch with AbortController so hanging requests don't block the MCP client.
83
+ */
84
+ async function fetchWithTimeout(url, init) {
85
+ const controller = new AbortController();
86
+ const timer = setTimeout(() => controller.abort(), SCREENEST_TIMEOUT_MS);
87
+ try {
88
+ return await fetch(url, { ...init, signal: controller.signal });
89
+ }
90
+ finally {
91
+ clearTimeout(timer);
92
+ }
93
+ }
94
+ function wrapNetworkError(error) {
95
+ if (error instanceof Error && error.name === "AbortError") {
96
+ return new Error(`Request timed out after ${SCREENEST_TIMEOUT_MS}ms. Set SCREENEST_TIMEOUT_MS to a larger value if needed.`);
97
+ }
98
+ if (error instanceof TypeError && error.message.includes("fetch")) {
99
+ return new Error(`Cannot connect to ScreeNest at ${SCREENEST_API_BASE}. Make sure the ScreeNest application is running.`);
100
+ }
101
+ return error instanceof Error ? error : new Error(String(error));
102
+ }
103
+ /**
104
+ * Make a GET request to the ScreeNest LocalApiServer
105
+ */
106
+ async function fetchFromScreeNest(endpoint, params) {
107
+ const url = new URL(endpoint, SCREENEST_API_BASE);
108
+ if (params) {
109
+ Object.entries(params).forEach(([key, value]) => {
110
+ if (value !== undefined && value !== null && value !== "") {
111
+ url.searchParams.set(key, value);
112
+ }
113
+ });
114
+ }
115
+ const headers = {
116
+ Accept: "application/json",
117
+ };
118
+ if (apiToken) {
119
+ headers["Authorization"] = `Bearer ${apiToken}`;
120
+ }
121
+ log("debug", `GET ${url.toString()}`);
122
+ try {
123
+ const response = await fetchWithTimeout(url.toString(), { headers });
124
+ if (!response.ok) {
125
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
126
+ }
127
+ const contentType = response.headers.get("content-type");
128
+ if (contentType?.includes("application/json")) {
129
+ return (await response.json());
130
+ }
131
+ else {
132
+ return await response.text();
133
+ }
134
+ }
135
+ catch (error) {
136
+ throw wrapNetworkError(error);
137
+ }
138
+ }
139
+ /**
140
+ * Make a PUT request to the ScreeNest LocalApiServer
141
+ */
142
+ async function putToScreeNest(endpoint, body) {
143
+ const url = new URL(endpoint, SCREENEST_API_BASE);
144
+ const headers = {
145
+ "Content-Type": "application/json",
146
+ Accept: "application/json",
147
+ };
148
+ if (apiToken) {
149
+ headers["Authorization"] = `Bearer ${apiToken}`;
150
+ }
151
+ log("debug", `PUT ${url.toString()}`);
152
+ try {
153
+ const response = await fetchWithTimeout(url.toString(), {
154
+ method: "PUT",
155
+ headers,
156
+ body: JSON.stringify(body),
157
+ });
158
+ if (!response.ok) {
159
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
160
+ }
161
+ return (await response.json());
162
+ }
163
+ catch (error) {
164
+ throw wrapNetworkError(error);
165
+ }
166
+ }
167
+ // 日本語は概ね 1文字≒1トークン。80,000文字を上限として受け側AIのコンテキスト超過を防ぐ
168
+ const MAX_RESPONSE_CHARS = 80_000;
169
+ function truncateIfNeeded(text) {
170
+ if (text.length <= MAX_RESPONSE_CHARS)
171
+ return text;
172
+ return (text.slice(0, MAX_RESPONSE_CHARS) +
173
+ "\n\n---\n" +
174
+ "⚠️ Response truncated at ~80,000 token limit.\n" +
175
+ "To retrieve additional data, narrow the query with `app_filter` or specify the date more precisely.");
176
+ }
177
+ /**
178
+ * Get today's date in YYYY-MM-DD format (local timezone)
179
+ */
180
+ function getTodayDate() {
181
+ const now = new Date();
182
+ const year = now.getFullYear();
183
+ const month = String(now.getMonth() + 1).padStart(2, "0");
184
+ const day = String(now.getDate()).padStart(2, "0");
185
+ return `${year}-${month}-${day}`;
186
+ }
187
+ // =====================
188
+ // Tool Definitions
189
+ // =====================
190
+ const tools = [
191
+ {
192
+ name: "get_daily_memory",
193
+ description: "Get user's AI-generated daily memory (hourly and daily reports). Use for 'What did I do today?', 'Summarize my work yesterday'. Returns AI-analyzed reports with topics and insights.",
194
+ inputSchema: {
195
+ type: "object",
196
+ properties: {
197
+ date: {
198
+ type: "string",
199
+ description: "Target date in YYYY-MM-DD format using your local timezone. Default: today.",
200
+ },
201
+ },
202
+ required: [],
203
+ },
204
+ },
205
+ {
206
+ name: "get_weekly_memory",
207
+ description: "Get user's weekly AI memory summary with daily reports and trends. Use for 'How was my week?', 'Weekly summary'. Does NOT include detailed raw logs for efficiency.",
208
+ inputSchema: {
209
+ type: "object",
210
+ properties: {
211
+ end_date: {
212
+ type: "string",
213
+ description: "End date in YYYY-MM-DD format using your local timezone. Default: today.",
214
+ },
215
+ days: {
216
+ type: "number",
217
+ description: "Number of days to include (1-30). Default: 7",
218
+ },
219
+ include: {
220
+ type: "array",
221
+ items: {
222
+ type: "string",
223
+ enum: ["daily_reports", "daily_breakdown", "top_apps", "trends"],
224
+ },
225
+ description: "Sections to include. Default: all sections.",
226
+ },
227
+ },
228
+ required: [],
229
+ },
230
+ },
231
+ {
232
+ name: "get_activity",
233
+ description: "Get user's activity data for a given date. Returns app usage timeline with keystroke input per region (editor/terminal/AI sidebar), clipboard history, and browser visits. Filterable by date and app.",
234
+ inputSchema: {
235
+ type: "object",
236
+ properties: {
237
+ date: {
238
+ type: "string",
239
+ description: "Target date in YYYY-MM-DD format using your local timezone. Default: today.",
240
+ },
241
+ app_filter: {
242
+ type: "string",
243
+ description: "Filter to specific application name. Default: all apps",
244
+ },
245
+ },
246
+ required: [],
247
+ },
248
+ },
249
+ {
250
+ name: "read_ltm",
251
+ description: "Read user's Long-Term Memory (LTM). Specify a section name to get only that section, or omit for full content. Sections: Work Style, Toolbox & Stack, Expertise, Communication, Interests, Current Context.",
252
+ inputSchema: {
253
+ type: "object",
254
+ properties: {
255
+ section: {
256
+ type: "string",
257
+ description: "Section name to read (omit for full content). Examples: 'Work Style', 'Current Context'",
258
+ },
259
+ },
260
+ required: [],
261
+ },
262
+ },
263
+ {
264
+ name: "update_ltm",
265
+ description: "Update user's Long-Term Memory (LTM). Append or replace a specific section. Include importance tags like [Priority: High] [Weight: 5].",
266
+ inputSchema: {
267
+ type: "object",
268
+ properties: {
269
+ section: {
270
+ type: "string",
271
+ description: "Section name to update. Examples: 'Work Style', 'Toolbox & Stack', 'Current Context'",
272
+ },
273
+ content: {
274
+ type: "string",
275
+ description: "Content to write (Markdown format). Include importance tags, e.g.: [Priority: High] [Weight: 5]",
276
+ },
277
+ replace: {
278
+ type: "boolean",
279
+ description: "true to replace the section, false to append (default: false)",
280
+ },
281
+ },
282
+ required: ["section", "content"],
283
+ },
284
+ },
285
+ ];
286
+ // =====================
287
+ // Tool Handlers
288
+ // =====================
289
+ async function handleGetDailyMemory(input) {
290
+ const date = String(input.date ?? getTodayDate());
291
+ const params = {
292
+ date,
293
+ include: "reports",
294
+ };
295
+ const response = await fetchFromScreeNest("/api/daily-report", params);
296
+ if (typeof response === "string") {
297
+ throw new Error(`Unexpected string response: ${response}`);
298
+ }
299
+ const data = response;
300
+ let text = `## Daily Memory for ${data.date}\n\n`;
301
+ if (data.reports && data.reports.count > 0) {
302
+ text += `### AI Reports (${data.reports.count})\n`;
303
+ data.reports.items.forEach((report, i) => {
304
+ text += `\n**${i + 1}. ${report.title}** (${report.type}, ${report.timestamp})\n`;
305
+ text += `${report.formattedContent || report.summary}\n`;
306
+ });
307
+ }
308
+ else {
309
+ text += "No AI reports found for this date.\n";
310
+ }
311
+ return truncateIfNeeded(text);
312
+ }
313
+ async function handleGetWeeklyMemory(input) {
314
+ const endDate = String(input.end_date ?? getTodayDate());
315
+ const days = Number(input.days ?? 7);
316
+ const include = input.include ?? [
317
+ "daily_reports",
318
+ "daily_breakdown",
319
+ "top_apps",
320
+ "trends",
321
+ ];
322
+ const params = {
323
+ end_date: endDate,
324
+ days: String(days),
325
+ include: include.join(","),
326
+ };
327
+ const data = await fetchFromScreeNest("/api/weekly-report", params);
328
+ const text = typeof data === "string" ? data : JSON.stringify(data, null, 2);
329
+ return truncateIfNeeded(text);
330
+ }
331
+ async function handleGetActivity(input) {
332
+ const date = String(input.date ?? getTodayDate());
333
+ const appFilter = input.app_filter ? String(input.app_filter) : "";
334
+ const params = {
335
+ date,
336
+ include: "activities,clipboard,browser",
337
+ };
338
+ if (appFilter)
339
+ params.app_filter = appFilter;
340
+ const response = await fetchFromScreeNest("/api/daily-report", params);
341
+ if (typeof response === "string") {
342
+ throw new Error(`Unexpected string response: ${response}`);
343
+ }
344
+ const data = response;
345
+ let text = `## Activity Data for ${data.date}\n`;
346
+ if (appFilter)
347
+ text += `**Filter**: ${appFilter}\n`;
348
+ text += "\n";
349
+ if (data.activities) {
350
+ text += `### Activities\n${data.activities}\n\n`;
351
+ }
352
+ if (data.clipboard) {
353
+ text += `### Clipboard\n${JSON.stringify(data.clipboard, null, 2)}\n\n`;
354
+ }
355
+ if (data.browser) {
356
+ text += `### Browser\n${JSON.stringify(data.browser, null, 2)}\n\n`;
357
+ }
358
+ return truncateIfNeeded(text);
359
+ }
360
+ async function handleReadLtm(input) {
361
+ const section = input.section ? String(input.section) : "";
362
+ const params = {};
363
+ if (section)
364
+ params.section = section;
365
+ const response = await fetchFromScreeNest("/api/ltm", params);
366
+ if (typeof response === "string")
367
+ return response;
368
+ const data = response;
369
+ if (data.error)
370
+ throw new Error(data.error);
371
+ return truncateIfNeeded(data.content ?? "");
372
+ }
373
+ async function handleUpdateLtm(input) {
374
+ const section = String(input.section ?? "");
375
+ const content = String(input.content ?? "");
376
+ const replace = Boolean(input.replace ?? false);
377
+ if (!section || !content) {
378
+ throw new Error("section and content are required.");
379
+ }
380
+ const result = await putToScreeNest("/api/ltm", { section, content, replace });
381
+ if (result.error)
382
+ throw new Error(String(result.error));
383
+ const action = replace ? "replaced" : "appended";
384
+ return `LTM updated (${action}). Section: ${section}. Total chars: ${result.charCount ?? "?"}`;
385
+ }
386
+ // =====================
387
+ // Main Server
388
+ // =====================
389
+ async function main() {
390
+ const server = new Server({
391
+ name: SERVER_NAME,
392
+ version: SERVER_VERSION,
393
+ }, {
394
+ capabilities: {
395
+ tools: {},
396
+ },
397
+ });
398
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
399
+ return { tools };
400
+ });
401
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
402
+ const { name, arguments: args } = request.params;
403
+ const input = (args ?? {});
404
+ try {
405
+ switch (name) {
406
+ case "get_daily_memory": {
407
+ const result = await handleGetDailyMemory(input);
408
+ return { content: [{ type: "text", text: result }] };
409
+ }
410
+ case "get_weekly_memory": {
411
+ const result = await handleGetWeeklyMemory(input);
412
+ return { content: [{ type: "text", text: result }] };
413
+ }
414
+ case "get_activity": {
415
+ const result = await handleGetActivity(input);
416
+ return { content: [{ type: "text", text: result }] };
417
+ }
418
+ case "read_ltm": {
419
+ const result = await handleReadLtm(input);
420
+ return { content: [{ type: "text", text: result }] };
421
+ }
422
+ case "update_ltm": {
423
+ const result = await handleUpdateLtm(input);
424
+ return { content: [{ type: "text", text: result }] };
425
+ }
426
+ default:
427
+ return {
428
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
429
+ isError: true,
430
+ };
431
+ }
432
+ }
433
+ catch (error) {
434
+ const message = error instanceof Error ? error.message : String(error);
435
+ return {
436
+ content: [{ type: "text", text: `Error: ${message}` }],
437
+ isError: true,
438
+ };
439
+ }
440
+ });
441
+ const transport = new StdioServerTransport();
442
+ await server.connect(transport);
443
+ log("info", `${SERVER_NAME} v${SERVER_VERSION} started`);
444
+ log("info", `API endpoint: ${SCREENEST_API_BASE}`);
445
+ log("info", `Log level: ${SCREENEST_LOG_LEVEL}`);
446
+ log("info", `Request timeout: ${SCREENEST_TIMEOUT_MS}ms`);
447
+ }
448
+ main().catch((error) => {
449
+ log("error", `Fatal error: ${error instanceof Error ? error.message : String(error)}`);
450
+ process.exit(1);
451
+ });
452
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@screenest/mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for ScreeNest — query your activity tracking data, AI-generated daily/weekly reports, and Long-Term Memory from Claude Desktop, Cursor, and other MCP-compatible clients.",
5
+ "type": "module",
6
+ "main": "build/index.js",
7
+ "bin": {
8
+ "screenest-mcp": "build/index.js"
9
+ },
10
+ "files": [
11
+ "build",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc && node scripts/add-shebang.js",
17
+ "dev": "tsx src/index.ts",
18
+ "start": "node build/index.js",
19
+ "prepublishOnly": "npm run build",
20
+ "test": "node build/index.js --help"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "claude",
26
+ "claude-desktop",
27
+ "cursor",
28
+ "screenest",
29
+ "activity-tracking",
30
+ "productivity",
31
+ "time-tracking",
32
+ "long-term-memory",
33
+ "ltm"
34
+ ],
35
+ "author": {
36
+ "name": "ScreeNest Team",
37
+ "email": "support@screenest.app"
38
+ },
39
+ "license": "MIT",
40
+ "os": [
41
+ "win32"
42
+ ],
43
+ "engines": {
44
+ "node": ">=18.0.0"
45
+ },
46
+ "dependencies": {
47
+ "@modelcontextprotocol/sdk": "~1.29.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.0.0",
51
+ "tsx": "^4.0.0",
52
+ "typescript": "^5.0.0"
53
+ }
54
+ }