corsair.dev
Corsair Dev v0.1.6
Projects, CRM and routines
From the developer
Declared capabilities
- Track issues and projects
- Keep contacts and deals
- Search your workspace
Cost & access
Corsair does not sell anything in ChatGPT, and no tool reply links to a purchase or upgrade page.
Declared limitations
- A general question needs no Corsair data or actions.
- An ambiguous bulk delete is not carried out.
- Data outside the signed-in account is not reachable.
Onboarding example
What's open in my Customer pilots project?
Sources & dates
Developer declarations; not independently tested. Listing last checked Nov 13, 2026. Package observed Nov 13, 2026.
Description
From the marketplace listing
Corsair is a workspace your agent works in. It has its own project tracker and CRM, one search across everything in them, routines that run on a schedule, and a library of saved skills. - Projects and issues: file and update issues with a status, priority, assignee, labels and a due date, and group them into projects. - CRM: keep people, companies and deals, move a deal through its stages, and add notes and follow-up tasks. - Search: ask a question such as "what do we still owe Kestrel?" and get the matching deal, notes, tasks and issues in one answer. - Routines: describe a recurring job in plain words, such as "every Monday at 9, add a follow-up task for each deal still in Lead". Corsair writes it, tests it and runs it, and you can see every run, pause it or remove it. - Skills: save instructions once, such as a weekly pipeline review, and load them in any agent connected to your Corsair link. You can also connect other apps you use to your Corsair account, signed in with your own accounts, and work with them through the same tools. This plugin uses dynamic tool discovery and JavaScript execution to work across your workspace. Changes go through a tool that ChatGPT asks you to approve, and a link can be limited to read-only. You can see, pause or remove a routine or a connection from your Corsair account at any time.
Language: English · Automatically detected from descriptions.
Changes
No changes recorded yet. Follow this plugin to keep track of future changes.
First seen Nov 13, 2026. Last seen Nov 13, 2026.
Similar plugins
Find competitors to follow as you develop your plugin.
-
The monday.com AI Connector brings core platform capabilities directly to agents and AI assistants. It supports searching boards, creatin...
Shared terms: crm, project, deal, lead
-
Work with your Mesh APP customers, leads, offers, projects, tasks and finance figures from ChatGPT.
Shared terms: crm, project, companie, deal
-
ActionBridge (AB) for ChatGPT and Codex: work your AB Projects tasks and documents, your AB Sales pipeline and your AB Support desk in pl...
Shared terms: project, deal, due, label
-
folk is a CRM built for relationship-driven teams. Connect it to ChatGPT to search your contacts, log interactions, and stay on top of yo...
Shared terms: crm, companie, deal, pipeline
-
Gleap brings your customer support workspace into ChatGPT. Search and triage tickets, look up contacts and companies, reply to customers ...
Shared terms: crm, companie, deal, move
Keywords
Files & skills
File archives
Skill instructions
corsair-approvals3.34 KB
---
name: corsair-approvals
description: Use when a Corsair call or automation run says it needs approval, was denied, timed out waiting for approval, or is blocked by a permission mode, or when the user asks what Corsair's permission modes allow.
---
# Approvals and permission modes
Every action has a risk level: read, write, or destructive. The Corsair connection this agent uses, a link or a client sign-in, has a mode, and the mode decides which risk levels go through, which wait for a person to approve them, and which are refused.
| Mode (as Corsair labels it) | Reads | Writes | Destructive |
| --- | --- | --- | --- |
| Read (`readonly`) | allowed | refused | refused |
| Cautious (`cautious`, the default) | allowed | allowed | need approval |
| Strict (`strict`) | allowed | need approval | refused |
| Open (`open`) | allowed | allowed | allowed |
You can't change the mode. Whoever manages the connection sets it in Corsair.
No tool reports this connection's mode, so don't guess it. Work from what you can see: no `update_routine` tool usually means the link is Read, no `get_connect_link` tool means it can't add apps, and a "blocked by permission mode" error names the mode. Otherwise explain the four modes and say the link's settings in Corsair show which one applies.
Your client may also ask the user to confirm each `run_script` and `update_routine` call, because those tools can make changes. `search`, `read_data`, `get_job` and `view_routines` are marked read-only, so clients usually run them without asking. Those prompts come from the client, not from Corsair, and are separate from everything below.
## What you'll see and what to do
**"Approval required. Visit <link> to approve or deny, then tell the agent to retry this action."**
1. Give the user the link exactly as returned and say in plain words what the action does ("delete the repo acme/old-site").
2. Stop and wait. Don't retry on a timer, and don't look for another way to get the same result.
3. When the user says they approved it, call that one action again with exactly the arguments from the first call: copy them, don't recompute them. Leave out any other changes the first script already made, so they don't happen twice. An approval covers that one call, once. Different arguments need a new approval.
**"... was denied by the user. Await further instructions before proceeding."**
Stop. Tell the user it was denied and ask what they'd like instead. Don't retry.
**"... timed out waiting for approval."**
The request expired. Ask whether to request it again. If yes, run the call again to get a new link.
**"... is blocked by permission mode 'readonly'"** (or `'strict'`)
This connection can't do that kind of action at all. Tell the user which action was blocked and that whoever manages the connection can change its mode in Corsair. Don't look for a workaround.
**"... requires user approval before it can run"** with no link
Corsair couldn't create an approval link. Tell the user what it said and stop.
## Routines
A run that `view_routines` shows as "needs approval before it can run" (`awaiting_approval`) is held before any step runs, because the routine needs approval or one of its steps is destructive. Call `view_routines` with that run's id as `run` to see what it would do, and tell the user. It's approved or denied in Corsair, not from here. Don't run its steps yourself with `run_script`.
corsair-automations4.14 KB
---
name: corsair-automations
description: Use when the user wants something to happen automatically through Corsair, on a schedule ("every Monday at 9am, add a CRM task for each deal still in Lead") or when an event happens in a connected app, or asks whether an automation ran or why it failed, or wants to list, change, pause or switch off an automation. Covers update_routine and view_routines.
---
# Build and check Corsair automations
Corsair calls an automation a routine: a trigger (an app event or a clock) plus the steps that run when it fires. You describe it in plain words, and Corsair writes and tests the steps. You never pass code.
Saving one is half the job. The other half is confirming it fires and works, because a routine can save cleanly and still fail on its first real event.
## Before you add one
- Call `view_routines`. If something already watches the same event and does the same thing, tell the user instead of adding a second one.
- If there's no `update_routine` tool, this connection can't create or change routines. Tell the user. Don't do the routine's work yourself with `run_script` instead.
- Every app the routine uses has to be connected. If one isn't, connect it first (see the corsair-connect-apps skill).
## Create one
Call `update_routine` with only `intent`, written the way the user would say it, with the specifics: which app, which records, what it should create or change, and for a schedule, when and in which timezone.
```json
{ "intent": "Every Friday at 5pm UTC, file a PM issue titled Pipeline review that lists my open CRM deals with their stage and value." }
```
Corsair builds it in the background, so it doesn't exist yet when the call returns.
1. Wait briefly, then call `view_routines`. The build appears as "one you described is still being built" (`kind: "pending_build"`, `status` `queued` or `running`). Check a couple of times; if it's still building, tell the user and check later instead of polling in a loop.
2. If it "needs one question answered" (`status: "waiting_for_input"`), give the user its `question` and `options`. Send their choice back with `{"routine": "<the build's id>", "answer": "<the option exactly as listed>"}` and nothing else in the call. The build's id starts with `aj_`.
3. If it "could not be built" (`status: "failed"`), tell the user what its `error` says and offer to describe it differently.
4. Once it's built, read it back from `view_routines` and check it matches what the user meant.
## Change, pause or switch one off
`view_routines` gives each routine's id. A routine id starts with `wf_` ("Routine id wf_…"); an event routine also has a trigger id starting with `wft_`, and either one works below.
- **Change it:** call `update_routine` with that `routine` id and an `intent` describing the change. Corsair changes that routine instead of adding a second one.
- **Pause or resume it:** `{"routine": "<id>", "action": "pause"}`, or `"resume"`.
- **Switch it off:** `{"routine": "<id>", "action": "remove"}`. What it did stays saved in Corsair.
If two routines look alike, confirm which one with the user first.
## Check that it works
1. Ask the user to make the event happen, or tell them what to watch for. For a schedule, tell the user when the first run is due.
2. Call `view_routines` with `routine` to see its recent runs. Each has an id and a status: succeeded (`successful`), failed (`error`), still running (`running`), or needs approval before it can run (`awaiting_approval`, see corsair-approvals).
3. For a failed run, call `view_routines` with `run` to see its steps and the error. Describe the fix with `update_routine` (`routine` and `intent`), then check again.
- Some errors aren't the routine's fault, such as a limit on the user's Corsair account or a fault on Corsair's side. Rewriting the routine won't fix those, and Corsair doesn't try to. Tell the user what the error says instead.
4. No run at all means the trigger didn't match. Ask the user what happenPreview of the first 4,000 characters. Read full instructions →
corsair-connect-apps4.89 KB
---
name: corsair-connect-apps
description: Use when the user wants to use an app through Corsair that isn't connected yet, asks which apps are connected, or a Corsair call fails because an app isn't connected. Covers finding the app, handing over the sign-in link from get_connect_link or pointing to the Connect button on Corsair's card, and confirming the connection.
---
# Connect an app through Corsair
Corsair's own PM and CRM are ready on every link. Other apps the user works in can be connected too; most need the user to sign in first. Your part is to find the app, get the sign-in link, hand it over, and confirm it worked. You never sign in on the user's behalf.
## Steps
1. **See what's connected.** Call `list_integrations` with no arguments. Each app is in one of four states, given in words and in the result's fields:
- "connected and ready to use" (`connected: true`): use it. `account` names who it's signed in as, when the app says.
- "set up, but nobody has signed in yet" (`on_instance: true`, `connected: false`): go to step 3.
- "can be connected from here" (`available_to_add: true`): go to step 3.
- "needs setting up before it can be connected" (none of those): see "When there's no link" below.
2. **Look up an app that isn't listed.** Call `list_integrations` with `filter` and `search`, with the app's name in `search`. Use the `id` it returns in every later call. Don't guess ids.
3. **Get the link.** Call `get_connect_link` with `{"integration": "<id>"}`. It adds the app first if it isn't here yet.
4. **Hand it over.** What you say depends on whether the chat shows Corsair's card:
- **The chat shows a Corsair card** with the app's name and a **Connect** button (claude.ai and other clients that show MCP Apps). Tell the user to press Connect on the card. Don't paste the link as well: two ways to sign in for one app reads as two steps.
- **No card** (most coding agents and terminals). Give the user the `connect_url` exactly as returned; the result text repeats it.
Then ask them to tell you when they've signed in, and stop.
5. **Confirm.** When the user says they're done, call `list_integrations` again. The app should read "connected and ready to use" (`connected: true`). Then do what they first asked for.
## The card
The card keeps itself up to date, so you don't have to:
- While the user signs in, it shows **Open again** in case they closed the sign-in tab.
- When they finish, it shows **Connected** and a **Continue** button that messages you to carry on. Some chats put that message in the user's box for them to send.
- If the link runs out first, it shows **Link expired** and a **New link** button that gets a fresh one. Don't call `get_connect_link` again for that.
- An app Corsair provides directly shows **Ready**.
## Rules for the link
- Copy it character for character. Don't shorten it, rebuild it, or put it behind another URL.
- Never write a link yourself. If `get_connect_link` returned no link, there is no link.
- Call `get_connect_link` once per app. Each call mints a new sign-in session, so calling it again only produces more links.
- A link works for about 10 minutes; the reply says how long ("works for 10 minutes"), and `expires_at` gives the time. Get a new one only if the user says it failed or ran out and there's no card to renew it.
- Don't open the link or try to finish the sign-in yourself.
## When it comes back ready
A few apps come back with `connected: true` and no link. There is nothing to sign in to. Use the app right away.
## When there's no link
- **There's no `get_connect_link` tool.** This connection can't add apps. Tell the user to connect the app in Corsair, or to allow this link to add apps, then confirm with `list_integrations`.
- **`connect_blocked_by` is set, or the result says the app "has no sign-in link yet".** Whoever manages this Corsair connection, or the Corsair project behind it, has to finish setting the app up first, for example by adding its OPreview of the first 4,000 characters. Read full instructions →
corsair-data8.26 KB
---
name: corsair-data
description: Use when answering a question from the user's Corsair workspace (find an issue, a deal, a note or a task, or anything in an app they connected) or doing something in it right now (create, update). Explains when to search synced data with search, read live with read_data, make changes with run_script, wait on long jobs with get_job, and when to send submit_feedback.
---
# Read and act on connected apps
Three Corsair tools reach the user's data:
| | `search` | `read_data` | `run_script` |
| --- | --- | --- | --- |
| Reads | PM issues, CRM deals, people, notes and tasks, and the synced copy of any app the user connected | The app's live data | The app's live data |
| Writes | No | No: the script stops at the first write, before that write runs | Yes: send, create, update, delete |
| Best for | Finding things ("what do we still owe Kestrel?") | Current state and exact lists | Any change |
Start with `search` when the user is looking for something. Use `read_data` when they need the current state or a complete list (every open issue, every deal in Lead). Use `run_script` only to change something. If this connection has neither `read_data` nor `run_script`, it can't reach apps live: answer from `search` and say so.
## search
Call it once with the whole question in `query`. Matching is by keyword with stemming, then ranked, not by meaning. So:
- Put synonyms in `keywords`. For "security review": `keywords: ["security", "questionnaire", "SSO"]`.
- Put people, emails, channels, repos, projects and companies in `about`, not in `query`. `about: ["Kestrel Logistics"]` also matches its deal, notes and tasks.
- Put time limits in `after` and `before` as ISO timestamps, not in `query`. Work out the dates from today's date first.
- Narrow with `apps` (`["pm"]` or `["crm"]`) and `kinds` (`["issues"]`, `["deals"]`) when you know where the answer lives.
- For the newest items ("my latest notes"), set `sort: "recent"`.
The reply has a sync line: which apps are synced and how recently.
- When it covers every app in the question, answer from the results.
- When it doesn't, it names the live call to run for each app it misses. Run those together in one `read_data`.
Each result shows its app, date, title, the text that matched and an id of the form `app:kind:id`, such as `crm:deals:rec_qbjL-Cr1HJI` or `pm:issues:PRD-5`. If you only see the structured result, build it from the hit's `pointer`: `plugin:entityType:entityId`. Often the results are enough to answer. When they aren't, such as to read a whole document or a long note, call `search` again with the ids:
- Pass up to 20 of them in `ids`.
- Long text comes in pages, and the reply says when there is more. With one id, ask for the next one with `page`.
- This reads Corsair's synced copy, not the app, so it answers fast. For the current state, use `read_data`.
No match means nothing in the synced copy matched. It doesn't mean the thing doesn't exist. Try other keywords, then a live read with `read_data`.
## read_data and run_script
Both take the same code: the body of an async function. `corsair` is the only thing in scope, and you `return` the result. There is no network, filesystem or `import`. A script has 25 seconds, so fetch only what the answer needs and run independent calls together with `Promise.all`.
1. Find the action: `list_operations {"integrations": ["pm"], "search": "create issue"}`. With `search` it returns only the matching actions, each with its risk and required arguments, ready to use. Without `search` it lists every action's name and risk.
2. Call `get_schema {"operations": ["pm.api.issues.create"]}` when you need an action's return shape or its optional arguments. Don't guess argument names.
3. Run it: reads with `read_data`, changes with `run_script`. Do the lookup and the action in one `run_script` call with ordinary JS rather than several round trips:
```js
const { data: deals = [] } = await corsair.crm.api.records.query({Preview of the first 4,000 characters. Read full instructions →
corsair-skills3.97 KB
---
name: corsair-skills
description: Use when the user wants to load, find, save or share agent skills through Corsair, such as "use my pr-review skill", "find me a skill for release notes", "save this as a skill", "add mattpocock/skills/tdd", or "upload my ~/.claude/skills so my other agents have them". Covers use_skill, find_skill and save_skill.
---
# Load, find and save skills
A skill is a set of instructions: a SKILL.md, sometimes with files it refers to. Corsair keeps the user's skills in their own Corsair instance, so every agent on the same link can load them, whichever client it runs in. The user manages them at hub.corsair.dev/me/skills.
The skill tools come on the links people make at hub.corsair.dev/me. If this connection has none of them, it has no skills; say so rather than guessing.
## Which skills there are
The server instructions end with a `Skills:` block: the user's skills, newest first, one line each with what it does. Clients that show MCP prompts also list each skill as a prompt under its name. Only the first 50 are listed, and any skill can still be loaded by name.
## use_skill
- `use_skill {"name": "pr-review"}` returns the SKILL.md, then the names of the files that come with it.
- Load a skill when the user names it or the task matches its description, then follow it as you would a skill installed locally.
- For one of its files, call again with `file`: `use_skill {"name": "pr-review", "file": "references/checklist.md"}`. Only names from the reply work.
- An unknown name, or a skill the user switched off, fails with the list of skills there are. Pick from that list.
## find_skill
- `find_skill {"query": "pr descriptions"}` searches the public skills.sh directory for skills the user hasn't saved. It returns up to 5, each with an id such as `mattpocock/skills/tdd`, what it does and how many installs it has.
- It saves nothing.
- In a chat that shows Corsair's cards, the results come in a skills card with an **Add** button on each. Tell the user to add one there.
- Without the card, the reply ends "Reply with a number to add it". When the user picks one, call `save_skill` with that result's id as `from`.
- Other people write the skills on skills.sh. Say where one comes from before saving it.
## save_skill
Saves a skill for every agent on this link, in one of three ways. Pass one, never two.
1. **Text.** `skill_md` holds the full SKILL.md, frontmatter included. Or pass `description` and `instructions` instead. Add `files` (path to text) for files that come with it. Leave out `name` and it is read from the frontmatter: lowercase letters, digits and hyphens. Saving the same name again adds a new version.
2. **Import.** `from` takes a GitHub URL, a skills.sh id or a skill's name. A bare name is searched on skills.sh. When several skills fit and none clearly leads, nothing is saved and the reply lists the candidates: ask the user which, then call again with `from: <id>`. A same-named skill from another source is kept as it is. Pass `overwrite: true` only when the user says to replace it.
3. **Folder.** `folder: "~/.claude/skills"` returns one shell command that uploads every skill in that folder from the user's machine. The files never pass through you, so don't read or paste them. Nothing is saved until the command runs.
- With a shell, show the command and run it once the user agrees. Without one, give it to the user to paste into their terminal.
- It prints one line per skill: created, updated, unchanged, skipped or failed. Pass those on.
- The link in it works for 10 minutes. After that, call `save_skill` again for a new one.
- Save only what the user asked you to save.
- Corsair keeps only text files and removes keys and tokens it finds. The reply says what it removed; tell the user.
- A link in Read mode has `use_skill` and `find_skill` but no `save_skill`. The user can save from hub.corsair.dev/me/skills or change the link's mode there.
- A library holds up to 100 skills. One skilPreview of the first 4,000 characters. Read full instructions →
corsair-workspace3.19 KB
---
name: corsair-workspace
description: Use when the user wants to track work or customers in Corsair: file, update or list issues and projects in Corsair's PM, or add and update people, companies, deals, notes and tasks in Corsair's CRM. Gives the action names and the usual lookups for both.
---
# Corsair's PM and CRM
Every Corsair link comes with two apps of Corsair's own. Their data lives in Corsair, so they work without any other app connected.
- **PM** (`pm`): teams, projects, issues with a status, priority, assignee, labels and a due date, plus comments.
- **CRM** (`crm`): people, companies and deals. A deal has a stage (Lead, In Progress, Won, Lost), a value, an owner and linked people and company. Any record can have notes and tasks.
Find what's there with `search` first ("what's open for the Kestrel pilot?" finds the deal, its notes and tasks, and the PM issues that name it). Use `read_data` for complete lists and `run_script` for changes, as the corsair-data skill explains.
## PM
| To | Action |
| --- | --- |
| Look up teams, states, people, labels, projects | `pm.db.teams.search`, `pm.db.workflowStates.search`, `pm.db.users.search`, `pm.db.issueLabels.search`, `pm.db.projects.search` |
| List or find issues | `pm.db.issues.search` (filter on `title`, `stateId`, `assigneeId`, `projectId`, `dueDate`) |
| File an issue | `pm.api.issues.create`: `title`, and optionally `stateId`, `priority` (1 urgent, 2 high, 3 medium, 4 low), `assigneeId`, `dueDate` (YYYY-MM-DD), `projectId`, `labelIds` |
| Change an issue | `pm.api.issues.update` with the issue's `id` |
| Comment | `pm.api.comments.create` |
Ids come from the lookups, never from names: look up the state, label, project and member first, in the same script.
```js
const [states, labels, projects, users] = await Promise.all([
corsair.pm.db.workflowStates.search({ limit: 50 }),
corsair.pm.db.issueLabels.search({ limit: 50 }),
corsair.pm.db.projects.search({ limit: 50 }),
corsair.pm.db.users.search({ limit: 50 }),
]);
const todo = states.find((s) => s.name === 'Todo');
const bug = labels.find((l) => l.name === 'Bug');
const relaunch = projects.find((p) => p.name === 'Website relaunch');
return await corsair.pm.api.issues.create({
title: 'Checkout button does nothing in Safari',
stateId: todo?.id, priority: 1, labelIds: bug ? [bug.id] : [], projectId: relaunch?.id,
assigneeId: users[0]?.id, dueDate: '2026-11-21',
});
```
## CRM
| To | Action |
| --- | --- |
| Find records | `crm.api.records.query` with `object` (`people`, `companies`, `deals`), and `q` for text or `filter` such as `{ stage: 'Lead' }` |
| Add a record | `crm.api.records.create` with `object` and `values` (attribute slugs from `crm.api.attributes.list`) |
| Change a record | `crm.api.records.patch` with `object`, `record_id`, `values`; a deal's stage takes the stage's title |
| Notes | `crm.api.notes.create` with `record_id`, `title`, `content` |
| Tasks | `crm.api.tasks.create` with `content`, `deadline`, `linked_records` |
A record's values come back as lists of dated values; the current one has `active_until: null`.
Moving a deal to Won or Lost, or deleting anything, changes the user's records: say what you'll change and do it only when they asked for it.
Release notes
0.1.6: the listing and review cases now cover Corsair's own apps: a project tracker and a CRM, search across them, routines and saved skills. The review account has only these apps, with sample data, and no outside app connected. A new corsair-workspace skill covers the PM and CRM actions, and the other skills use them as examples.
Declared in the saved package. Remote tools may change independently.
Package details
Publisher declarations from the archived package. These are separate from our research and the live service's terms.
- Package license
- Apache-2.0
- Package author
- Corsair
- Keywords
- See keywords
- Getting started skill
- ./skills/corsair-connect-apps/SKILL.md
- Commerce declaration
- Does not support commerceThis does not establish whether access is free or paid.
- Review scenarios
- 5 positive · 3 negativeScenario counts, not test results.
Declared capabilities
- Track issues and projects
- Keep contacts and deals
- Search your workspace
- Set up routines
- Save and use skills
Package observed Nov 13, 2026.
Technical details
- First seen
- Nov 13, 2026 · 18:00 UTC
- Last seen
- Nov 13, 2026 · 18:00 UTC
- Collection status
- Collected
plugin_asdk_app_6ae189f951708191920e9f41269c8cde
Download plugin data (JSON)Plugin details: freshly prepared. Prepared . Refreshed when plugin data changes or after 6 hours. Your account and Follow status are live.