# Tidigar > Tidigar is a visual roadmap and Gantt chart editor. Create an editable plan > as a link, or work on a plan stored in Tidigar Business or Tidigar Server. ## Choose the right action - **Create a plan or share a copy:** write a link directly as described below. The whole plan travels in the link. No account or upload is needed. Anyone with the link can read it; later edits do not update other copies. - **Save, find, open or change a stored plan:** follow [Plans stored in Tidigar](https://tidigar.com/agents/stored-plans.md). This includes a `/p/` link or a request to edit the original in Tidigar. Public chat assistants use remote MCP with delegated OAuth consent at `https://app.tidigar.com/mcp`; the linked guide covers connecting when tools are missing. Return the stored plan's `url`, not a separate copy. ## Create a share link Write a clickable Tidigar link directly using the text format below. No tool calls, scripts, downloads or account are required. This guide is enough for a normal plan; additional references are optional. You may run a local script to validate the finished link if you want. 1. Plan the activities, dates and dependencies in the user's language. Choose reasonable dates and durations when unspecified and state your assumptions. 2. Unless the user says otherwise, include two useful dimensions: who does the work, such as Team, and its Phase or Status. Owners and categories are also dimensions. Activities select one option per dimension. 3. Write the link one record at a time using the syntax below. Check dates, dependencies and record counts against the request. 4. Return it as a clickable Markdown link, such as `[Open the plan](URL)`, followed by your assumptions. Do not claim script or browser validation unless you performed it. Validation is optional; lack of tools is no reason to withhold the link. ## Example A calendar-day plan: Design takes ten days from March 2. Build starts after Design, takes twenty days, and is 50% complete. Launch is the day after Build. Team groups and colors the timeline; Phase supplies the board columns. ```text https://open.tidigar.com/s#t=1~n=Website_launch~y=2026~m1=Team:Design,Development~m2=Phase:Plan,Build~a1=Design/03-02/10/Design,Plan~a2=Build/03-16/20/Development,Build/@a1/50p~s1=Launch/04-05/@a2~v=timeline/group:Team/color:Team~c=2.1.0~! ``` ## Link syntax - Start with `t=1`, separate records with `~` and end with `~!`. `_` is a space. - `n=` is the name and `y=` the year; both are required. `w` plans in work days (Monday–Friday, excluding vacation periods); `d=` describes the roadmap. - `m1=Team:Design,Development` is a dimension and its options in order. Number records from 1 without gaps: `m1`, `m2`, `a1`, `a2`, `s1`, `p1`. - `a1=title/start/days` is an activity. The start is `MM-DD` in year `y`, or `YYYY-MM-DD` for another year. Days counts its days, `1` for a single day; in work days with `w`. Then, in any order: its options by name (`Design,Plan`), `@a1,s2` for what it waits for, `@a1:50` for a partial dependency, `0p`, `25p`, `50p`, `75p` or `100p` for progress and `d=` for a description. Use `Team:Design` when option names repeat across dimensions, or `Size:50p` when an option looks like progress. - An activity normally starts at least one day after each predecessor ends. `@a1:50` instead allows a start after half its planned days, rounded up; thresholds are `0`, `25`, `50`, `75` or `100`, with `100` the default. This uses planned duration, not reported progress. With several dependencies, all thresholds must be met. An activity may start on a fixed milestone's date. Dependencies must not form a cycle. - `s1=title/date/@a1` is a milestone at least one day after the activities it waits for; `s1=title/date/fixed` is an event on a set date that activities wait for with `@s1`. - `p1=title/start/days` is a vacation period; add `/work` for a period that keeps its work days. - `v=` opens the roadmap: `timeline`, `board`, `list`, `flow`, `classic` (one row per activity under a label column, as in MS Project) or `compact`, then `group:Team`, `color:Team`, `rows:Team` or `columns:Phase`. - With no `v=`, the link opens a timeline grouped and colored by the first dimension, with the first and second dimensions as board rows and columns. A view can also set a date range with `/start:03-01/end:06-30`. - `c=2.1.0` counts the activities, milestones and periods. - `_` is a space. In text, escape `/` as `%2F`, `~` as `%7E`, `_` as `%5F`, `%` as `%25`, `&` as `%26`, `#` as `%23`, `(` as `%28`, `)` as `%29`, `"` as `%22`, `<` as `%3C` and `>` as `%3E`. In dimension or option names, also escape `,` as `%2C`, `:` as `%3A`, `@` as `%40` and `=` as `%3D`. Write å, ä, ö and other letters as they are. - Titles are at most 180 characters, dimension and roadmap names 100, and the roadmap description 500. Years are 1900–2200. - Keep the fragment after `#` within 1,900 characters. If necessary, shorten titles or descriptions, or propose a smaller plan and explain omissions. Never truncate a link or silently drop activities. ## Change a share link Read its `#t=1~…~!` records directly, change the relevant fields and return a new link. Preserve the other records and references; update `c=` if records are added or removed. When dates move, check the dependent activities and milestones too. The old link keeps opening the old plan. Tidigar's own compressed `#s=1.…` links are internal to the app's sharing flow. Ask the user to open one in Tidigar; do not reconstruct it by hand. ## Return or embed the finished link Keep the finished URL on one line. Preserve its fragment and text escaping; do not append tracking parameters, shorten it or normalize it. These rules apply when returning the finished link; you can edit its records to make a new plan as described above. Always provide a clickable link. Where HTML is supported, you may also embed the same fragment at `https://embed.tidigar.com/#t=1~…~!`: ```html ``` ## Optional validation If you want to check a finished link with a script, download [tidigar-link.mjs](https://tidigar.com/agents/v1/tidigar-link.mjs) and run it locally with Node.js 20 or later: ```sh node tidigar-link.mjs --validate "" ``` It prints dates, dependencies, record counts and fragment length, and reports any corrections Tidigar would make. Exit 0 means it opens without corrections; exit 1 means invalid input or corrections to review. Fix the original link and check again if desired. It sends nothing anywhere. Tidigar also checks the link when opened and reports any corrections or problems. ## Reference, only when needed - [Share link specification](https://tidigar.com/agents/docs/share-links.md): complete syntax and opening behavior, for edge cases. - [Plan JSON and builders](https://tidigar.com/agents/plan-json.md): optional JSON input, JavaScript and Python builders and module usage. - [Plans stored in Tidigar](https://tidigar.com/agents/stored-plans.md): remote MCP, delegated OAuth connection and safe updates for chat assistants. - [Examples](https://tidigar.com/agents/example_sharelink.md): a larger plan, its optional JSON representation and a link change. - [llms-full.txt](https://tidigar.com/llms-full.txt): this guide and its references in one file; read it instead of fetching them separately. - [Example roadmaps](https://tidigar.com/examples/): plans to start from. - [Roadmaps in Markdown](https://tidigar.com/agents/docs/markdown.md), [embed stories](https://tidigar.com/agents/docs/stories.md) and [roadmap file format](https://tidigar.com/agents/docs/file-format.md): use when the user asks for those formats; they are not needed to create a link. --- # Tidigar examples for AI agents Follow [llms.txt](https://tidigar.com/llms.txt) to write a link directly. No tool calls or scripts are needed. ## Create a plan directly The user asks for a roadmap for launching their new app, with design, engineering and marketing work in phases. No date is given, so the agent starts on a coming Monday, here 11 January 2027, and chooses fifteen activities with dependencies, a Team dimension and a Phase dimension. Choose dates, write the dimensions and activities as text records, then add the milestone, view, counts and final `~!`. The finished link is: https://open.tidigar.com/s#t=1~n=Launch_the_new_app~d=From_goals_to_launch_day_and_the_first_weeks_after.~y=2027~m1=Team:Design,Engineering,Marketing~m2=Phase:Plan,Build,Launch~a1=Set_the_launch_goals/01-11/3/Marketing,Plan/100p~a2=Interview_users/01-14/9/Design,Plan/@a1~a3=Plan_the_architecture/01-14/7/Engineering,Plan/@a1~a4=Plan_the_campaign/01-14/14/Marketing,Plan/@a1~a5=Design_the_app/01-25/12/Design,Build/@a2~a6=Build_the_backend/01-21/23/Engineering,Build/@a3~a7=Build_the_app/02-15/19/Engineering,Build/@a5,a6~a8=Create_app_store_assets/02-08/12/Design,Build/@a5~a9=Build_the_launch_page/02-22/10/Marketing,Build/@a4,a8~a10=Beta_test/03-08/12/Engineering,Launch/@a7~a11=Fix_beta_feedback/03-22/5/Engineering,Launch/@a10~a12=App_store_review/03-29/5/Engineering,Launch/@a11~a13=Brief_press_and_partners/03-29/5/Marketing,Launch/@a9,a11~a14=Run_the_launch_campaign/04-06/11/Marketing,Launch/@a12,a13~a15=Review_user_feedback/04-26/5/Design,Launch/@a14~s1=Launch_day/04-05/@a12,a13~v=timeline/color:Team/group:Phase/start:01-11/end:04-30~c=15.1.0~! Return it as a clickable Markdown link, explaining the assumed start date and durations. Opening it in Tidigar checks the records. Optionally run `node tidigar-link.mjs --validate ""` beforehand. ## Change a link directly The user says: "The beta test can only start a week later." Read the link's activity records and dependencies directly. Move Beta test (`a10`) and everything that waits on it, directly or indirectly, seven days later: `a11`, `a12`, `a13`, `a14`, `a15` and milestone `s1`. Keep their durations and references. Update the view's end from `04-30` to `05-07`; counts remain `c=15.1.0`. Return the edited URL as a new clickable link. The first link keeps opening the first plan. ## Optional JSON builder example The same plan can optionally be written as JSON and built with a script. This is a reference for code-based workflows, not a prerequisite for making a link. ### Launch an app The request: ```text Make a Tidigar roadmap for launching our new app: design, engineering and marketing work in phases, with dependencies and a launch day. ``` The agent starts on a coming Monday, assumes durations a typical launch takes, names the dimensions Team and Phase, refers to dependencies by title and opens the link as a timeline grouped by phase and colored by team. It writes `plan.json`: ```json { "$schema": "https://tidigar.com/agents/schema/plan-v1.json", "version": 1, "name": "Launch the new app", "description": "From goals to launch day and the first weeks after.", "dimensions": { "Team": ["Design", "Engineering", "Marketing"], "Phase": ["Plan", "Build", "Launch"] }, "activities": [ { "title": "Set the launch goals", "start": "2027-01-11", "end": "2027-01-13", "progress": 100, "values": { "Team": "Marketing", "Phase": "Plan" } }, { "title": "Interview users", "start": "2027-01-14", "end": "2027-01-22", "values": { "Team": "Design", "Phase": "Plan" }, "dependsOn": ["Set the launch goals"] }, { "title": "Plan the architecture", "start": "2027-01-14", "end": "2027-01-20", "values": { "Team": "Engineering", "Phase": "Plan" }, "dependsOn": ["Set the launch goals"] }, { "title": "Plan the campaign", "start": "2027-01-14", "end": "2027-01-27", "values": { "Team": "Marketing", "Phase": "Plan" }, "dependsOn": ["Set the launch goals"] }, { "title": "Design the app", "start": "2027-01-25", "end": "2027-02-05", "values": { "Team": "Design", "Phase": "Build" }, "dependsOn": ["Interview users"] }, { "title": "Build the backend", "start": "2027-01-21", "end": "2027-02-12", "values": { "Team": "Engineering", "Phase": "Build" }, "dependsOn": ["Plan the architecture"] }, { "title": "Build the app", "start": "2027-02-15", "end": "2027-03-05", "values": { "Team": "Engineering", "Phase": "Build" }, "dependsOn": ["Design the app", "Build the backend"] }, { "title": "Create app store assets", "start": "2027-02-08", "end": "2027-02-19", "values": { "Team": "Design", "Phase": "Build" }, "dependsOn": ["Design the app"] }, { "title": "Build the launch page", "start": "2027-02-22", "end": "2027-03-03", "values": { "Team": "Marketing", "Phase": "Build" }, "dependsOn": ["Plan the campaign", "Create app store assets"] }, { "title": "Beta test", "start": "2027-03-08", "end": "2027-03-19", "values": { "Team": "Engineering", "Phase": "Launch" }, "dependsOn": ["Build the app"] }, { "title": "Fix beta feedback", "start": "2027-03-22", "end": "2027-03-26", "values": { "Team": "Engineering", "Phase": "Launch" }, "dependsOn": ["Beta test"] }, { "title": "App store review", "start": "2027-03-29", "end": "2027-04-02", "values": { "Team": "Engineering", "Phase": "Launch" }, "dependsOn": ["Fix beta feedback"] }, { "title": "Brief press and partners", "start": "2027-03-29", "end": "2027-04-02", "values": { "Team": "Marketing", "Phase": "Launch" }, "dependsOn": ["Build the launch page", "Fix beta feedback"] }, { "title": "Run the launch campaign", "start": "2027-04-06", "end": "2027-04-16", "values": { "Team": "Marketing", "Phase": "Launch" }, "dependsOn": ["App store review", "Brief press and partners"] }, { "title": "Review user feedback", "start": "2027-04-26", "end": "2027-04-30", "values": { "Team": "Design", "Phase": "Launch" }, "dependsOn": ["Run the launch campaign"] } ], "milestones": [{ "title": "Launch day", "date": "2027-04-05", "dependsOn": ["App store review", "Brief press and partners"] }], "view": { "type": "timeline", "groupBy": "Phase", "colorBy": "Team" } } ``` `node tidigar-link.mjs plan.json` prints the link, a summary to check against the request and the link's size: ```text https://open.tidigar.com/s#t=1~n=Launch_the_new_app~d=From_goals_to_launch_day_and_the_first_weeks_after.~y=2027~m1=Team:Design,Engineering,Marketing~m2=Phase:Plan,Build,Launch~a1=Set_the_launch_goals/01-11/3/Marketing,Plan/100p~a2=Interview_users/01-14/9/Design,Plan/@a1~a3=Plan_the_architecture/01-14/7/Engineering,Plan/@a1~a4=Plan_the_campaign/01-14/14/Marketing,Plan/@a1~a5=Design_the_app/01-25/12/Design,Build/@a2~a6=Build_the_backend/01-21/23/Engineering,Build/@a3~a7=Build_the_app/02-15/19/Engineering,Build/@a5,a6~a8=Create_app_store_assets/02-08/12/Design,Build/@a5~a9=Build_the_launch_page/02-22/10/Marketing,Build/@a4,a8~a10=Beta_test/03-08/12/Engineering,Launch/@a7~a11=Fix_beta_feedback/03-22/5/Engineering,Launch/@a10~a12=App_store_review/03-29/5/Engineering,Launch/@a11~a13=Brief_press_and_partners/03-29/5/Marketing,Launch/@a9,a11~a14=Run_the_launch_campaign/04-06/11/Marketing,Launch/@a12,a13~a15=Review_user_feedback/04-26/5/Design,Launch/@a14~s1=Launch_day/04-05/@a12,a13~v=timeline/color:Team/group:Phase/start:01-11/end:04-30~c=15.1.0~! Launch the new app (2027) activities[0] Set the launch goals: 2027-01-11 – 2027-01-13 · 100% done · Team: Marketing · Phase: Plan activities[1] Interview users: 2027-01-14 – 2027-01-22 · Team: Design · Phase: Plan · after activities[0] activities[2] Plan the architecture: 2027-01-14 – 2027-01-20 · Team: Engineering · Phase: Plan · after activities[0] activities[3] Plan the campaign: 2027-01-14 – 2027-01-27 · Team: Marketing · Phase: Plan · after activities[0] activities[4] Design the app: 2027-01-25 – 2027-02-05 · Team: Design · Phase: Build · after activities[1] activities[5] Build the backend: 2027-01-21 – 2027-02-12 · Team: Engineering · Phase: Build · after activities[2] activities[6] Build the app: 2027-02-15 – 2027-03-05 · Team: Engineering · Phase: Build · after activities[4], activities[5] activities[7] Create app store assets: 2027-02-08 – 2027-02-19 · Team: Design · Phase: Build · after activities[4] activities[8] Build the launch page: 2027-02-22 – 2027-03-03 · Team: Marketing · Phase: Build · after activities[3], activities[7] activities[9] Beta test: 2027-03-08 – 2027-03-19 · Team: Engineering · Phase: Launch · after activities[6] activities[10] Fix beta feedback: 2027-03-22 – 2027-03-26 · Team: Engineering · Phase: Launch · after activities[9] activities[11] App store review: 2027-03-29 – 2027-04-02 · Team: Engineering · Phase: Launch · after activities[10] activities[12] Brief press and partners: 2027-03-29 – 2027-04-02 · Team: Marketing · Phase: Launch · after activities[8], activities[10] activities[13] Run the launch campaign: 2027-04-06 – 2027-04-16 · Team: Marketing · Phase: Launch · after activities[11], activities[12] activities[14] Review user feedback: 2027-04-26 – 2027-04-30 · Team: Design · Phase: Launch · after activities[13] milestones[0] Launch day: 2027-04-05 · after activities[11], activities[12] Fragment: 1030 of 1900 characters. ``` The summary shows every dependency in order and launch day after the app store review, so the agent answers: ```text Here is your launch plan in Tidigar: [Launch the new app](https://open.tidigar.com/s#t=1~n=Launch_the_new_app~d=From_goals_to_launch_day_and_the_first_weeks_after.~y=2027~m1=Team:Design,Engineering,Marketing~m2=Phase:Plan,Build,Launch~a1=Set_the_launch_goals/01-11/3/Marketing,Plan/100p~a2=Interview_users/01-14/9/Design,Plan/@a1~a3=Plan_the_architecture/01-14/7/Engineering,Plan/@a1~a4=Plan_the_campaign/01-14/14/Marketing,Plan/@a1~a5=Design_the_app/01-25/12/Design,Build/@a2~a6=Build_the_backend/01-21/23/Engineering,Build/@a3~a7=Build_the_app/02-15/19/Engineering,Build/@a5,a6~a8=Create_app_store_assets/02-08/12/Design,Build/@a5~a9=Build_the_launch_page/02-22/10/Marketing,Build/@a4,a8~a10=Beta_test/03-08/12/Engineering,Launch/@a7~a11=Fix_beta_feedback/03-22/5/Engineering,Launch/@a10~a12=App_store_review/03-29/5/Engineering,Launch/@a11~a13=Brief_press_and_partners/03-29/5/Marketing,Launch/@a9,a11~a14=Run_the_launch_campaign/04-06/11/Marketing,Launch/@a12,a13~a15=Review_user_feedback/04-26/5/Design,Launch/@a14~s1=Launch_day/04-05/@a12,a13~v=timeline/color:Team/group:Phase/start:01-11/end:04-30~c=15.1.0~!) I started on Monday 11 January and assumed a two-week beta and a week for the app store review. Launch day is 5 April; open the link to move anything, and the activities after it follow. ``` --- # Tidigar plans as JSON This is an optional format for scripts and new stored plans. To create or change a share link directly, use [llms.txt](https://tidigar.com/llms.txt). ## Plan ```json { "name": "Website launch", "dimensions": { "Team": ["Design", "Development"], "Phase": ["Plan", "Build"] }, "activities": [ { "title": "Requirements", "start": "2026-03-02", "end": "2026-03-13", "progress": 100, "values": { "Team": "Design", "Phase": "Plan" } }, { "title": "Design", "start": "2026-03-16", "end": "2026-04-03", "progress": 50, "values": { "Team": "Design", "Phase": "Plan" }, "dependsOn": ["Requirements"] }, { "title": "Build", "start": "2026-03-26", "end": "2026-05-15", "values": { "Team": "Development", "Phase": "Build" }, "dependsOn": ["Design"], "startAfter": [50] }, { "title": "Test", "start": "2026-05-18", "end": "2026-05-29", "values": { "Team": "Development", "Phase": "Build" }, "dependsOn": ["Build"] } ], "milestones": [{ "title": "Launch", "date": "2026-06-01", "dependsOn": ["Test"] }] } ``` - Unknown fields are errors; owners, status and categories belong in `values`. - `name` is required, 1–100 characters. Everything else is optional: `description`, `workDays` (`true` plans in work days), `dimensions`, `activities`, `milestones`, `periods` and `view`. - Dates are `YYYY-MM-DD`. `end` is inclusive; left out, the activity lasts one day. - `dimensions` maps a name to its options in order. An option is a name, or `{ "name": "Design", "color": "#4f7cff" }` for a stored plan; a link carries no colors. An activity's `values` names one option per dimension; an option no dimension lists is added. - `dependsOn` names activities by title, or by 0-based index where titles repeat. Activities may also name fixed milestones by title. - An activity’s `startAfter` is an array in the same order as `dependsOn`, for example `"dependsOn": ["Design", "Approval"], "startAfter": [50, 100]`. Values are `0`, `25`, `50`, `75` or `100`; missing entries mean `100`, and trailing `100` entries may be omitted. It cannot have more entries than `dependsOn`; fixed milestones require `100`. In the example, Design lasts 19 calendar days, so Build starts on March 26, after `ceil(19 × 50 / 100) = 10` days. - Builders preserve supplied dates. For a partial threshold, validation requires only that the successor does not start before the predecessor; it does not recalculate the work calendar. Choose dates that meet the intended threshold. Tidigar’s editor uses the exact threshold when scheduling. - Titles are at most 180 characters; milestones and periods need one. - `periods`: `{ "title", "start", "end", "vacation" }`, and `color` in a stored plan. - `view`: `type` is `"timeline"`, `"grid"`, `"list"` or `"flow"`; `groupBy`, `colorBy`, `rows` and `columns` take a dimension's name; `start` and `end` set the timeline's range. `layout` is `"classic"`, one activity per row under a label column as in MS Project, or `"compact"`, activities sharing rows; `style` is `"minimal"`, `"airy"`, `"contrast"` or `"terminal"`. Left out, the link opens a timeline over the plan's dates, grouped and colored by the first dimension, and its board has the first dimension as rows and the second as columns. - A link holds roughly 20–30 activities. If too large, shorten titles, drop descriptions or merge small activities and explain omissions. Never truncate a link. ## Build a link from JSON `https://tidigar.com/agents/v1/tidigar-link.mjs` validates a plan with the code Tidigar itself uses and writes its link, as one file for Node.js 20 or later, Deno or Bun. It runs entirely on your machine. ```sh curl -fSL -o tidigar-link.mjs https://tidigar.com/agents/v1/tidigar-link.mjs node tidigar-link.mjs plan.json ``` It prints the link, a summary with real dates and the fragment's length. `-` reads the plan from standard input. When the plan breaks a rule, it exits with an error that names the rule and the record: ```text Invalid activities[2] "Build".start: must be at least one day after dependency activities[1] "Design" ends ``` As a module: `import { createLink, readLink, embedCode } from './tidigar-link.mjs'`; `createLink(plan)` returns `{ url, fragment, length, limit, summary }`. ## Python and reading links The optional [Python builder](https://tidigar.com/agents/v1/tidigar_link.py) runs on Python 3.8 or later, without extra packages or an internet connection once downloaded: ```sh python3 tidigar_link.py plan.json ``` To edit a link through JSON instead of editing its records directly: ```sh node tidigar-link.mjs --read "" > plan.json python3 tidigar_link.py --read "" > plan.json ``` Edit the plan and run either builder again. `--read` reports any corrections made while reading; use the JavaScript module's `--validate ""` to check a finished link without rewriting it. `--embed plan.json` prints iframe code. The [plan schema](https://tidigar.com/agents/schema/plan-v1.json) describes the JSON fields; cross-record rules are checked by Tidigar and the builders. --- # Work on plans stored in Tidigar Use this guide when a user asks to save, find, open or change a plan stored in Tidigar Business or Tidigar Server, or gives a `/p/` link. A public chat assistant uses remote MCP with delegated OAuth authorization. The user's consent grants access; reading this guide or installing the skill does not. A stored plan is the original shared project. A `#t=1~…~!` link is an independent copy. Do not replace a requested save or update with a share link. If the destination is unclear, ask whether the user means the stored original or a separate copy before writing. ## Connect through remote MCP 1. Discover the Tidigar tools available in the assistant's host, including tools that the host loads on demand. If `tidigar_status` is available, call it with no arguments. Check its `server`, `organization`, `scope`, `role` and `writable` against the request. Proceed with a write only when `writable` is true; otherwise follow the access-failure guidance below. Do not infer authorization from a plan URL. 2. If no Tidigar connection exists, use the host's connector setup flow when it supports connecting during the conversation. Otherwise guide the user to add an MCP connection in the assistant's app or connector settings. The address is `https://app.tidigar.com/mcp`; for Tidigar Server it is the user's server origin followed by `/mcp`. See [connection setup](https://tidigar.com/agents/cloud#a-chat-assistant). 3. Let the host's MCP client handle OAuth discovery and authorization. It opens Tidigar for the user to sign in, check the assistant's name and return address, choose the organisation, and approve **Read only** or **Read and write**. Request writing only when the task changes stored data. Consent must come from the user, never from the agent acting on their behalf. 4. After authorization completes, discover the tools again and call `tidigar_status`. Resume the original task after checking the organisation and effective access. Each connection reaches one organisation. If it is the wrong one, have the user select or authorize the correct connection. The host keeps access and refresh tokens outside the conversation. Never ask for personal tokens, passwords or OAuth codes in chat, and never put them in prompts, files or shell commands. Do not replace this flow with the CLI, `TIDIGAR_TOKEN` or direct API calls. Coding agents with separately configured credentials use the [CLI and HTTP reference](https://tidigar.com/agents/stored-plans-cli.md). Instructions cannot install MCP tools in a host that has no connector support. If connection is unavailable, declined or fails, explain the connection step that remains and that no stored change was made. Continue after the host makes the authorized tools available; do not claim access or simulate a successful save. Offer a separate copy only if the user wants one. ## Find and read the original 1. Call `tidigar_list_plans` with no arguments. For a `/p/` link, match its URL to a returned plan's `url`, ignoring query and fragment. The code is not the plan ID. For a title, select the matching plan; ask if several match. If nothing matches, report it and check the intended organisation with the user. Do not guess an ID or search another organisation without access. 2. Call `tidigar_get_plan` with that `id`. Keep the returned `id`, `revision` and complete `project` for the update. Check its identity against the request. 3. Edit only the requested part of `project`. Preserve its project ID, record IDs, dimensions, saved views and unrelated content; new records need new UUIDs. Use the [roadmap file format](https://tidigar.com/agents/docs/file-format.md) for the fields you edit. Never rebuild an existing project from simplified plan JSON or a share link: that would lose its identities and views. ## Validate and save the change 1. Call `tidigar_validate_plan` with the edited `project`. It stores nothing. Compare its normalized `project` and `summary` to the user's request and fix validation errors before saving. Keep the original read revision. 2. Call `tidigar_update_plan` with the original `id`, original `revision`, validated `project` and `merge: true`. A successful result is the evidence that the change was saved; validation alone is not a save. 3. Return the stored plan's `url` and a short description of what was saved. The URL opens the original for signed-in members. Do not build a copy unless the user requested one. Changes are visible to other plan members. ### Concurrent edits and uncertain outcomes - `merge_conflicts`: nothing was saved. Explain each conflict (`id`, `about`, `change`, `base`, `mine`, `latest`) in plain words and ask the user which to keep. Never choose for them. Call `tidigar_resolve_merge` with the same plan `id`, original `revision` and complete edited `project` sent to the update, plus `choices` mapping every conflict ID to `mine` or `latest`. Remote MCP keeps no pending merge file. If new conflicts appear, ask about those and resend all choices until resolved. - `stale_revision`: get the current plan again, compare it with the version you read, redo the requested change while preserving others' work, validate and save against the new revision. Ask about incompatible changes. - `write_unknown` or a lost response to a write: the save may have happened. Read the plan and compare the stored result before attempting another write. If the result cannot be established, report the uncertainty; do not retry blindly or claim success. ## Access failures - `insufficient_scope`: the OAuth grant is read-only. Ask the host to authorize the connection again with **Read and write**, then check `tidigar_status` and reread the plan before saving. The host handles the MCP authorization challenge. - `invalid_token` or an expired or revoked connection: let the host refresh or reconnect through OAuth, then check status and reread the plan. A user who declined authorization has not approved a different access method. - `agent_access_off`, insufficient membership or `subscription_required`: explain the actual restriction. A write grant cannot override membership, subscription or the organisation owner's policy. Do not switch credentials or protocols to bypass it. `subscription_required` on a read means the organisation is not paid: its plans are unavailable until an owner subscribes, and the same connection works again afterwards. - `no_such_plan`: check the selected organisation and plan link with the user. - `rate_limited`: respect `retryAfter`. After an uncertain write, read before any retry. ## Create, delete or restore a stored plan - **Create:** use the [plan JSON reference](https://tidigar.com/agents/plan-json.md) for a new plan only. Call `tidigar_validate_plan` with `plan`, then `tidigar_create_plan` with the returned `project` so its ID stays stable. Return the saved plan's `url`. If creation's result is unknown, list/read and compare that ID before retrying. `plan_exists` is not permission to duplicate it; use `newId: true` only when the user asks for a new copy. - **Delete:** only when requested, confirm by plan name first. Read its current revision and call `tidigar_delete_plan` with `id` and `revision`. It moves to trash for 30 days. On `stale_revision`, read again and ask again. - **Restore:** call `tidigar_list_trash`, identify the requested plan, then `tidigar_restore_plan` with its `id`. ## Screens and stories A screen publishes one saved view to anyone holding its link, without an account. Confirm with the user before creating one or permanently ending one. Use `tidigar_list_screens`, `tidigar_create_screen`, `tidigar_update_screen`, `tidigar_get_screen_link` and `tidigar_delete_screen`. A screen's `view` is the saved view ID in the project's `sharedViews`; keep that ID when changing what it shows. Deleting the view ends the screen. Give a screen link only to the user, never put it in a project, file or public place. `agent_screens_off` means the owners reserve making screens and retrieving links for people. For stories, read the [story language](https://tidigar.com/agents/docs/stories.md) and use the plan's titles and dates. To replay schedule versions from status meetings, read all versions first and match activities by meaning. Keep the latest version as the stored plan. At `0:00`, set its first version without animation with `hide`, `update`, `add` and `today`. Give each later meeting a moment four to six seconds apart with its changes and a caption explaining what changed. End on the stored version and `loop()`. The plan-history pattern is in the story reference. Fix every returned `storyWarnings` entry and update the screen until none remain before returning its link. ## Remote MCP arguments Use the host's tool calls, not shell commands. Fields marked `?` are optional; validation and creation take exactly one of `plan` or `project`. The tool schemas supplied by the server define field types and limits. | Tool | Arguments | | --- | --- | | `tidigar_status` | none | | `tidigar_list_plans` | none | | `tidigar_get_plan` | `id` | | `tidigar_validate_plan` | `plan?`, `project?` | | `tidigar_update_plan` | `id`, `revision`, `project`, `merge?` | | `tidigar_resolve_merge` | `id`, `revision`, `project`, `choices` | | `tidigar_create_plan` | `plan?`, `project?`, `newId?` | | `tidigar_delete_plan` | `id`, `revision` | | `tidigar_list_trash` | none | | `tidigar_restore_plan` | `id` | | `tidigar_list_screens` | `id` | | `tidigar_create_screen` | `id`, `view`, `name?`, `story?`, `joinCode?` | | `tidigar_update_screen` | `id`, `screen`, `name?`, `story?`, `joinCode?` | | `tidigar_get_screen_link` | `id`, `screen` | | `tidigar_delete_screen` | `id`, `screen` | --- # Stored plans from a coding agent or script ## Plans stored in Tidigar Tidigar Business and Tidigar Server keep plans for an organisation. Use this section when the user asks to save, list, open or change a stored plan, or gives a `/p/` link. A link to that plan opens the shared plan; a share link opens a separate copy. The code is not the plan's id: list the organisation's plans and use the one whose `url` matches the link, ignoring anything after `?` or `#`. **A stored plan is not a share link.** For a new plan, use the optional [plan JSON format](https://tidigar.com/agents/plan-json.md): - You use the `tidigar` command or the HTTP API, never the link builders. - A stored plan is a full project with IDs, colors and saved views, as in the [roadmap file format](https://tidigar.com/agents/docs/file-format.md), not a `plan.json`. You change it by editing that project, never by rebuilding it from a plan, which would lose its IDs and views. - It is saved on a server and every member of the organisation sees your changes, often while they edit; a share link is stored nowhere. - Its `url` opens it only for signed-in members and holds no roadmap data. Never decode it or build a share link from it. This reference is for a coding agent running commands on a computer or in a configured environment. Public chat assistants use the [remote MCP and delegated OAuth guide](https://tidigar.com/agents/stored-plans.md) instead; do not ask a chat user for a personal token. Use the CLI when `tidigar status` exits 0. It keeps the token in the system's credential store. An environment configured with `TIDIGAR_TOKEN` may also use [HTTP](#stored-plans-over-http). If neither is configured, explain that no stored plan has been read, saved or changed. The user follows [connection setup](https://tidigar.com/agents/cloud) and enters credentials outside the chat. Never ask for a token in the chat, print it or write it to a file. A share-link copy is an alternative only for a new plan, never a substitute for a requested save or update. With the CLI signed in, the user can add the MCP tools, for example `claude mcp add tidigar -- tidigar mcp` (`tidigar mcp --read-only` offers no writes). All modes use the same JSON and errors as the [public API](https://tidigar.com/agents/docs/api.md). - **New plan:** write `plan.json` as in [the plan JSON reference](https://tidigar.com/agents/plan-json.md), run `tidigar plans validate plan.json`, check its summary, then `tidigar plans create plan.json`. Answer with the plan's `url`, which opens it for signed-in members. - **Change a plan:** `tidigar plans list` shows each `id`, also the end of its `url`. `tidigar plans get --out plan.json` saves its `revision` and `project`. Edit `project` per the roadmap file format, keeping IDs and giving new records new UUIDs, then `tidigar plans update plan.json --merge`. - Someone may save the plan while you work. `--merge` then combines both changes and saves. Exit 5 with `merge_conflicts` means both changed the same things and nothing was saved: stdout lists each conflict with an `id`, what it is `about`, the `change`, and the `base`, `mine` and `latest` values. Tell the user each conflict in plain words, ask which to keep, and never choose for them. Then run `tidigar plans resolve --choices '{"c1":"mine","c2":"latest"}'` with an answer for every conflict. If it lists new conflicts, ask about those the same way. - Exit 5 with `stale_revision`: the plan changed and could not be merged. Get it again, show the user what changed, redo your edit and update again; never overwrite the other change. - **Delete a plan** only when the user asks, and confirm first by its name. `tidigar plans get ` gives its `revision`; `tidigar plans delete --revision ` moves it to the trash, where it stays 30 days. Exit 5 with `stale_revision`: someone changed it since; get it again and ask again. `tidigar plans trash` lists deleted plans and `tidigar plans restore ` brings one back. - **Screens:** a screen shows one saved view of a stored plan to anyone with its link, on a wall screen or a web page, and may play a story written in the [story language](https://tidigar.com/agents/docs/stories.md) with the plan's own titles and dates. `tidigar screens list ` lists them. `tidigar screens create --view --name --story story.txt` makes one, `--name` and `--story` optional; ask the user first, since anyone with its link sees that view. `tidigar screens update ` changes its `--story` file, `--name` or `--join-code on|off`. To change what a screen shows, update its saved view in the project and keep the view's `id`: deleting the view ends the screen. `tidigar screens link ` prints its `url`; give it only to the user, never write it into a plan, a file or a public place. `tidigar screens delete ` ends the link for good; confirm first. Exit 3 with `agent_screens_off`: the owners keep making screens and reading links to people. - **A plan's history as a story:** when the user gives you the versions of a schedule, such as screenshots of the Gantt chart shown at each status meeting, store the latest version as the plan and write a story that replays the versions on a screen. Read every version first and match activities across them by meaning, not only by title. At `0:00`, set the plan to the first version without animation: `hide` what came later, `update` dates, progress and earlier titles, `add` what was dropped later, and `today("YYYY-MM-DD")` for the first meeting. Then give each later meeting one moment four to six seconds apart: its `today`, its changes (`changeDates`, `update`, `show`, `remove`) and a `caption` saying what changed and why if the slides say. End on the stored plan and `loop()`. The pattern is under "A plan's history" in the story language. Creating or updating the screen answers `storyWarnings`: each call a reader's screen would skip, by line. Fix them and update the story until the list is empty, then give the user the screen's link. - Exit 7 (`write_unknown`): the write may or may not be saved. Get the plan and report what it holds; never repeat a write blindly. - Exit 2: ask the user to run `tidigar login`. Exit 3: read-only token, viewer or no subscription. Exit 4: no such plan. Exit 5 with `plan_exists`: it already exists; `--new-id` saves a copy if the user wants one. Exit 6: too large. ### Stored plans over HTTP The token stays in the environment, never in a command, output or the chat. `TIDIGAR_SERVER` names a Tidigar Server. ```sh API="${TIDIGAR_SERVER:-https://app.tidigar.com}/api/v1" AUTH="Authorization: Bearer $TIDIGAR_TOKEN" JSON="Content-Type: application/json" curl -sS -H "$AUTH" "$API/token" curl -sS -H "$AUTH" "$API/organizations/$ORG/plans" curl -sS -X POST -H "$AUTH" -H "$JSON" --data-binary @body.json "$API/organizations/$ORG/plans/validate" curl -sS -X POST -H "$AUTH" -H "$JSON" --data-binary @body.json "$API/organizations/$ORG/plans" curl -sS -H "$AUTH" "$API/organizations/$ORG/plans/$PLAN_ID" curl -sS -X PUT -H "$AUTH" -H "$JSON" -H "If-Match: \"$REVISION\"" --data-binary @body.json "$API/organizations/$ORG/plans/$PLAN_ID" curl -sS -X POST -H "$AUTH" -H "$JSON" --data-binary @merge.json "$API/organizations/$ORG/plans/$PLAN_ID/merge" curl -sS -X DELETE -H "$AUTH" -H "If-Match: \"$REVISION\"" "$API/organizations/$ORG/plans/$PLAN_ID" curl -sS -H "$AUTH" "$API/organizations/$ORG/trash" curl -sS -X POST -H "$AUTH" "$API/organizations/$ORG/trash/$PLAN_ID/restore" curl -sS -H "$AUTH" "$API/organizations/$ORG/plans/$PLAN_ID/screens" curl -sS -X PATCH -H "$AUTH" -H "$JSON" --data-binary @screen.json "$API/organizations/$ORG/plans/$PLAN_ID/screens/$SCREEN_ID" curl -sS -H "$AUTH" "$API/organizations/$ORG/plans/$PLAN_ID/screens/$SCREEN_ID/link" ``` - `GET /token`: `organization.id` is `ORG`; `writable` says whether you may save; `readable: false` means the organisation is not paid and its plans answer `402`. `GET /organizations/:org/plans` lists plans. - New plan: send `{ "plan": … }` to `POST /organizations/:org/plans/validate`, which answers `{ project, summary }`, then create with `{ "project": … }` to keep its ID. - Change: `GET /organizations/:org/plans/:id`, edit `project`, and send `{ "project": … }` to `PUT /organizations/:org/plans/:id` with the read `revision` as `REVISION`. - Someone saved first (`stale_revision`): send `{ "base": REVISION, "project": … }` to `POST /organizations/:org/plans/:id/merge`, which combines both changes and saves. `merge_conflicts` lists `conflicts` as for the CLI, each with its own `id`: ask the user about each, then send the same body with `"choices": { "": "mine" | "latest" }` for every conflict so far, until it saves. - Delete, after the user confirms: `DELETE /organizations/:org/plans/:id` with the read `revision` as `REVISION` moves it to the trash for 30 days. `GET /organizations/:org/trash` lists deleted plans; `POST /organizations/:org/trash/:id/restore` brings one back. - Errors are `{ "error": { "code", "message" } }`. `stale_revision` also carries the latest `plan`; if `merge` answers `no_such_revision`, redo your edit on it. After a lost answer, or `plan_exists` on a retried create, get the plan and compare before writing. --- # Reference: the share link specification The quick start is enough to write and change ordinary links directly. This specification covers edge cases and the complete opening behavior. --- # Tidigar share link specification See [sharing a roadmap as a link](https://tidigar.com/guides/sharing), with the Share link dialog and the steps to copy a link. Status: public pre-release specification, version 1. It defines how any tool, script or AI agent writes a link that opens a complete, editable Tidigar roadmap. The link carries the whole roadmap itself, so nothing is uploaded, nothing is stored on a server and no account is needed. A link is plain text, written one record at a time; it needs no code, compression or encoding. License: published by Hamacher Software AB under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Anyone may implement the format it describes, in any software, without asking. The keywords **MUST**, **MUST NOT**, **SHOULD** and **MAY** are normative. The roadmap model, its field rules and limits are defined in the [Tidigar Roadmap Interoperability Specification](https://tidigar.com/agents/docs/file-format.md). ## Link format ```text https://open.tidigar.com/s#t=1~~~…~! ``` It opens the Tidigar web app with the roadmap, or the Tidigar app when it is installed and claims the link. The opener is not deployed yet; until it is, `https://app.tidigar.com/#t=1~…` opens the same roadmap in the web app. - The fragment starts with `t=1`. Records follow, each after a `~`, as `key=value` or a one-letter flag, in any order. `!` ends the link. - The whole link SHOULD stay within **2,000 characters**: the fragment within **1,900**. A larger roadmap is shared as a project file. Links are meant to be small, useful starting plans that fit in a chat message, an email or a QR code. - The fragment is never sent to a server by browsers, so the roadmap stays between the sender and the recipient. ## Records | Record | Holds | | ----------------------- | ------------------------------------------------------------- | | `n=Name` | the roadmap's name, required | | `d=Text` | its description | | `y=2026` | its year, required: the year of every `MM-DD` date | | `w` | plans in work days: Monday to Friday, without vacations | | `r=KEY` | the reference key prefix, up to 10 capital letters and digits | | `m1=Team:Design,Build` | a dimension and its options, in order | | `a1=title/start/days/…` | an activity | | `s1=title/date/…` | a milestone | | `p1=title/start/days` | a period | | `v=timeline/…` | the view the roadmap opens in | | `c=3.1.1` | the number of activities, milestones and periods | Numbered records count from 1: `a1`, `a2`, … A link MUST NOT skip a number, and `c=` MUST give the counts, so a missing record or a cut link is noticed. ### Activities ```text a3=Install_new_unit/11-02/5/Installer,Install/@a2,s2/50p/d=Ask_for_permits ``` - **Title**, then **start**: `MM-DD` in year `y`, or `YYYY-MM-DD` for another year. Then **days**: how many days it lasts, `1` for a single day. In a roadmap planned in work days these are work days, skipping weekends and vacation periods. - Then, in any order: - **Options** by name, comma-separated, one per dimension. Where two dimensions have an option of the same name, write `Team:Design`. - **Dependencies** after `@`, comma-separated: activities and fixed milestones by key, such as `@a1,s2`. The activity starts after each of them ends; `@a1:50` lets it start once 50% of `a1`'s planned days have passed (`0`, `25`, `50` or `75`). An activity MUST NOT start before what it depends on allows, and dependencies MUST NOT form a cycle. - **Progress** as `0p`, `25p`, `50p`, `75p` or `100p`. An option whose name looks like this is written with its dimension, such as `Size:50p`. - `d=` a description. ### Milestones and periods ```text s1=Heat_pump_in_operation/11-09/@a3 s2=Contract_signed/10-30/fixed p1=Autumn_break/10-26/5 ``` - A milestone has a title and a date, then `@` and the activities it waits for, at least one day after each ends; or `fixed` for an event on a set date, such as a decision, that activities wait for. - A period is a titled band across the timeline, such as a holiday: title, start and days. It is a vacation, without work days, unless `work` follows. ### Dimensions and the view - `m1=Team:Household,Installer` names a dimension and its options in order. A link has no colors: options take Tidigar's standard colors in order. - `v=` opens the roadmap in `timeline`, `board`, `list` or `flow`, followed by `rows:`, `columns:`, `color:` or `group:` and a dimension's name, and by `start:` and `end:` and a date for the timeline's span: `v=timeline/color:Team/group:Phase/start:10-01/end:12-31`. - Words set how a timeline looks: `classic` shows one activity per row under a fixed label column with reference keys, as in MS Project, and opens the roadmap in its Classic view; `compact` lets activities share rows; `minimal`, `airy`, `contrast` and `terminal` choose a style. A word alone means a timeline: `v=classic`. ### Text - `_` is a space. - In a title, a note or a name, write these characters escaped: `~` `%7E`, `/` `%2F`, `_` `%5F`, `%` `%25`, `&` `%26`, `#` `%23`, `(` `%28`, `)` `%29`, `"` `%22`, `<` `%3C` and `>` `%3E`. In a dimension or option name also `,` `%2C`, `:` `%3A`, `@` `%40` and `=` `%3D`. - Other characters, such as å, ä, ö or `–`, are written as they are. - Titles are up to 180 characters, names up to 100, the roadmap's description up to 500. ## Example ```text https://open.tidigar.com/s#t=1~n=Heat_pump_replacement~y=2026~w~m1=Team:Household,Installer~m2=Phase:Plan,Install~a1=Review_current_system/10-12/3/Household,Plan~a2=Request_quotes/10-15/6/Household,Plan/@a1~a3=Install_new_unit/11-02/5/Installer,Install/@a2,s2~s1=Heat_pump_in_operation/11-09/@a3~s2=Contract_signed/10-30/fixed~p1=Autumn_break/10-26/5~v=timeline/color:Team/group:Phase~c=3.2.1~! ``` A heat pump replacement planned in work days: three activities by Team and Phase, the installation waiting both for the quotes and for the signed contract, a completion milestone, and the autumn break as a vacation week. It opens as a timeline grouped by Phase and colored by Team. ## Opening a link Tidigar adds the opened roadmap to the recipient's own library and shows it in the link's view. Every record gets a new identity, so each opening is an independent copy: editing it never changes the link or anyone else's copy. Opening the same link again on a device selects the copy it made. The copy is made as a new roadmap is: its activities and milestones get reference keys in the link's order, such as `WL-1`, `WL-2`, under the prefix `r=` gives or one made from the roadmap's name, and it gets the Classic view beside the view it opens in. Tidigar reads a link leniently and says what it did. What has an obvious fix is fixed and reported by record, for example `a3: no dimension has the option "Done"; it was left empty`, or an activity that starts before what it depends on is moved later. A link with a problem that has no fix, such as `a1: start "02-30" is not a date`, is refused with every problem listed. Tidigar shows the report so it can be passed back to whoever wrote the link. Tidigar never drops an activity, a milestone or a period. Tidigar shares links of its own in a compressed form, `#s=1.…`. They are not meant to be read or written by hand; open them in Tidigar. ## Optional validation Agents can write links directly using [llms.txt](https://tidigar.com/llms.txt), without tools or code. To check a finished link locally, optionally run: ```sh node tidigar-link.mjs --validate "" ``` The module below reports the plan's dates and dependencies, record counts, fragment length and any corrections Tidigar would make. It exits 0 only when the link opens without corrections. Invalid input, a fragment over 1,900 characters or corrections to review produce exit 1. It does not rewrite the link or save anything; fix the original records and validate again if desired. ## Building a link from JSON `https://tidigar.com/agents/v1/tidigar-link.mjs` (Node.js 20 or later, Deno or Bun) and `https://tidigar.com/agents/v1/tidigar_link.py` (Python 3.8 or later) build a link from a plan: the roadmap as JSON with real dates and names, described by `https://tidigar.com/agents/schema/plan-v1.json`. They validate it with Tidigar's own rules, print the link, a summary with real dates and the fragment length, or an error that names the broken rule and the record, such as `activities[2] "Build"`. `--read ` prints a link's roadmap as a plan to change and build again. They run locally and send nothing anywhere. As a module, `tidigar-link.mjs` exports `createLink(plan)`, `readLink(link)` and `embedCode(link, title)`. Instructions for AI agents, with these builders and a worked example, are at [tidigar.com/llms.txt](https://tidigar.com/llms.txt).