add-data-source
Skill34 starsChanged 4 months agoMITView on GitHub
Canonical add flow for Microsoft Managed Apps. Use when adding any data source through `ms app add data-source` (with `--as table` or `--as action`), or when the user wants help discovering which connector / api-id to use.
We split this skill into the rules it gives an agent
17 rules. 0 are common, 6 are distinctive, and 11 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
6
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 21
If this skill is called from a wrapper, do not delegate back
- Distinctive: line 22
If this skill is called directly, complete the workflow without delegation
- Distinctive: line 25
If invoked via a specialized skill → Refer to that specialized skill's documentation for usage patterns (it was already provided)
- Distinctive: line 26
If invoked directly → Identify which specialized skill matches your use case and refer to its documentation for:
- Very specific: line 38
Run the matching ms app add ...
- Very specific: line 39
Check for a shared connection and declare allowedActions if so.
- Very specific: line 75
Wrapper preset: If invoked by a specialized /add-* skill (see "Common Presets" below), use the preset api-id and skip discovery.
- Very specific: line 76
Caller-supplied: If $ARGUMENTS includes an api-id (e.g., api-id=shared_office365), use it verbatim.
- Very specific: line 77
User-supplied verbatim string: If the user already typed an api-id (anything matching the shared_* / dataverse / microsoftcopilotstudio …
- Distinctive: line 96
When user intent is about knowledge retrieval / grounded Microsoft 365 search summaries (for example: "analyze M365 content", "search my …
- Very specific: line 111
If they insist on /add-data-source, proceed but after adding the connector, refer them to the /add-workiq skill documentation so they …
- Distinctive: line 123
If the caller is a wrapper skill, use wrapper presets as defaults and only ask for missing fields.
- Very specific: line 127
All modes use the single ms app add data-source command.
- Very specific: line 185
If it prints OK, skip to Step 5 — the connection isn't shared, or is already covered.
- Very specific: line 203
Deferral — when there is no app code yet: If src/ has no calls into this service because the app hasn't been written yet (the usual case …
- Very specific: line 207
Leave allowedActions unset for now.
- Very specific: line 227
If memory-bank.md exists, record api-id, mode, parameters used, and — when the reference is shared — the allowedActions that were agreed, …
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
📋 Shared Instructions: shared-instructions.md — Cross-cutting concerns.
Reference: connector-reference.md — Inline connection creation, Grep-first for large generated files.
Reference: allowed-actions.md — Shared connections must declare allowedActions before deploy (Step 4).
Add Data Source (Canonical)
This is the single implementation for all connector-binding skills.
Delegation model:
- Specialized
/add-*skills (e.g.,/add-office365,/add-workiq) delegate to this skill with presets - If this skill is called from a wrapper, do not delegate back
- If this skill is called directly, complete the workflow without delegation
After the connector is added:
- If invoked via a specialized skill → Refer to that specialized skill's documentation for usage patterns (it was already provided)
- If invoked directly → Identify which specialized skill matches your use case and refer to its documentation for:
- Correct import paths for generated services
- Best practices for using the connector
- Common patterns and implementation examples
- Error handling guidance
This ensures developers have complete context for implementing features, not just adding the connector.
Workflow
- Verify workspace + auth.
- Resolve
api-id(discover viams connector listif the user didn't supply one),mode, and required arguments. - Run the matching
ms app add ...command. - Check for a shared connection and declare
allowedActionsif so. - Run
npm run build. - Record the binding in
memory-bank.mdif present.
Step 1: Verify Project + Env
test -f ms.config.json || { echo "Not in a Microsoft App workspace."; exit 1; }
BIN=ms
$BIN auth statusStep 2: Resolve Inputs
Collect:
api-id(required — see resolution order below). Passed to the CLI via--connector <api-id>.mode=action|table(controls the--asflag). There is noproceduremode — binding a specific SQL stored procedure is not exposed by the current CLI (see note below).connection-id(optional interactive, required for non-interactive where applicable)
Additional by mode:
table:dataset,table
SQL stored procedures: the CLI has no
ms app add procedurecommand andms app add data-sourcedoes not accept--sql-stored-procedure. You can still add the SQL data source as a table (--connector shared_sql --as table --dataset <db> --table <tbl>), but binding a specific stored procedure is not currently supported.
2a. Resolve api-id
Try sources in this order; stop at the first one that yields a value:
- Wrapper preset. If invoked by a specialized
/add-*skill (see "Common Presets" below), use the preset api-id and skip discovery. - Caller-supplied. If
$ARGUMENTSincludes anapi-id(e.g.,api-id=shared_office365), use it verbatim. - User-supplied verbatim string. If the user already typed an api-id (anything matching the
shared_*/dataverse/microsoftcopilotstudioshape, or a string they explicitly call an api-id), use it. Discovery via
ms connector list. Do not ask the user to type an api-id from memory. Instead:a. Ask one question: "Which connector do you need? (a short keyword like 'teams', 'sql', 'sharepoint', 'salesforce' is fine — I'll search the catalog.)" Capture the keyword as
{term}.b. Search the catalog:
$BIN connector list --search "<term>"Parse the output into a short table (display name + api-id). If the result set is large (more than ~10 rows), narrow with a more specific term and re-run rather than dumping everything.
c. Present the candidates to the user via
AskUserQuestionwith the display names as choices (and api-ids in parentheses for transparency). Map their selection back to the api-id; never ask them to retype it.d. If
ms connector list --search "<term>"returns no results, fall back toms connector listwith no filter, surface a representative slice, and ask the user to refine the term. Do not proceed with a guessed api-id.- Validation. Once an api-id is chosen, confirm it's real before spending a build cycle on it:
$BIN connector list-actions --connector <api-id> --search ""should succeed. If the CLI replies that the api-id is unknown, drop back to step 4 — don't keep retrying with the same value.
Work IQ intent hint
When user intent is about knowledge retrieval / grounded Microsoft 365 search summaries (for example: "analyze M365 content", "search my email and Teams", "knowledge-grounded query"), default to:
api-id:shared_a365copilotchatmcpmode:action
⚠️ IMPORTANT: If the user is adding Work IQ via /add-data-source, ask them to use /add-workiq instead.
Why: Work IQ uses MCP (Model Context Protocol), a stateful protocol that requires special handling. The /add-workiq skill provides:
- Complete
McpSessionwrapper class (handles session initialization, auto-retry, response parsing) - Best practices for structuring prompts
- Error handling patterns
- Multi-turn conversation support
Guidance: "I can add the connector, but for Work IQ I recommend using /add-workiq — it provides a production-ready McpSession class and comprehensive patterns to avoid common errors. Would you like to use /add-workiq instead?"
If they insist on /add-data-source, proceed but after adding the connector, refer them to the /add-workiq skill documentation so they understand the McpSession requirement.
2b. Resolve mode
For api-ids in the "Common Presets" table, use that table's mode. Otherwise ask the user one question, framed by what they want to do:
- "Read or write rows in a tabular store?" →
table - "Trigger an operation (send a message, post a file, list events)?" →
action
mode selects the --as flag. Tabular connectors (e.g. SharePoint, SQL) support both; in
non-interactive runs --as is required for them. Action-only connectors ignore --as.
If the caller is a wrapper skill, use wrapper presets as defaults and only ask for missing fields.
Step 3: Execute Add Command
All modes use the single ms app add data-source command; --as chooses table vs action. The
connector is passed via --connector (there is no --api-id flag).
Deprecated alias:
ms app add connectorstill works but is deprecated — preferms app add data-source. Both share the same handler and flags.
Action mode
$BIN app add data-source --connector <api-id> --as actionTable mode
$BIN app add data-source --connector <api-id> --as table --dataset "<dataset>" --table "<table>"The CLI resolves a connection inline (interactive picker, or --connection-id <id> / -c <id>
for a specific one). In non-interactive mode, if --connection-id is omitted the CLI prints the
available connections and then errors. Dataverse (--connector dataverse --as table) needs no
--connection-id. See connector-reference.md.
SQL stored procedures have no
ms app add procedurecommand and--sql-stored-procedureis not accepted byms app add data-source; binding a specific stored procedure is not currently supported.
Step 4: Shared Connection Policy (allowedActions)
Do this before the build, on every add. The CLI writes sharedConnectionId automatically
when the connection's auth type is shareable, so this can trigger without the user asking for
it — and it doesn't surface as a build error, it surfaces later as a deploy failure.
4a. Read the config back and check the reference that was just written. Node 22+ is a project prerequisite, so this works in bash and PowerShell alike:
node -e '
const fs = require("fs");
const refs = JSON.parse(fs.readFileSync("ms.config.json", "utf8")).connectionReferences || {};
const ok = (a) => Array.isArray(a) && a.length > 0 &&
a.every((x) => typeof x === "string" && /\S/.test(x));
let bad = 0;
for (const [name, r] of Object.entries(refs)) {
if (!String(r.sharedConnectionId || "").trim()) continue;
const t = Object.entries(r.dataSets || {}).flatMap(([d, s]) =>
Object.entries(s.dataSources || {}).map(([k, v]) => [d + "/" + k, v]));
if (r.allowedActions !== undefined && !ok(r.allowedActions)) {
bad++;
console.log("INVALID connector-level allowedActions: " + name);
}
if (t.length) {
for (const [p, v] of t) if (!ok(v.allowedActions)) { bad++; console.log("MISSING per-table allowedActions: " + name + " -> " + p); }
} else if (r.allowedActions === undefined) { bad++; console.log("MISSING connector-level allowedActions: " + name); }
}
if (bad) { console.log(bad + " issue(s): fix before deploy"); process.exitCode = 1; } else console.log("OK: all shared references declare allowedActions");
'If it prints OK, skip to Step 5 — the connection isn't shared, or is already covered.
4b. If it is shared, determine the shape:
| Reference has… | Declare |
dataset tables (dataSets) | per-table allowedActions — every table, from "get" / "post" / "patch" / "delete" |
| no dataset tables | connector-level allowedActions — Action IDs from ms connector list-actions --connector <api-id> --json (id, behavior: Allow only) |
4c. Infer least privilege, then confirm. Grep src/ for calls into the generated service
and map them to values (read/list → get, create → post, update → patch, delete →
delete). Present the inferred list and ask the user to confirm or adjust:
"
<reference>is a shared connection, so it needs an action policy before deploy. From the code, I'd declare<inferred>. Anything else it should be allowed to do?"
Never grant the full set just to pass validation.
Deferral — when there is no app code yet. If src/ has no calls into this service because
the app hasn't been written yet (the usual case when /create-app invokes this skill before
generating the UI), do not guess and do not prompt. Instead:
- Leave
allowedActionsunset for now.ms app devdoes not validate it, so local iteration is unaffected — onlyms app pack/ms app deploydo. - Record the reference as shared, policy pending in
memory-bank.md. - Note it in your summary so the decision happens once the app code exists.
/deploy re-runs this same check as a preflight gate, so a deferred policy is caught before it
can reach a failing deploy — not silently forgotten.
4d. Write the confirmed values into ms.config.json (skip when deferring).
Full rules, worked examples, and failure recovery: allowed-actions.md.
Step 5: Build
npm run buildStep 6: Memory Update
If memory-bank.md exists, record api-id, mode, parameters used, and — when the reference is
shared — the allowedActions that were agreed, so the next session doesn't re-litigate them.
Common Presets
| Wrapper skill | api-id | mode |
/add-dataverse | dataverse | table |
/add-sharepoint | shared_sharepointonline | table |
/add-excel | shared_excelonlinebusiness | table |
/add-office365 | shared_office365 | action |
/add-office365-users | shared_office365users | action |
/add-teams | shared_teams | action |
/add-onedrive | shared_onedriveforbusiness | action |
/add-azuredevops | shared_visualstudioteamservices | action |
/add-mcscopilot | microsoftcopilotstudio | action |
/add-workiq | shared_a365copilotchatmcp | action |
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- microsoft/power-platform-skills★ 1.1ksame name
- nirholas/free-crypto-news★ 331same name
- nirholas/cryptocurrency.cv★ 330same name
- paulieb89/property-shared★ 16same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository23 other files it gives its agents.
- github-actions/AGENTS.mdAGENTS.md
- plugins/microsoft-managed-apps/AGENTS.mdAGENTS.md
- add-azuredevopsSkill
- add-backendSkill
- add-dataverseSkill
- add-excelSkill
- add-mcscopilotSkill
- add-office365Skill
- add-office365-usersSkill
- add-onedriveSkill
- add-sharepointSkill
- add-teamsSkill
- add-workiqSkill
- create-appSkill
- delete-appSkill
- deploySkill
- devSkill
- list-appsSkill
- list-connectorsSkill
- playSkill
- share-linkSkill
- shareSkill
- stateSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

