mcp-server-for-ynab 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_server_for_ynab-0.1.0/.agents/.skill-lock.json +42 -0
- mcp_server_for_ynab-0.1.0/.agents/README.md +34 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/agent-runtime-guardrails/SKILL.md +56 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/architecture-boundaries/SKILL.md +67 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/contract-sync/SKILL.md +59 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/data-access-discipline/SKILL.md +58 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/docs-honesty/SKILL.md +54 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/hardening-review/SKILL.md +57 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/live-api-verification/SKILL.md +113 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/local-workflow-reproducibility/SKILL.md +54 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/postman-standards/SKILL.md +46 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/python-api-docs/SKILL.md +52 -0
- mcp_server_for_ynab-0.1.0/.agents/skills/ynab-platform-compliance/SKILL.md +120 -0
- mcp_server_for_ynab-0.1.0/.env.example +28 -0
- mcp_server_for_ynab-0.1.0/.github/CODEOWNERS +3 -0
- mcp_server_for_ynab-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +72 -0
- mcp_server_for_ynab-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +42 -0
- mcp_server_for_ynab-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +34 -0
- mcp_server_for_ynab-0.1.0/.github/dependabot.yml +20 -0
- mcp_server_for_ynab-0.1.0/.github/workflows/ci.yml +81 -0
- mcp_server_for_ynab-0.1.0/.github/workflows/release.yml +88 -0
- mcp_server_for_ynab-0.1.0/.gitignore +52 -0
- mcp_server_for_ynab-0.1.0/.python-version +1 -0
- mcp_server_for_ynab-0.1.0/AGENTS.md +246 -0
- mcp_server_for_ynab-0.1.0/CODE_OF_CONDUCT.md +50 -0
- mcp_server_for_ynab-0.1.0/CONTRIBUTING.md +214 -0
- mcp_server_for_ynab-0.1.0/LICENSE +176 -0
- mcp_server_for_ynab-0.1.0/Makefile +161 -0
- mcp_server_for_ynab-0.1.0/NOTICE.md +12 -0
- mcp_server_for_ynab-0.1.0/PKG-INFO +354 -0
- mcp_server_for_ynab-0.1.0/README.md +324 -0
- mcp_server_for_ynab-0.1.0/SECURITY.md +67 -0
- mcp_server_for_ynab-0.1.0/docs/README.md +191 -0
- mcp_server_for_ynab-0.1.0/docs/architecture.md +331 -0
- mcp_server_for_ynab-0.1.0/docs/client-setup.md +500 -0
- mcp_server_for_ynab-0.1.0/docs/repo-structure.md +155 -0
- mcp_server_for_ynab-0.1.0/docs/security.md +57 -0
- mcp_server_for_ynab-0.1.0/docs/testing.md +311 -0
- mcp_server_for_ynab-0.1.0/docs/tool-surface.md +214 -0
- mcp_server_for_ynab-0.1.0/postman/README.md +158 -0
- mcp_server_for_ynab-0.1.0/postman/collections/ynab-operator.postman_collection.json +2113 -0
- mcp_server_for_ynab-0.1.0/postman/collections/ynab-qa.postman_collection.json +1830 -0
- mcp_server_for_ynab-0.1.0/postman/environments/ynab-operator.postman_environment.json +106 -0
- mcp_server_for_ynab-0.1.0/postman/environments/ynab-qa.postman_environment.json +86 -0
- mcp_server_for_ynab-0.1.0/postman/sources/operator/routes.yaml +859 -0
- mcp_server_for_ynab-0.1.0/pyproject.toml +115 -0
- mcp_server_for_ynab-0.1.0/scripts/generate_operator_collection.py +271 -0
- mcp_server_for_ynab-0.1.0/scripts/generate_qa_collection.py +559 -0
- mcp_server_for_ynab-0.1.0/scripts/live_read_sweep.py +206 -0
- mcp_server_for_ynab-0.1.0/scripts/live_write_sweep.py +369 -0
- mcp_server_for_ynab-0.1.0/scripts/mcp_http_check.sh +159 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/__init__.py +19 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/auth/__init__.py +4 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/auth/base.py +22 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/auth/pat.py +23 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/cli/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/cli/main.py +241 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/cli/smoke.py +48 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/config/__init__.py +3 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/config/settings.py +98 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/embed.py +47 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/enriched/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/enriched/analysis.py +158 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/enriched/bookkeeping.py +179 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/enriched/overview.py +162 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/enriched/triage.py +82 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/history/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/history/capture.py +159 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/history/journal.py +194 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/history/revert.py +225 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/http_client/__init__.py +3 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/http_client/client.py +222 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/http_client/rate_budget.py +98 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/__init__.py +14 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/amounts.py +56 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/errors.py +106 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/__init__.py +1 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/accounts.py +73 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/categories.py +106 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/common.py +17 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/money_movements.py +62 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/months.py +44 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/payees.py +59 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/plans.py +62 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/scheduled_transactions.py +75 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/transactions.py +171 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/models/ynab/user.py +15 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/py.typed +0 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/app.py +69 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/context.py +136 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/registry.py +75 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/boundary.py +63 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/enriched.py +333 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/history.py +118 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/pagination.py +53 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/__init__.py +13 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/accounts.py +91 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/categories.py +254 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/money_movements.py +110 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/months.py +58 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/payees.py +168 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/plans.py +70 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/scheduled_transactions.py +191 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/transactions.py +574 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/raw/user.py +31 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/server/tools/registration.py +31 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/__init__.py +21 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/accounts.py +32 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/base.py +10 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/categories.py +92 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/money_movements.py +50 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/months.py +23 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/payees.py +72 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/plans.py +32 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/scheduled_transactions.py +52 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/transactions.py +210 -0
- mcp_server_for_ynab-0.1.0/src/mcp_server_for_ynab/ynab_client/user.py +11 -0
- mcp_server_for_ynab-0.1.0/tests/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/conftest.py +90 -0
- mcp_server_for_ynab-0.1.0/tests/contract/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/contract/test_categories_client.py +123 -0
- mcp_server_for_ynab-0.1.0/tests/contract/test_money_movements_client.py +163 -0
- mcp_server_for_ynab-0.1.0/tests/contract/test_transactions_client.py +145 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/money_movement_groups_list.json +23 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/money_movements_list.json +49 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/scheduled_transaction_create.json +11 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/transaction_create.json +12 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/transaction_create_invalid.json +3 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/transaction_create_split.json +23 -0
- mcp_server_for_ynab-0.1.0/tests/fixtures/transactions_bulk_update.json +33 -0
- mcp_server_for_ynab-0.1.0/tests/integration/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/integration/test_error_boundary.py +159 -0
- mcp_server_for_ynab-0.1.0/tests/integration/test_server_version.py +33 -0
- mcp_server_for_ynab-0.1.0/tests/integration/test_startup.py +80 -0
- mcp_server_for_ynab-0.1.0/tests/integration/test_transaction_pagination.py +158 -0
- mcp_server_for_ynab-0.1.0/tests/integration/test_write_gate.py +86 -0
- mcp_server_for_ynab-0.1.0/tests/qa/cases/01_auth_and_plans.yaml +167 -0
- mcp_server_for_ynab-0.1.0/tests/qa/cases/02_accounts_and_categories.yaml +177 -0
- mcp_server_for_ynab-0.1.0/tests/qa/cases/03_transactions_read.yaml +250 -0
- mcp_server_for_ynab-0.1.0/tests/qa/cases/04_error_handling.yaml +97 -0
- mcp_server_for_ynab-0.1.0/tests/qa/features/01_auth_and_plans.feature +50 -0
- mcp_server_for_ynab-0.1.0/tests/qa/features/02_accounts_and_categories.feature +52 -0
- mcp_server_for_ynab-0.1.0/tests/qa/features/03_transactions_read.feature +78 -0
- mcp_server_for_ynab-0.1.0/tests/qa/features/04_error_handling.feature +37 -0
- mcp_server_for_ynab-0.1.0/tests/unit/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_cli/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_cli/test_resolve_bind.py +49 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_cli/test_startup_errors.py +74 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_config/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_config/test_settings.py +65 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_enriched/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_enriched/builders.py +222 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_enriched/test_analysis.py +191 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_enriched/test_bookkeeping.py +151 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_enriched/test_overview.py +124 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_enriched/test_triage.py +98 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_history/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_history/test_history_path.py +73 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_history/test_journal.py +82 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_history/test_revert.py +189 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_http_client/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_http_client/test_rate_budget.py +82 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_http_client/test_rate_limit.py +103 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_http_client/test_retries.py +152 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_models/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_models/test_amounts.py +57 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_models/test_errors.py +75 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_packaging.py +28 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_server/__init__.py +0 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_server/test_embed.py +46 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_server/test_pagination.py +73 -0
- mcp_server_for_ynab-0.1.0/tests/unit/test_server/test_split_transactions.py +225 -0
- mcp_server_for_ynab-0.1.0/uv.lock +1002 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"skills": {
|
|
4
|
+
"find-skills": {
|
|
5
|
+
"source": "vercel-labs/skills",
|
|
6
|
+
"sourceType": "github",
|
|
7
|
+
"sourceUrl": "https://github.com/vercel-labs/skills.git",
|
|
8
|
+
"skillPath": "skills/find-skills/SKILL.md",
|
|
9
|
+
"skillFolderHash": "3013fdeb8a11b10b1eb795ec3ae8bfca38f7c26d",
|
|
10
|
+
"installedAt": "2026-04-06T01:04:58.085Z",
|
|
11
|
+
"updatedAt": "2026-04-06T01:04:58.085Z"
|
|
12
|
+
},
|
|
13
|
+
"writing-clearly-and-concisely": {
|
|
14
|
+
"source": "softaworks/agent-toolkit",
|
|
15
|
+
"sourceType": "github",
|
|
16
|
+
"sourceUrl": "https://github.com/softaworks/agent-toolkit.git",
|
|
17
|
+
"skillPath": "skills/writing-clearly-and-concisely/SKILL.md",
|
|
18
|
+
"skillFolderHash": "4bb2d919b567277219f7a18358bd05e0a1679a77",
|
|
19
|
+
"installedAt": "2026-04-06T01:05:44.917Z",
|
|
20
|
+
"updatedAt": "2026-04-06T01:05:44.917Z"
|
|
21
|
+
},
|
|
22
|
+
"requesting-code-review": {
|
|
23
|
+
"source": "obra/superpowers",
|
|
24
|
+
"sourceType": "github",
|
|
25
|
+
"sourceUrl": "https://github.com/obra/superpowers.git",
|
|
26
|
+
"skillPath": "skills/requesting-code-review/SKILL.md",
|
|
27
|
+
"skillFolderHash": "ed265b1a03114cc400d5524afc5c961a4aa9ea8b",
|
|
28
|
+
"installedAt": "2026-04-06T01:06:17.201Z",
|
|
29
|
+
"updatedAt": "2026-04-06T01:06:17.201Z"
|
|
30
|
+
},
|
|
31
|
+
"karpathy-guidelines": {
|
|
32
|
+
"source": "forrestchang/andrej-karpathy-skills",
|
|
33
|
+
"sourceType": "github",
|
|
34
|
+
"sourceUrl": "https://github.com/forrestchang/andrej-karpathy-skills.git",
|
|
35
|
+
"skillPath": "skills/karpathy-guidelines/SKILL.md",
|
|
36
|
+
"skillFolderHash": "e119339197d600aa39a24fd7a95c946800c9c949",
|
|
37
|
+
"installedAt": "2026-04-06T03:02:13.858Z",
|
|
38
|
+
"updatedAt": "2026-04-06T03:02:13.858Z"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"dismissed": {}
|
|
42
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Agent skills (mcp-server-for-ynab)
|
|
2
|
+
|
|
3
|
+
This repository is **Python**. Skills under `skills/` assume:
|
|
4
|
+
|
|
5
|
+
- **`pyproject.toml`** for dependencies, scripts, and tool config (`ruff`, `pytest`, `mypy`, etc.)
|
|
6
|
+
- **MCP** as the primary agent surface (thin tools, logic in services/domain modules)
|
|
7
|
+
- **`pytest`** for tests; optional HTTP/Postman only if documented in the repo
|
|
8
|
+
|
|
9
|
+
| Skill | When to use |
|
|
10
|
+
|-------|-------------|
|
|
11
|
+
| `architecture-boundaries` | Layering MCP tools, services, clients, persistence |
|
|
12
|
+
| `agent-runtime-guardrails` | MCP tools, prompts, observability, bounded behavior |
|
|
13
|
+
| `python-api-docs` | Docstrings, type hints, public API and tool descriptions |
|
|
14
|
+
| `contract-sync` | Pydantic models, OpenAPI, schemas, generated artifacts |
|
|
15
|
+
| `live-api-verification` | Response models, new routes, transport changes, "does it work" claims |
|
|
16
|
+
| `ynab-platform-compliance` | Naming, branding, disclaimers, privacy policy, OAuth, rate limits |
|
|
17
|
+
| `data-access-discipline` | DB schema, queries, transactions (if used) |
|
|
18
|
+
| `docs-honesty` | README and docs match implementation |
|
|
19
|
+
| `local-workflow-reproducibility` | Local dev, env, seeds, repeatable commands |
|
|
20
|
+
| `hardening-review` | Pre-merge / signoff review |
|
|
21
|
+
| `postman-standards` | Only if repo maintains HTTP Postman collections |
|
|
22
|
+
| `karpathy-guidelines` | General coding discipline |
|
|
23
|
+
| `find-skills` | Discover installable skills from the ecosystem |
|
|
24
|
+
| `requesting-code-review` | Structured review before merge |
|
|
25
|
+
| `writing-clearly-and-concisely` | Human-facing prose |
|
|
26
|
+
|
|
27
|
+
## Third-party skills
|
|
28
|
+
|
|
29
|
+
Skills installed from other repositories are recorded in `.skill-lock.json` but
|
|
30
|
+
their content is **not** committed here — they carry their own upstream licenses,
|
|
31
|
+
and vendoring them would redistribute someone else's work from an Apache-2.0
|
|
32
|
+
repo. Reinstall them from the lock file if you want them locally.
|
|
33
|
+
|
|
34
|
+
The skills tracked in this repository are its own.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-runtime-guardrails
|
|
3
|
+
description: Keep autonomous runtime behavior observable, bounded, and separate from durable business logic.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Runtime Guardrails
|
|
7
|
+
|
|
8
|
+
Use this skill when working on MCP servers, tool execution, planning loops, memory, checkpoints, approvals, or other agent-facing runtime behavior in this **Python** repository.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- Adding or editing MCP tools, resources, or prompts
|
|
13
|
+
- Changing tool-calling or error-mapping behavior
|
|
14
|
+
- Adding memory or checkpoint systems
|
|
15
|
+
- Adding human-in-the-loop approval boundaries
|
|
16
|
+
- Reviewing runtime safety and observability
|
|
17
|
+
|
|
18
|
+
## Read First
|
|
19
|
+
|
|
20
|
+
- `AGENTS.md` (if present)
|
|
21
|
+
- `README.md`
|
|
22
|
+
- MCP SDK usage in this repo (server setup, lifespan, tool registration)
|
|
23
|
+
- Any runtime or workflow docs (for example `docs/agent-design.md`, `docs/current-state.md`)
|
|
24
|
+
|
|
25
|
+
## Core Rules
|
|
26
|
+
|
|
27
|
+
1. Prompts and tool descriptions do not replace durable business rules or validation in code.
|
|
28
|
+
2. Ephemeral conversation or session state does not replace persistent storage when durability is required.
|
|
29
|
+
3. Runtime orchestration should be observable (structured logging, clear error types, traceable tool results).
|
|
30
|
+
4. Human approvals or intervention boundaries should be explicit where relevant.
|
|
31
|
+
5. Tools must not silently bypass application invariants (budget scope, auth, rate limits).
|
|
32
|
+
6. Long-running or multi-step behavior should use explicit checkpoints or idempotent steps—not implicit “continue from chat” assumptions.
|
|
33
|
+
7. Tool and server capabilities advertised to clients must match what is implemented.
|
|
34
|
+
8. **MCP boundary:** Each tool should have a narrow, documented contract (Pydantic models or typed parameters). Prefer structured errors (`isError`, clear messages) over opaque stack traces in tool results.
|
|
35
|
+
|
|
36
|
+
## Workflow
|
|
37
|
+
|
|
38
|
+
1. Identify what belongs in MCP wiring versus service/domain logic.
|
|
39
|
+
2. Make durable state transitions explicit in code, not only in prompts.
|
|
40
|
+
3. Ensure important steps are observable through logs or persisted records.
|
|
41
|
+
4. Check auth, env vars, and secrets handling (`YNAB_*`, tokens via env—not hardcoded).
|
|
42
|
+
5. Update docs if tool behavior or required env changed.
|
|
43
|
+
6. Verify unhappy paths: API failures, partial data, timeouts, invalid user input.
|
|
44
|
+
|
|
45
|
+
## Common Failure Modes
|
|
46
|
+
|
|
47
|
+
- critical logic only in tool docstrings or system prompts
|
|
48
|
+
- session memory used as system-of-record
|
|
49
|
+
- unhandled exceptions surfaced as generic tool failures
|
|
50
|
+
- no clear boundary between “call YNAB API” and “orchestrate workflow”
|
|
51
|
+
- tools that do too much in one invocation
|
|
52
|
+
- overstated autonomy in README vs actual tool set
|
|
53
|
+
|
|
54
|
+
## Completion Standard
|
|
55
|
+
|
|
56
|
+
Runtime behavior is bounded, observable, documented honestly, and does not hide durable business logic behind MCP or prompt layers.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture-boundaries
|
|
3
|
+
description: Preserve clean system layering and prevent logic from smearing across handlers, services, persistence, integrations, and agent runtime.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Architecture Boundaries
|
|
7
|
+
|
|
8
|
+
Use this skill when adding or changing core logic, MCP tools, HTTP APIs, jobs, integrations, or runtime orchestration in this **Python** repository.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- Adding MCP tools, resources, or prompts
|
|
13
|
+
- Adding HTTP routes (if any)
|
|
14
|
+
- Adding orchestration or business logic
|
|
15
|
+
- Adding database access patterns
|
|
16
|
+
- Adding jobs, workers, or scheduled tasks
|
|
17
|
+
- Adding third-party integrations (for example YNAB API clients)
|
|
18
|
+
- Reviewing whether a change belongs in the right layer
|
|
19
|
+
|
|
20
|
+
## Read First
|
|
21
|
+
|
|
22
|
+
- `AGENTS.md` (if present)
|
|
23
|
+
- `README.md`
|
|
24
|
+
- `pyproject.toml` (package layout, entry points)
|
|
25
|
+
- Any repo-specific architecture docs (for example `docs/architecture.md`, `docs/current-state.md`)
|
|
26
|
+
|
|
27
|
+
## Core Rules
|
|
28
|
+
|
|
29
|
+
1. **Transport / protocol layer** (MCP server setup, FastAPI routers, CLI entrypoints) owns wiring, validation at the boundary, and mapping to/from wire types—not core business rules.
|
|
30
|
+
2. **Services or domain modules** own workflows, state transitions, and business rules.
|
|
31
|
+
3. **Data access** owns persistence and queries, not business policy.
|
|
32
|
+
4. **Integration clients** (YNAB SDK, HTTP clients) own provider-specific IO and normalization, not app-wide orchestration.
|
|
33
|
+
5. **MCP tool handlers** should stay thin: parse inputs, call services, map errors to structured tool results. Do not hide durable invariants only in tool docstrings or prompts.
|
|
34
|
+
6. Do not invent a parallel architecture when the repo already has one; follow existing package layout (`src/` layout, module naming).
|
|
35
|
+
7. Keep boundaries obvious enough that future agents can place code correctly.
|
|
36
|
+
8. **Multi-step workflows:** Reusable step logic belongs in domain or service modules, not duplicated in each tool or route.
|
|
37
|
+
9. **Persistence:** Prefer normalized storage and explicit fields as source of truth. Use **`data-access-discipline`** for schema and transactions.
|
|
38
|
+
|
|
39
|
+
## Typical Python layout (adapt to this repo)
|
|
40
|
+
|
|
41
|
+
| Layer | Examples |
|
|
42
|
+
|-------|----------|
|
|
43
|
+
| Entry | `__main__.py`, `server.py`, Typer/Click CLI, FastAPI `APIRouter` |
|
|
44
|
+
| MCP surface | Tool/resource registration; argument validation via Pydantic |
|
|
45
|
+
| Services | `services/`, `domain/`, use-case functions |
|
|
46
|
+
| Integrations | `clients/ynab.py`, thin wrappers around external APIs |
|
|
47
|
+
| Persistence | `db/`, repositories, SQLAlchemy models (if used) |
|
|
48
|
+
|
|
49
|
+
## Workflow
|
|
50
|
+
|
|
51
|
+
1. Identify the type of change: protocol surface, orchestration, persistence, integration.
|
|
52
|
+
2. Find the existing repo pattern for that kind of work.
|
|
53
|
+
3. Place new logic in the narrowest correct layer.
|
|
54
|
+
4. Check whether cross-layer documentation needs to be updated.
|
|
55
|
+
5. Verify the change did not create new ambiguity about responsibility.
|
|
56
|
+
|
|
57
|
+
## Common Failure Modes
|
|
58
|
+
|
|
59
|
+
- business logic in MCP tool functions or route handlers
|
|
60
|
+
- raw DB or file access scattered through tools
|
|
61
|
+
- integration clients owning multi-step workflows
|
|
62
|
+
- prompts replacing durable validation rules
|
|
63
|
+
- multiple competing patterns for the same concern
|
|
64
|
+
|
|
65
|
+
## Completion Standard
|
|
66
|
+
|
|
67
|
+
The change fits the existing architecture cleanly, layer responsibilities remain legible, and no new ambiguity was introduced.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contract-sync
|
|
3
|
+
description: Keep source-of-truth contracts, generated artifacts, and tests aligned whenever interfaces change.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Contract Sync
|
|
7
|
+
|
|
8
|
+
Use this skill when the repo has any source-of-truth contract and derived artifacts such as OpenAPI, JSON Schema, generated clients, MCP tool schemas, or prompt/task contracts.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- Changing HTTP routes or MCP tool inputs/outputs
|
|
13
|
+
- Changing request or response shapes (Pydantic models, dataclasses, TypedDicts)
|
|
14
|
+
- Changing schema-driven generated artifacts
|
|
15
|
+
- Updating public interface docs
|
|
16
|
+
- Updating codegen outputs
|
|
17
|
+
- Reviewing drift between source and generated files
|
|
18
|
+
|
|
19
|
+
## Read First
|
|
20
|
+
|
|
21
|
+
- `AGENTS.md` (if present)
|
|
22
|
+
- `README.md` and `pyproject.toml` (`[project.scripts]`, `[tool.*]`, optional dependency groups)
|
|
23
|
+
- `CONTRIBUTING.md` if present and maintained
|
|
24
|
+
- Contract-related docs in this repo (for example `docs/api-strategy.md`, `docs/contract-discipline.md`)
|
|
25
|
+
- `postman/` or OpenAPI under `docs/api/`, only if this repo maintains them
|
|
26
|
+
- Generation scripts under `scripts/` or `tools/`
|
|
27
|
+
|
|
28
|
+
## Core Rules
|
|
29
|
+
|
|
30
|
+
1. Identify the source of truth before editing anything.
|
|
31
|
+
- Common patterns in Python repos: **Pydantic** (or similar) models; FastAPI/Starlette route signatures; hand-authored OpenAPI; JSON Schema; MCP tool parameter schemas derived from types or explicit definitions.
|
|
32
|
+
- Derived artifacts (OpenAPI YAML, JSON Schema exports, generated clients, Postman collections) must be regenerated from that source unless the repo documents otherwise.
|
|
33
|
+
2. Do not hand-edit generated artifacts unless the repo explicitly says to.
|
|
34
|
+
3. Regenerate derived artifacts when the source changes, using commands in `pyproject.toml`, `Makefile`, `uv run`, `poetry run`, or documented in `README.md` / `AGENTS.md`.
|
|
35
|
+
4. Commit source changes and generated changes together.
|
|
36
|
+
5. Update docs that describe the public or shared contract surface.
|
|
37
|
+
6. Ensure tests validate the actual interface (`pytest`, contract tests, schema snapshots)—not only internal mocks.
|
|
38
|
+
|
|
39
|
+
## Workflow
|
|
40
|
+
|
|
41
|
+
1. Determine whether the change affects a contract.
|
|
42
|
+
2. Identify the hand-authored source and the generated outputs (`pyproject.toml`, CI config, repo docs).
|
|
43
|
+
3. Update the source of truth (models, tool definitions, route handlers).
|
|
44
|
+
4. Run the appropriate generation or export step.
|
|
45
|
+
5. Update any relevant docs or examples.
|
|
46
|
+
6. Run the relevant tests or checks.
|
|
47
|
+
|
|
48
|
+
## Common Failure Modes
|
|
49
|
+
|
|
50
|
+
- generated artifacts not regenerated
|
|
51
|
+
- public docs still describing old request or response shapes
|
|
52
|
+
- manually patched generated files
|
|
53
|
+
- tests passing while contract artifacts drift
|
|
54
|
+
- MCP tool schema out of sync with implementation
|
|
55
|
+
- temporary undocumented contract changes
|
|
56
|
+
|
|
57
|
+
## Completion Standard
|
|
58
|
+
|
|
59
|
+
The source-of-truth contract, generated artifacts, tests, and docs all describe the same interface.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: data-access-discipline
|
|
3
|
+
description: Keep persistence logic explicit, consistent, and separate from transport concerns and business rules.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Data Access Discipline
|
|
7
|
+
|
|
8
|
+
Use this skill when adding tables, queries, migrations, persistence helpers, cross-entity writes, or scope or tenant enforcement.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- Adding or changing schema
|
|
13
|
+
- Writing new queries
|
|
14
|
+
- Adding persistence helpers or repository modules
|
|
15
|
+
- Adding cross-table workflows
|
|
16
|
+
- Reviewing DB access placement
|
|
17
|
+
- Tightening scope or tenant rules
|
|
18
|
+
|
|
19
|
+
## Read First
|
|
20
|
+
|
|
21
|
+
- `AGENTS.md` (if present)
|
|
22
|
+
- `README.md`
|
|
23
|
+
- Architecture and data docs in this repo (for example `docs/architecture.md`, `docs/data-access-patterns.md`, `docs/data-model.md`, `docs/environment.md`)
|
|
24
|
+
- Migration tooling config (for example `alembic.ini`, SQLAlchemy models under `src/`, Django migrations—whatever this repo uses)
|
|
25
|
+
|
|
26
|
+
## Core Rules
|
|
27
|
+
|
|
28
|
+
1. Persistence code should be consistent and discoverable.
|
|
29
|
+
2. Business rules should not be buried in route or MCP tool handlers.
|
|
30
|
+
3. Persistence helpers should not quietly own domain policy.
|
|
31
|
+
4. Cross-entity workflows should have a clear orchestration layer (service/module), not ad hoc scripts.
|
|
32
|
+
5. Scope or tenant boundaries should be enforced explicitly.
|
|
33
|
+
6. Schema changes, migrations, and related docs should move together.
|
|
34
|
+
7. Domain-facing shapes should be intentional, not accidental spillover from ORM rows or raw dicts.
|
|
35
|
+
8. **Single source of truth:** Prefer normalized tables and explicit columns for durable state. In-memory aggregates assembled for reads must not be duplicated as parallel persisted blobs unless documented and intentional.
|
|
36
|
+
9. **Multi-write consistency:** When several SQL statements must succeed or fail together, use one outer transaction (`session.begin()`, `async with session.begin()`, or equivalent). Pass the same session/connection into helpers; avoid nested transaction calls that commit independently. Keep slow network or external API calls outside the transaction; persist only after durable inputs are ready.
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
1. Identify whether the task is schema, query, migration, or workflow related.
|
|
41
|
+
2. Place query or persistence logic in the repo’s established pattern.
|
|
42
|
+
3. Keep cross-entity business logic out of thin repository functions.
|
|
43
|
+
4. Review whether scope and ownership enforcement are explicit.
|
|
44
|
+
5. Update migrations, docs, and tests as needed.
|
|
45
|
+
|
|
46
|
+
## Common Failure Modes
|
|
47
|
+
|
|
48
|
+
- raw SQL or ORM calls scattered unpredictably
|
|
49
|
+
- MCP handlers or FastAPI routes directly owning DB logic
|
|
50
|
+
- hidden cross-tenant reads or writes
|
|
51
|
+
- business rules implemented implicitly in query code
|
|
52
|
+
- schema changes without migration or documentation updates
|
|
53
|
+
- leaking ORM instances or untyped dicts into higher layers without intent
|
|
54
|
+
- multiple commits for one logical unit of work
|
|
55
|
+
|
|
56
|
+
## Completion Standard
|
|
57
|
+
|
|
58
|
+
The data-access change follows the repo’s pattern, respects scope boundaries, keeps business logic in the right place, and remains easy to reason about.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docs-honesty
|
|
3
|
+
description: Keep repo documentation aligned with implementation reality and prevent overclaiming.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Docs Honesty
|
|
7
|
+
|
|
8
|
+
Use this skill when changing documentation or when code changes affect documented behavior.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- Updating README
|
|
13
|
+
- Updating architecture docs
|
|
14
|
+
- Updating current-state docs
|
|
15
|
+
- Adding or modifying workflows
|
|
16
|
+
- Changing behavior that docs describe
|
|
17
|
+
- Reviewing whether docs still match implementation
|
|
18
|
+
|
|
19
|
+
## Read First
|
|
20
|
+
|
|
21
|
+
- `AGENTS.md` (if present)
|
|
22
|
+
- `README.md`
|
|
23
|
+
- Relevant architecture docs in this repo (for example `docs/architecture.md`, `docs/system-design.md`, `docs/current-state.md`)
|
|
24
|
+
- `CONTRIBUTING.md` (if maintained)
|
|
25
|
+
|
|
26
|
+
## Core Rules
|
|
27
|
+
|
|
28
|
+
1. Distinguish implemented vs deferred vs conceptual.
|
|
29
|
+
2. Do not present future-state thinking as current-state reality.
|
|
30
|
+
3. If behavior changed materially, update the matching docs in the same task.
|
|
31
|
+
4. If a documented flow or relationship changed materially, update the matching diagram (for example Mermaid) in the same task when the repo uses diagrams for that flow.
|
|
32
|
+
5. Prefer blunt accuracy over polished ambiguity.
|
|
33
|
+
6. If something is partial, say it is partial.
|
|
34
|
+
7. If something is unknown, mark it as unknown.
|
|
35
|
+
|
|
36
|
+
## Workflow
|
|
37
|
+
|
|
38
|
+
1. Inspect the code or behavior being changed.
|
|
39
|
+
2. Identify which docs claim or imply behavior in that area.
|
|
40
|
+
3. Update the docs so they match actual implementation.
|
|
41
|
+
4. Check whether a diagram should be added or updated.
|
|
42
|
+
5. Re-read for overstatement, stale claims, and future-state leakage.
|
|
43
|
+
|
|
44
|
+
## Common Failure Modes
|
|
45
|
+
|
|
46
|
+
- README implies the system is more complete than it is
|
|
47
|
+
- architecture docs describe intended design instead of implemented behavior
|
|
48
|
+
- current-state doc is stale
|
|
49
|
+
- diagrams describe old flows
|
|
50
|
+
- partial systems are described as complete
|
|
51
|
+
|
|
52
|
+
## Completion Standard
|
|
53
|
+
|
|
54
|
+
The relevant docs accurately describe the current implementation and clearly label deferred or conceptual work.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hardening-review
|
|
3
|
+
description: Review completed work for edge cases, drift, missing tests, overstated claims, and signoff readiness.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Hardening Review
|
|
7
|
+
|
|
8
|
+
Use this skill when reviewing a completed feature, workflow, or integration for quality and signoff readiness in this **Python** repository.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- Reviewing another agent’s work
|
|
13
|
+
- Preparing for merge
|
|
14
|
+
- Auditing a feature or phase
|
|
15
|
+
- Checking whether implementation is truly complete
|
|
16
|
+
- Looking for edge cases and drift
|
|
17
|
+
|
|
18
|
+
## Read First
|
|
19
|
+
|
|
20
|
+
- `AGENTS.md` (if present)
|
|
21
|
+
- `README.md` and `pyproject.toml`
|
|
22
|
+
- Relevant architecture docs and tests under `tests/`
|
|
23
|
+
- Contract or MCP tool schema docs, if present
|
|
24
|
+
|
|
25
|
+
## Core Rules
|
|
26
|
+
|
|
27
|
+
1. “Works on the happy path” is not enough.
|
|
28
|
+
2. Docs honesty is part of completion.
|
|
29
|
+
3. Missing or weak tests (`pytest`) are a real issue, not a footnote.
|
|
30
|
+
4. Scope, auth, or boundary mistakes are high severity (wrong budget, leaked tokens in logs).
|
|
31
|
+
5. Generated artifact drift (OpenAPI, schemas) matters when the repo uses codegen.
|
|
32
|
+
6. Overclaiming implementation is a bug.
|
|
33
|
+
7. Review should prioritize bugs, regressions, and risks before summaries.
|
|
34
|
+
8. Run or verify `pytest`, `ruff`, `mypy`/`pyright`—whatever this repo’s CI uses—when judging signoff.
|
|
35
|
+
|
|
36
|
+
## Workflow
|
|
37
|
+
|
|
38
|
+
1. Identify the implemented scope.
|
|
39
|
+
2. Check the actual code path, not just the claimed behavior.
|
|
40
|
+
3. Review unhappy paths and partial-data behavior (API errors, empty lists, invalid ids).
|
|
41
|
+
4. Check docs and contract alignment (README, tool descriptions, Pydantic models).
|
|
42
|
+
5. Check tests for real proof, not only heavy mocking of the code under test.
|
|
43
|
+
6. Report findings ordered by severity.
|
|
44
|
+
7. State clearly whether the work is signoff-ready.
|
|
45
|
+
|
|
46
|
+
## Common Failure Modes
|
|
47
|
+
|
|
48
|
+
- unit tests exist but MCP tools or integrations are untested
|
|
49
|
+
- docs still describe old or aspirational behavior
|
|
50
|
+
- env vars or secrets handling is unclear or unsafe
|
|
51
|
+
- generated artifacts drift from Pydantic/OpenAPI source
|
|
52
|
+
- incomplete feature presented as complete
|
|
53
|
+
- type hints lie about optional vs required fields
|
|
54
|
+
|
|
55
|
+
## Completion Standard
|
|
56
|
+
|
|
57
|
+
The work has been checked for implementation reality, unhappy paths, docs honesty, contract alignment, and verification depth, and is clearly judged ready or not ready for signoff.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: live-api-verification
|
|
3
|
+
description: Verify response models and MCP transports against the real YNAB API before claiming a tool works.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Live API Verification
|
|
7
|
+
|
|
8
|
+
Use this skill whenever a change touches how a YNAB response is parsed, or how
|
|
9
|
+
an agent connects to the server. The test suite cannot catch drift between a
|
|
10
|
+
response model and the real API, because every payload in it was written by
|
|
11
|
+
hand: the model and the fixture are the same guess.
|
|
12
|
+
|
|
13
|
+
## Use When
|
|
14
|
+
|
|
15
|
+
- Adding or editing a model under `src/mcp_server_for_ynab/models/ynab/`
|
|
16
|
+
- Adding a raw tool or a `ynab_client` wrapper for a new route
|
|
17
|
+
- Upgrading the `mcp` SDK, or changing transport/CLI startup
|
|
18
|
+
- Reviewing a claim that a tool "works" when only unit tests were run
|
|
19
|
+
- Investigating a tool that fails in a client but passes in CI
|
|
20
|
+
|
|
21
|
+
## The Failures This Prevents
|
|
22
|
+
|
|
23
|
+
The money movement models were written by analogy with transactions. They
|
|
24
|
+
required `date` on a movement and `name`/`amount` on a group. The real API
|
|
25
|
+
sends none of those — it sends `month`, `moved_at`, and category endpoints.
|
|
26
|
+
All four money movement tools failed at validation on every call, while the
|
|
27
|
+
suite passed, because no test used a real payload and no test touched the
|
|
28
|
+
family at all.
|
|
29
|
+
|
|
30
|
+
Two properties made this invisible:
|
|
31
|
+
|
|
32
|
+
1. Hand-written fixtures agree with the model by construction.
|
|
33
|
+
2. The tool boundary returns failures as a structured error payload with
|
|
34
|
+
`isError: False`, so a caller that only checks the MCP result looks fine.
|
|
35
|
+
|
|
36
|
+
The write tools failed four more ways, each invisible to the same suite:
|
|
37
|
+
|
|
38
|
+
- `category-groups` in the path where the API wants `category_groups`, so YNAB
|
|
39
|
+
answered "Invalid URI" for create and update alike
|
|
40
|
+
- `categories_create` could not send `category_group_id`, which the API
|
|
41
|
+
requires, so no category could ever be created
|
|
42
|
+
- the bulk update model expected `data.bulk`, a shape this route does not
|
|
43
|
+
return, so the write succeeded and the response failed to parse
|
|
44
|
+
- the group create and update routes return a group without its `categories`,
|
|
45
|
+
which the response model required
|
|
46
|
+
|
|
47
|
+
None of these are visible from the request side. Three of the four failed
|
|
48
|
+
*after* YNAB had already accepted the write.
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
|
|
52
|
+
1. Never infer a response shape from a sibling resource. Fetch the endpoint and
|
|
53
|
+
read what it actually returns.
|
|
54
|
+
2. Record fixtures from a live response and replace the identifiers. Do not
|
|
55
|
+
write fixture payloads from the model definition.
|
|
56
|
+
3. Profile every record in the response before setting a field required, not
|
|
57
|
+
just the first one. A field that is non-null in record 1 and null in record
|
|
58
|
+
40 makes a required field a guaranteed failure.
|
|
59
|
+
4. A tool is not verified until it has been invoked against the live API. Green
|
|
60
|
+
unit tests are not evidence that a tool works.
|
|
61
|
+
5. When parsing fails, check whether the error is reported as a tool error or
|
|
62
|
+
hidden in a success envelope, and say which in the report.
|
|
63
|
+
6. Accepted is not applied. YNAB takes `budgeted` on the category update route
|
|
64
|
+
and ignores it, returning 200 and a `budgeted` of 0. After any write sweep,
|
|
65
|
+
read the plan back and confirm the values actually changed.
|
|
66
|
+
7. Check both directions of a route pair. A resource's create response is
|
|
67
|
+
frequently a different shape from its list response — usually thinner, as
|
|
68
|
+
with a category group returned without its categories.
|
|
69
|
+
|
|
70
|
+
## Workflow
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 1. See what the endpoint really returns, across all records.
|
|
74
|
+
curl -s -H "Authorization: Bearer $YNAB_API_KEY" \
|
|
75
|
+
"https://api.ynab.com/v1/budgets/$YNAB_PLAN_ID/<resource>" | python3 -c "
|
|
76
|
+
import json, sys, collections
|
|
77
|
+
data = json.load(sys.stdin)['data']
|
|
78
|
+
key = [k for k in data if isinstance(data[k], list)][0]
|
|
79
|
+
records = data[key]
|
|
80
|
+
types = collections.defaultdict(collections.Counter)
|
|
81
|
+
for record in records:
|
|
82
|
+
for field, value in record.items():
|
|
83
|
+
types[field][type(value).__name__] += 1
|
|
84
|
+
print(f'{len(records)} records')
|
|
85
|
+
for field, counts in types.items():
|
|
86
|
+
print(f' {field:28} {dict(counts)}')
|
|
87
|
+
"
|
|
88
|
+
|
|
89
|
+
# 2. Make the change, then verify.
|
|
90
|
+
make test
|
|
91
|
+
make verify-live # every read-only tool against the live API
|
|
92
|
+
make verify-write PLAN_ID=<uuid> # every write tool, against a disposable plan
|
|
93
|
+
make verify-mcp-http # the MCP handshake an agent performs
|
|
94
|
+
|
|
95
|
+
# 3. For writes, read the plan back and confirm the values changed.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
A field whose type counter shows `NoneType` for any record is optional.
|
|
99
|
+
|
|
100
|
+
Never point `verify-write` at a real budget. It takes an explicit plan id, never
|
|
101
|
+
falls back to `YNAB_PLAN_ID`, and refuses plans whose name does not look
|
|
102
|
+
disposable. Keep those guards if you extend it.
|
|
103
|
+
|
|
104
|
+
## Reporting
|
|
105
|
+
|
|
106
|
+
State what was actually run. "39 read tools invoked live, 0 failures" is a
|
|
107
|
+
verification claim; "tests pass" is not. If a tool was skipped because the plan
|
|
108
|
+
has no such record, say so rather than counting it as passing.
|
|
109
|
+
|
|
110
|
+
## Related Skills
|
|
111
|
+
|
|
112
|
+
- `contract-sync` — keeping generated artifacts aligned with the source of truth
|
|
113
|
+
- `docs-honesty` — keeping claims in docs matched to implementation
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: local-workflow-reproducibility
|
|
3
|
+
description: Turn repeated local setup, seed, and manual-test workflows into safe, documented, repeatable scripts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Local Workflow Reproducibility
|
|
7
|
+
|
|
8
|
+
Use this skill when local development or manual testing depends on repeated setup, seed, reset, fixture, or scenario-loading steps.
|
|
9
|
+
|
|
10
|
+
## Use When
|
|
11
|
+
|
|
12
|
+
- local setup is repetitive or error-prone
|
|
13
|
+
- realistic test state requires many manual steps
|
|
14
|
+
- developers are copying IDs, tokens, or env values between tools
|
|
15
|
+
- manual testing depends on exact ordering
|
|
16
|
+
- seed or reset flows need guardrails
|
|
17
|
+
|
|
18
|
+
## Read First
|
|
19
|
+
|
|
20
|
+
- `AGENTS.md` (if present)
|
|
21
|
+
- `README.md` and `pyproject.toml` (scripts, optional groups, entry points)
|
|
22
|
+
- `Makefile` or `scripts/` if present
|
|
23
|
+
- Environment docs (for example `docs/environment.md`, `.env.example`)
|
|
24
|
+
- Existing fixtures under `tests/`, `scripts/`, or `tools/`
|
|
25
|
+
|
|
26
|
+
## Core Rules
|
|
27
|
+
|
|
28
|
+
1. Repeated workflows should become scripts or documented commands, not tribal knowledge.
|
|
29
|
+
2. Destructive reset flows should be explicit and guarded (confirm DB name, env file, or `--dry-run` where appropriate).
|
|
30
|
+
3. Scenario data should be intentional and named.
|
|
31
|
+
4. Local workflows should prefer exercising real app code paths where practical (run the MCP server, call tools via inspector/CLI).
|
|
32
|
+
5. Docs should explain how to reset, seed, and test locally—including required env vars (for example YNAB API tokens) without committing secrets.
|
|
33
|
+
6. Use a virtual environment (`uv`, `venv`, `poetry`) consistently; document the canonical install and run commands.
|
|
34
|
+
|
|
35
|
+
## Workflow
|
|
36
|
+
|
|
37
|
+
1. Identify repeated manual setup pain.
|
|
38
|
+
2. Decide whether it needs reset, load, list, or verify commands.
|
|
39
|
+
3. Script the workflow with safety checks (Python CLI, `make` targets, or shell wrappers that call `python -m ...`).
|
|
40
|
+
4. Document the command surface and expected state.
|
|
41
|
+
5. Add or update `pytest` fixtures or seed data as the model evolves.
|
|
42
|
+
|
|
43
|
+
## Common Failure Modes
|
|
44
|
+
|
|
45
|
+
- manual setup requires many fragile steps
|
|
46
|
+
- resets can accidentally target the wrong environment
|
|
47
|
+
- scenarios drift from current schema or tool contracts
|
|
48
|
+
- docs list workflows that no longer work
|
|
49
|
+
- secrets committed or assumed in docs
|
|
50
|
+
- “works on my machine” without pinned deps in `pyproject.toml` / lockfile
|
|
51
|
+
|
|
52
|
+
## Completion Standard
|
|
53
|
+
|
|
54
|
+
The repeated local workflow is safe, repeatable, discoverable, and documented well enough that future humans and agents can use it without tribal knowledge.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: postman-standards
|
|
3
|
+
description: Keep Postman collections complete and aligned with API contracts when this repo documents HTTP testing with Postman or Newman.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Postman standards
|
|
7
|
+
|
|
8
|
+
**Scope:** Use this skill only if this repo maintains Postman/Newman collections or an HTTP API. Many MCP-only Python repos do not—skip this skill if there is no `postman/` or documented HTTP operator workflow.
|
|
9
|
+
|
|
10
|
+
Use when editing Postman surfaces or HTTP routes and you need collections to stay a high-quality operator and integration-testing surface.
|
|
11
|
+
|
|
12
|
+
## Use when
|
|
13
|
+
|
|
14
|
+
- This repo exposes HTTP endpoints (FastAPI, etc.) with Postman collections
|
|
15
|
+
- Changing request or response shapes or route behavior
|
|
16
|
+
- Updating Postman examples, naming, variables, or tests
|
|
17
|
+
- Adding or updating OpenAPI- or script-generated Postman artifacts
|
|
18
|
+
|
|
19
|
+
## Read first
|
|
20
|
+
|
|
21
|
+
- `AGENTS.md` (if present)
|
|
22
|
+
- `README.md` and `pyproject.toml` (generation scripts, if any)
|
|
23
|
+
- `.agents/skills/contract-sync/SKILL.md`
|
|
24
|
+
- OpenAPI or contract docs in this repo
|
|
25
|
+
|
|
26
|
+
## Core rules
|
|
27
|
+
|
|
28
|
+
1. **Source of truth**: contracts live in hand-authored Python (Pydantic models, route handlers, tests). OpenAPI and generated Postman collections are derived unless the repo documents otherwise.
|
|
29
|
+
- Do not hand-edit generated OpenAPI or collection JSON; regenerate using commands in `pyproject.toml`, `Makefile`, or repo docs.
|
|
30
|
+
2. **Variable contract (inputs equal outputs)**:
|
|
31
|
+
- Path params must use the OpenAPI parameter name as the Postman variable name.
|
|
32
|
+
- Post-scripts that capture ids must write to the same canonical keys the collection documents.
|
|
33
|
+
3. **Every request needs a description** with: `Purpose:`, `Auth:`, `Reads:`, `Writes:`, `Assumptions:`, `Side Effects:`, `Downstream:`, `Notes:`.
|
|
34
|
+
4. **Variables**: `{{baseUrl}}` in environment; collection variables for workflow ids; never hardcode tokens or production ids.
|
|
35
|
+
5. **Body examples**: happy path, minimal payload, and a common edge case where applicable.
|
|
36
|
+
6. **Post-script tests**: assert status and stable fields; avoid brittle full-body string matches on dynamic content.
|
|
37
|
+
|
|
38
|
+
## Postman runtime note
|
|
39
|
+
|
|
40
|
+
Postman and Newman run **JavaScript** in the sandbox, not Python from this repo. Shared logic belongs in repo templates injected at generation time—not imported Python modules.
|
|
41
|
+
|
|
42
|
+
Use `postmanDebug=true` on the collection or environment to gate verbose script logs.
|
|
43
|
+
|
|
44
|
+
## Completion standard
|
|
45
|
+
|
|
46
|
+
An operator can run the collection end to end for the implemented subset with minimal guessing: clear descriptions, runnable examples, and tests that capture ids for chained requests.
|