Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ jobs:
EOF
npm run build # This includes CSS building via npm run build-css

- name: Check Obsidian Sync bundle size budget
run: npm run check:bundle-size

- name: Verify release notes
run: |
if [ ! -f "$RELEASE_NOTES_PATH" ]; then
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,34 @@ on:
branches: [ main, develop, v3-maintenance ]

jobs:
bundle-size:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: true

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci --prefer-offline --no-audit
timeout-minutes: 5

- name: Test bundle size guard and dependency deduplication
run: node --test scripts/check-bundle-size.test.mjs scripts/bundle-dependencies.test.mjs

- name: Build production plugin
run: npm run build
timeout-minutes: 10

- name: Check Obsidian Sync bundle size budget
run: npm run check:bundle-size

test:
runs-on: ubuntu-latest
strategy:
Expand Down
35 changes: 35 additions & 0 deletions docs/HTTP_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,41 @@ Example:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/health
```

## Connecting Claude Desktop with MCP

TaskNotes 4.13.0 and later require a **TaskNotes API token**, not a Claude/Anthropic API key. The local MCP endpoint uses bearer authentication, not OAuth registration.

1. In **Settings → TaskNotes → Integrations**, enable **HTTP API** and **MCP server**.
2. To generate a TaskNotes token, leave **API authentication token** empty and restart Obsidian. An existing TaskNotes token can be reused; do not clear it unless you intend to replace it for all clients.
3. Reopen Integrations and copy the generated token. Keep it private.
4. In Claude Desktop, open **Settings → Developer → Edit Config** and add the following entry, preserving any other MCP servers:

```json
{
"mcpServers": {
"Tasknotes": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://127.0.0.1:8080/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer YOUR_TASKNOTES_API_TOKEN"
}
}
}
}
```

Replace `YOUR_TASKNOTES_API_TOKEN` with the token from TaskNotes, keeping the `Bearer ` prefix. Change `8080` if you configured a different port. This configuration requires Node.js/npm so Claude can run `npx`.

5. Fully quit and reopen Claude Desktop. Keep Obsidian running while using the tools.

If Claude reports **Server Disconnected**, or `mcp-remote` fails in `registerClient`/OAuth registration, first check that the bearer header contains the current TaskNotes token. A missing or rejected token can cause the client to attempt OAuth registration, which this endpoint does not provide. After changing the token in TaskNotes, update every client and restart Claude. Do not disable authentication as a workaround.

## Response Format

Success:
Expand Down
2 changes: 2 additions & 0 deletions docs/features/calendar-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ TaskNotes can subscribe to external calendar feeds using the iCalendar (ICS) for

Add and manage ICS subscriptions from `Settings -> TaskNotes -> Integrations` (Calendar Subscriptions section).

Cancelled events are hidden. A guest declining an invitation does not hide the meeting. When a feed's `X-WR-CALNAME` is an email address (as in many personal Google Calendar feeds), TaskNotes matches that address to the owner's `ATTENDEE` response and hides meetings they declined. Recurring exceptions can override the series response. If the feed does not identify the owner, TaskNotes keeps events visible rather than guessing whose response applies. This does not use the subscription's display name. Refresh the subscription after updating to restore previously hidden meetings.

For details on creating notes and tasks from calendar events, see [ICS Integration](ics-integration.md).

## Time Blocking
Expand Down
16 changes: 16 additions & 0 deletions docs/releases/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,24 @@ When a change has user-facing documentation, include a canonical tasknotes.dev l

-->

## Added

- (#2223, #2224) Added `task-card__metadata-date--today` and `task-card__metadata-date--future` CSS classes for due and scheduled dates. Completed past dates are not classified as future when overdue styling is hidden. Thanks to @chmac for the suggestion and contribution.

## Fixed

- (#2313) Fixed ICS meetings disappearing when another guest declined. Declined meetings are hidden only when the feed identifies the calendar owner's response; otherwise they remain visible. Refresh subscriptions after updating. See [Calendar Integration](https://tasknotes.dev/features/calendar-integration/#ics-calendar-subscriptions). Thanks to @benschifman for reporting and providing the reproduction.

- (#2203) Fixed completing or skipping a recurring instance in the edit modal creating a duplicate Google Calendar event when the scheduled date advances. Manual rescheduling still creates the appropriate moved occurrence. Thanks to @christenbc for the fix.

- (#2336) Reduced the plugin bundle below Obsidian Sync Standard's 5 MB per-file limit so it can sync between devices again, and removed duplicate bundled dependencies to leave more room for future updates. Thanks to @kmalakoff for reporting and @CyberBlaed for confirming.

- (#2335) Fixed date-like text in the current note’s folder or title being replaced when choosing a task folder with `{{currentNotePath}}` or `{{currentNoteTitle}}`. Date tokens written in the folder template still work. Thanks to @hikatamika for reporting.

- (#2301) Fixed clicking the Pomodoro timer display to edit its duration. Thanks to @minnyee for reporting and identifying the cause.

- (#2328) Fixed direct status edits on occurrence notes not updating the recurring parent’s completion history or creating the next occurrence when configured. Thanks to @mudnug for reporting this.

## Changed

- (#2329) Clarified how to generate a TaskNotes API token and configure Claude Desktop's MCP bearer authentication, including restart and token replacement instructions. See [HTTP API](https://tasknotes.dev/HTTP_API/#connecting-claude-desktop-with-mcp). Thanks to @kmaustral for reporting the setup confusion and confirming the solution.
2 changes: 2 additions & 0 deletions esbuild.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ const context = await esbuild.context({
treeShaking: true,
outfile: "main.js",
minify: prod,
// Avoid bulky Unicode escapes in translations; keep the bundle within Obsidian Sync's limit.
charset: "utf8",
plugins: [markdownPlugin, ...(!prod ? [copyToVaultPlugin] : [])],
});

Expand Down
2 changes: 1 addition & 1 deletion i18n.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@
"settings.integrations.httpApi.port.description": "b6428bfa6964ba7f4e87759cca444726cb674f67",
"settings.integrations.httpApi.port.placeholder": "7507d41ecbd162a0d6dfdaaa9988a91184351735",
"settings.integrations.httpApi.authToken.name": "1ba4dadc61225e43b73eaa19ae9c57856129ff60",
"settings.integrations.httpApi.authToken.description": "4645950dc83ea5b5601e58223affbd795b962da4",
"settings.integrations.httpApi.authToken.description": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"settings.integrations.httpApi.authToken.placeholder": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
"settings.integrations.httpApi.mcp.enable.name": "9eba0b2f5b88c4347b23d9fa6c942fc6aa0482f8",
"settings.integrations.httpApi.mcp.enable.description": "8d7793dc5646fed97cd0505769894e69227f59c4",
Expand Down
32 changes: 16 additions & 16 deletions i18n.state.json
Original file line number Diff line number Diff line change
Expand Up @@ -4865,8 +4865,8 @@
"translation": "e50713ea8f3f9cd33d13e62b2f9446506bba0ea3"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "74c173787c7db629c78eeb2bcfa56a8c053a5f05"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "2c95c0d616e6b1c3399ada537e8920463914cf19"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -13827,8 +13827,8 @@
"translation": "6fe94ef62939d4193d6fa157862ab7d5e221928d"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "c2bae8e5fb8112db9f4082e1a7b152ba60a3c6c2"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "ee31554b1740438b50b7f8fe3174a737e016d5d1"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -22789,8 +22789,8 @@
"translation": "7825b9593525f7e3ea8068d78e10507085cd174e"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "d132b21f1a09c216bce09c229759f17501d04d79"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "410d1907b9f34d269e5b6ab32b782a108f136a87"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -31751,8 +31751,8 @@
"translation": "4547f427f7ad30077971b37d14a3d18392ffb209"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "f0956cfefe9d470fa5920f96fc6a9c9fe8f34071"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "d3d849ef07f7e8aea516c17497077013941a62a5"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -40713,8 +40713,8 @@
"translation": "e3762218f782e767ec7710ad5ae8af573a53e91d"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "e102ad3dbcaec0d0599191fe1fd57751220daed8"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "08ed9f463b8d4df5ab14624b5c48fe82e0c4539b"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -49675,8 +49675,8 @@
"translation": "a290148f2f26d6fc99f0343e99f8bc1d17cf550d"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "2bf0b0029283a34afa81afbb40323a6af90e768b"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "6faf7ce9863aa5fa8ab04c0cab6df1693ccb314b"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -58637,8 +58637,8 @@
"translation": "9a20576cbad2401545a21cce3a90dc01cb77f9cf"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "dcccbcc0d0fc6924eba4be25691241a587c005fb"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "90cf59746a592a0558b5859ce552c699ff1774f1"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down Expand Up @@ -67599,8 +67599,8 @@
"translation": "a154370a00ca79783bcc05897a84f78a62897467"
},
"settings.integrations.httpApi.authToken.description": {
"source": "4645950dc83ea5b5601e58223affbd795b962da4",
"translation": "0cfe0078a28e054b5c0bf3b551e7543415979f8e"
"source": "fdd1030eecc5290a4e2bca46f8809277659f93ce",
"translation": "6b7c4ad219534e1db8691afcc8f47904933f6d9a"
},
"settings.integrations.httpApi.authToken.placeholder": {
"source": "dfd8e9adf613d1b2a46dfac755c50174ccecef4c",
Expand Down
Loading
Loading