tana-mcp-codemode 0.2.3 → 0.3.3

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/README.md CHANGED
@@ -1,314 +1,98 @@
1
- # Tana MCP Server
1
+ # tana-mcp-codemode
2
2
 
3
- A codemode MCP server for [Tana](https://tana.inc) knowledge management. AI writes TypeScript code that executes against the Tana Local API.
3
+ Codemode MCP server for [Tana](https://tana.inc). AI writes TypeScript that executes directly against the Tana Local API.
4
4
 
5
- ## Features
5
+ **Requires:** Tana Desktop with Local API enabled + an API token (Settings → API).
6
6
 
7
- - **Codemode Pattern** — AI writes executable TypeScript, not structured API calls
8
- - **Tana Local API** — Workspaces, nodes, tags, fields, calendar, import
9
- - **Top-level Await** — `await tana.workspaces.list()` works directly
10
- - **Timeout Protection** — 10s max execution prevents infinite loops
11
- - **Script History** — SQLite persistence for debugging and replay
12
- - **Retry Logic** — Exponential backoff for transient failures
13
- - **Debug UI** — WebSocket-based dashboard for testing scripts
7
+ ## Install
14
8
 
15
- ## Requirements
16
-
17
- - [Bun](https://bun.sh) runtime
18
- - [Tana Desktop](https://tana.inc) with Local API enabled
19
- - API token from Tana (Settings → API → Generate Token)
20
-
21
- ## Installation
22
-
23
- ### Option 1: bun (recommended)
24
-
25
- ```bash
26
- # Requires Bun runtime
27
- bun add -g tana-mcp-codemode
28
- ```
29
-
30
- ### Option 2: From source
9
+ **Binary** — download from [GitHub Releases](https://github.com/fabiogaliano/tana-mcp-codemode/releases), `chmod +x`, run.
31
10
 
11
+ **npm** (Node.js ≥ 20):
32
12
  ```bash
33
- git clone https://github.com/fabiogaliano/tana-mcp-codemode
34
- cd tana-mcp-codemode
35
- bun install
13
+ npm install -g tana-mcp-codemode
36
14
  ```
37
15
 
38
- ## Configuration
39
-
40
- | Variable | Default | Description |
41
- | ----------------------- | ----------------------- | -------------------------------------------------------------- |
42
- | `TANA_API_TOKEN` | (required) | Bearer token from Tana Desktop |
43
- | `TANA_API_URL` | `http://127.0.0.1:8262` | Tana Local API URL |
44
- | `TANA_TIMEOUT` | `10000` | Request timeout in ms |
45
- | `TANA_HISTORY_PATH` | (platform default) | Custom path for SQLite history database |
46
- | `MAIN_TANA_WORKSPACE` | (none) | Default workspace name or ID, resolved at startup |
47
- | `TANA_SEARCH_WORKSPACES`| (none) | Comma-separated workspace names or IDs for default search scoping |
16
+ **From source** (Bun): `git clone` → `bun install` → `bun run src/entry-bun.ts`
48
17
 
49
- ## MCP Integration
18
+ ## Setup
50
19
 
51
- Add to your MCP client's configuration:
20
+ Run the interactive setup script — detects your installation, prompts for credentials, and configures Claude Code and/or Claude Desktop automatically:
52
21
 
53
- ```json
54
- {
55
- "mcpServers": {
56
- "tana": {
57
- "command": "tana-mcp-codemode",
58
- "env": {
59
- "TANA_API_TOKEN": "your_token_here",
60
- // Optional
61
- "MAIN_TANA_WORKSPACE": "My Workspace",
62
- "TANA_SEARCH_WORKSPACES": "My Workspace",
63
- // Optional: customize where the SQLite history database is stored
64
- "TANA_HISTORY_PATH": "/path/to/history.db"
65
- }
66
- }
67
- }
68
- }
22
+ ```bash
23
+ bun run setup
24
+ # or for team-shared config:
25
+ bun run setup --scope project
69
26
  ```
70
27
 
71
- | Client | Config Location |
72
- | ----------------- | ----------------------------------------------------------- |
73
- | Claude Desktop | `claude_desktop_config.json` |
74
- | Claude Code | `.mcp.json` (project) or `~/.claude/settings.json` (global) |
75
- | Cursor / Windsurf | IDE MCP settings |
76
-
77
- **If installed from source**, use `bun` as the command:
28
+ ## Manual MCP Configuration
78
29
 
79
30
  ```json
80
31
  {
81
32
  "mcpServers": {
82
33
  "tana": {
83
- "command": "bun",
84
- "args": ["run", "/path/to/tana-mcp-codemode/src/index.ts"],
34
+ "command": "tana-mcp-codemode",
85
35
  "env": {
86
- "TANA_API_TOKEN": "your_token_here",
87
- // Optional
88
- "MAIN_TANA_WORKSPACE": "My Workspace",
89
- "TANA_SEARCH_WORKSPACES": "My Workspace",
90
- // Optional: customize where the SQLite history database is stored
91
- "TANA_HISTORY_PATH": "/path/to/history.db"
36
+ "TANA_API_TOKEN": "your-token-here",
37
+ "MAIN_TANA_WORKSPACE": "My Workspace"
92
38
  }
93
39
  }
94
40
  }
95
41
  }
96
42
  ```
97
43
 
98
- ## Examples
44
+ For binary: set `command` to the binary path. For source: `"command": "bun", "args": ["run", "/path/to/src/entry-bun.ts"]`.
99
45
 
100
- ### Search for nodes
46
+ ## Environment Variables
101
47
 
102
- ```typescript
103
- const results = await tana.nodes.search({
104
- textContains: "meeting notes"
105
- });
106
- console.log("Found:", results.length, "nodes");
107
- ```
48
+ | Variable | Default | Description |
49
+ |----------|---------|-------------|
50
+ | `TANA_API_TOKEN` | required | Bearer token from Tana Desktop |
51
+ | `TANA_API_URL` | `http://127.0.0.1:8262` | Tana Local API URL |
52
+ | `MAIN_TANA_WORKSPACE` | — | Default workspace name or ID |
53
+ | `TANA_SEARCH_WORKSPACES` | — | Comma-separated workspaces for search scope |
54
+ | `TANA_TIMEOUT` | `10000` | Request timeout in ms |
55
+ | `TANA_HISTORY_PATH` | platform default | Custom SQLite history path |
108
56
 
109
- ### Complex query
57
+ ## Usage Examples
110
58
 
111
59
  ```typescript
112
- const tasks = await tana.nodes.search({
113
- and: [
114
- { hasType: "taskTagId" },
115
- { is: "todo" },
116
- { created: { last: 7 } }
117
- ]
60
+ // Search nodes
61
+ const results = await tana.nodes.search("project ideas", {
62
+ workspaceIds: [tana.workspace.id]
118
63
  });
119
- console.log({ tasks });
120
- ```
121
-
122
- ### Import content
123
64
 
124
- ```typescript
125
- await tana.import(parentNodeId, `
126
- - Project Alpha #[[^projectTagId]]
127
- - [[^statusFieldId]]:: Active
128
- - [[^dueDateFieldId]]:: [[date:2024-03-15]]
65
+ // Import with tags and fields
66
+ await tana.import(tana.workspace.id, `
67
+ %%tana%%
68
+ - Meeting notes #meeting
69
+ - Date:: [[2024-01-15]]
70
+ - Attendees:: Alice, Bob
129
71
  `);
130
72
  ```
131
73
 
132
- ## Debug UI
133
-
134
- A WebSocket-based dashboard for testing scripts:
135
-
136
- ```bash
137
- # Start debug server
138
- bun run src/debug-server.ts
139
-
140
- # Open http://localhost:3333
141
- ```
142
-
143
- **Routes:**
144
- - `http://localhost:3333/#debug` — Script execution console
145
- - `http://localhost:3333/#benchmark` — Codemode vs tana-local performance comparison
146
-
147
- **Features:**
148
- - Real-time script execution
149
- - Workflow event timeline
150
- - Error display with suggestions
151
- - Benchmark results visualization (cost, speed, token usage)
152
-
153
- ### workflow Helper (Debug UI only)
154
-
155
- Track multi-step operations with a timeline view:
156
-
157
- ```typescript
158
- workflow.start("Processing nodes");
159
- workflow.step("Fetching workspaces");
160
- workflow.progress(5, 100, "Processing");
161
- workflow.complete("Done!");
162
- // Or: workflow.abort("Error message");
163
- ```
164
-
165
- > **Note**: `workflow` is only available in the Debug UI. It's not exposed in the production MCP prompt.
166
-
167
- ### Building the React UI (optional)
168
-
169
- ```bash
170
- cd ui
171
- bun install
172
- bun run build
173
- cd ..
174
- bun run src/debug-server.ts
175
- ```
176
-
177
- ## Architecture
178
-
179
- ```
180
- src/
181
- ├── index.ts # MCP server entry
182
- ├── prompts.ts # Tool description
183
- ├── types.ts # TypeScript interfaces
184
- ├── debug-server.ts # WebSocket debug UI
185
- ├── api/
186
- │ ├── client.ts # HTTP client (auth, retry, timeouts)
187
- │ ├── tana.ts # API wrapper → `tana` object
188
- │ └── types.ts # API type definitions
189
- ├── sandbox/
190
- │ ├── executor.ts # Code execution engine
191
- │ └── workflow.ts # Progress tracking
192
- ├── storage/
193
- │ └── history.ts # SQLite script history
194
- └── generated/
195
- └── api.d.ts # Generated OpenAPI types
196
-
197
- ui/ # React debug dashboard
198
- ```
199
-
200
- ### How It Works
201
-
202
- 1. AI sends TypeScript code to the `execute` tool
203
- 2. `executor.ts` creates an AsyncFunction for top-level await
204
- 3. Code runs with injected `tana` and `console` objects
205
- 4. 10s timeout via Promise.race prevents hangs
206
- 5. `console.log()` output is captured and returned
207
- 6. Script run is saved to SQLite history
208
-
209
- ## Script History
210
-
211
- Runs are persisted to SQLite:
212
-
213
- | Platform | Location |
214
- | -------- | --------------------------------------------------- |
215
- | macOS | `~/Library/Application Support/tana-mcp/history.db` |
216
- | Windows | `%APPDATA%/tana-mcp/history.db` |
217
- | Linux | `~/.local/share/tana-mcp/history.db` |
218
-
219
- Old runs (>30 days) are automatically cleaned up on startup.
220
-
221
- ### What Gets Saved
222
-
223
- Each script run records:
74
+ ## API Reference
224
75
 
225
- | Field | Description |
226
- | ------------------- | ------------------------------------- |
227
- | `script` | The TypeScript code that was executed |
228
- | `output` | Captured `console.log()` output |
229
- | `error` | Error message if execution failed |
230
- | `api_calls` | Which Tana API methods were called |
231
- | `node_ids_affected` | Node IDs that were read/modified |
232
- | `workspace_id` | Workspace used (if detected) |
233
- | `duration_ms` | Execution time |
76
+ | Namespace | Methods |
77
+ |-----------|---------|
78
+ | `tana.workspace` | pre-resolved default workspace |
79
+ | `tana.workspaces` | `list()` |
80
+ | `tana.nodes` | `search()`, `read()`, `getChildren()`, `edit()`, `move()`, `trash()`, `check()`, `uncheck()`, `open()` |
81
+ | `tana.tags` | `listAll()`, `getSchema()`, `create()`, `modify()`, `addField()`, `setCheckbox()` |
82
+ | `tana.fields` | `setOption()`, `setContent()`, `getFieldOptions()` |
83
+ | `tana.calendar` | `getOrCreate()` |
84
+ | `tana.import()` | import Tana Paste content |
85
+ | `tana.health()` | API health check |
234
86
 
235
87
  ## Development
236
88
 
237
89
  ```bash
238
- # Dev mode with watch
239
- bun run dev
240
-
241
- # Type check
242
- bun run typecheck
243
-
244
- # Regenerate API types from OpenAPI spec
245
- bun run generate
246
-
247
- # Run debug server
248
- bun run debug
249
- ```
250
-
251
- ## API Reference
252
-
253
- The server exposes a single `execute` tool. AI writes TypeScript code with access to the `tana` object:
254
-
255
- ### Workspaces
256
-
257
- ```typescript
258
- const workspaces = await tana.workspaces.list();
259
- // → Workspace[] (id, name, homeNodeId)
260
- ```
261
-
262
- ### Nodes
263
-
264
- ```typescript
265
- await tana.nodes.search(query, options?) // → SearchResult[]
266
- await tana.nodes.read(nodeId, maxDepth?) // → string (markdown)
267
- await tana.nodes.getChildren(nodeId, opts?) // → { children, total, hasMore }
268
- await tana.nodes.edit({ nodeId, name?, description? })
269
- await tana.nodes.trash(nodeId)
270
- await tana.nodes.check(nodeId) // mark done
271
- await tana.nodes.uncheck(nodeId) // mark undone
272
- ```
273
-
274
- ### Tags (Supertags)
275
-
276
- ```typescript
277
- await tana.tags.listAll(workspaceId) // All workspace supertags (paginated)
278
- await tana.tags.getSchema(tagId, opts?) // opts: { includeInheritedFields? }
279
- await tana.tags.modify(nodeId, action, tagIds) // action: "add" | "remove"
280
- await tana.tags.create({ workspaceId, name, description?, extendsTagIds?, showCheckbox? })
281
- await tana.tags.addField({ tagId, name, dataType, ... })
282
- await tana.tags.setCheckbox({ tagId, showCheckbox, doneStateMapping? })
283
- ```
284
-
285
- ### Fields
286
-
287
- ```typescript
288
- await tana.fields.setOption(nodeId, attributeId, optionId) // dropdown fields
289
- await tana.fields.setContent(nodeId, attributeId, content) // text/date/url fields
290
- ```
291
-
292
- ### Calendar
293
-
294
- ```typescript
295
- await tana.calendar.getOrCreate(workspaceId, granularity, date?)
296
- // granularity: "day" | "week" | "month" | "year"
297
- ```
298
-
299
- ### Import (Tana Paste)
300
-
301
- ```typescript
302
- await tana.import(parentNodeId, tanaPasteContent)
303
- // → { success, nodeIds?, error? }
304
- ```
305
-
306
- ### Utility
307
-
308
- ```typescript
309
- tana.workspace // Pre-resolved default workspace (from MAIN_TANA_WORKSPACE) or null
310
- tana.format(data) // Compact display of any API response
311
- await tana.health() // → { status: "ok" }
90
+ bun run start # MCP server
91
+ bun run dev # watch mode
92
+ bun run test # tests
93
+ bun run build # Node.js dist (tsup)
94
+ bun run build:binary # self-contained binary
95
+ bun run debug # debug UI at :3333
312
96
  ```
313
97
 
314
98
  ## License