Skip to content

Commit a1040b4

Browse files
committed
v0.1.0 Foundation — Plaid Developer Tools
Scaffold complete Cursor plugin with 17 skills (6 production, 11 stubs), 7 rules (3 production, 4 stubs), 30 MCP tool stubs, CI workflows, comprehensive test suite (443 tests), and full repo documentation. Made-with: Cursor
1 parent fc62fd7 commit a1040b4

86 files changed

Lines changed: 4775 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cursor-plugin/plugin.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "plaid-developer-tools",
3+
"displayName": "Plaid Developer Tools",
4+
"version": "0.1.0",
5+
"description": "Plaid API integration for fintech developers using Cursor, Claude Code, and MCP-compatible editors. 17 skills covering Link setup, transaction sync, webhooks, sandbox testing, category mapping, error handling, API reference, institution search, account verification, investments, identity, recurring detection, migration, security, React integration, Next.js integration, and production readiness - plus 7 rules. Companion MCP server provides 30 tools for live Plaid sandbox interaction.",
6+
"author": {
7+
"name": "TMHSDigital",
8+
"url": "https://github.com/TMHSDigital"
9+
},
10+
"homepage": "https://github.com/TMHSDigital/Plaid-Developer-Tools",
11+
"repository": "https://github.com/TMHSDigital/Plaid-Developer-Tools",
12+
"license": "CC-BY-NC-ND-4.0",
13+
"keywords": [
14+
"plaid",
15+
"fintech",
16+
"banking",
17+
"transactions",
18+
"plaid-link",
19+
"webhooks",
20+
"sandbox",
21+
"open-banking",
22+
"payments",
23+
"account-verification",
24+
"investments",
25+
"identity",
26+
"mcp",
27+
"cursor-plugin"
28+
],
29+
"category": "developer-tools",
30+
"tags": [
31+
"plaid",
32+
"fintech",
33+
"api"
34+
],
35+
"logo": "assets/logo.png",
36+
"skills": "./skills/",
37+
"rules": "./rules/"
38+
}

.cursorrules

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Cursor Rules
2+
3+
## Formatting
4+
5+
- Never use em dashes (-). Use a regular dash (-) or rewrite the sentence instead.
6+
7+
## Skill File Conventions
8+
9+
- Every skill lives in `skills/<skill-name>/SKILL.md`
10+
- YAML frontmatter is required with `name` (matching the directory name) and `description` (one line, when-to-use guidance)
11+
- Required sections in order: Trigger, Required Inputs, Workflow, Key References (if applicable), Example Interaction, MCP Usage, Common Pitfalls, See Also
12+
- Keep `## MCP Usage` present even for non-MCP skills (state that no MCP tool exists yet)
13+
14+
## Rule File Conventions
15+
16+
- Rules use `.mdc` extension in the `rules/` directory
17+
- YAML frontmatter must include `description` and `alwaysApply` (boolean)
18+
- If `alwaysApply` is false, include `globs` to scope when the rule activates
19+
20+
## Plaid Conventions
21+
22+
- Plaid environments: `sandbox`, `development`, `production` (set via `PLAID_ENV`)
23+
- Access tokens follow the format `access-{env}-{uuid}` and are permanent credentials
24+
- Never hardcode `PLAID_CLIENT_ID`, `PLAID_SECRET`, or access tokens. Use environment variables or `.env` files.
25+
- Sandbox test user: `user_good` / `pass_good` (MFA code: `1234`)
26+
- Default sandbox institution: `ins_109508` (First Platypus Bank)
27+
- Plaid amounts: positive = debit (money out), negative = credit (money in)
28+
29+
## MCP Tool Signatures
30+
31+
When referencing MCP tools in documentation, use the canonical parameter names from the skill files:
32+
- `plaid_syncTransactions({ access_token, cursor?, count? })` not `{ token, offset }`
33+
- `plaid_createSandboxItem({ institution_id?, products?, webhook? })` not `{ inst, prods }`
34+
- `plaid_searchInstitutions({ query, country_codes?, products? })` not `{ name, countries }`
35+
- `plaid_fireSandboxWebhook({ access_token, webhook_code, webhook_type? })` not `{ token, code }`
36+
37+
## MCP Tool Naming
38+
39+
- All MCP tool names use `plaid_camelCase` prefix (e.g. `plaid_syncTransactions`, `plaid_getBalance`)
40+
- Each tool lives in its own file under `mcp-server/src/tools/`
41+
- Each tool file exports `register(server: McpServer): void`
42+
- Use `.js` extension on all imports (ESM)
43+
44+
## Release Checklist
45+
46+
When preparing a release:
47+
1. Update version in `.cursor-plugin/plugin.json`
48+
2. Update version in `mcp-server/package.json`
49+
3. Update `CHANGELOG.md` with new entry
50+
4. Update `ROADMAP.md` current version marker
51+
5. Update `CLAUDE.md` version reference
52+
6. Verify counts in `plugin.json` description match disk
53+
7. Run `pytest tests/ -v` to verify all tests pass
54+
8. Build MCP server: `cd mcp-server && npm run build`

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Plaid API credentials (free sandbox signup at https://dashboard.plaid.com/signup)
2+
# PLAID_CLIENT_ID=your_client_id_here
3+
# PLAID_SECRET=your_sandbox_secret_here
4+
# PLAID_ENV=sandbox

.github/workflows/ci.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test-plugin:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Python
16+
uses: actions/setup-python@v5
17+
with:
18+
python-version: '3.12'
19+
20+
- name: Install test dependencies
21+
run: pip install -r requirements-test.txt
22+
23+
- name: Run test suite
24+
run: pytest tests/ -v --tb=short
25+
26+
build-mcp:
27+
runs-on: ubuntu-latest
28+
defaults:
29+
run:
30+
working-directory: mcp-server
31+
strategy:
32+
matrix:
33+
node-version: [20, 22]
34+
steps:
35+
- uses: actions/checkout@v4
36+
37+
- name: Set up Node.js ${{ matrix.node-version }}
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: ${{ matrix.node-version }}
41+
42+
- name: Install dependencies
43+
run: npm ci
44+
45+
- name: Build
46+
run: npm run build
47+
48+
- name: Test
49+
run: npm test

.github/workflows/codeql.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: CodeQL
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
schedule:
9+
- cron: '0 6 * * 1'
10+
11+
jobs:
12+
analyze:
13+
name: Analyze
14+
runs-on: ubuntu-latest
15+
permissions:
16+
security-events: write
17+
actions: read
18+
contents: read
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
language: [python, javascript-typescript]
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- name: Initialize CodeQL
27+
uses: github/codeql-action/init@v3
28+
with:
29+
languages: ${{ matrix.language }}
30+
31+
- name: Autobuild
32+
uses: github/codeql-action/autobuild@v3
33+
34+
- name: Perform CodeQL Analysis
35+
uses: github/codeql-action/analyze@v3
36+
with:
37+
category: '/language:${{ matrix.language }}'

.github/workflows/validate.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Validate Plugin Structure
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
validate:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Validate plugin.json
16+
run: |
17+
echo "Checking plugin.json is valid JSON..."
18+
python3 -c "import json; json.load(open('.cursor-plugin/plugin.json'))"
19+
echo "plugin.json is valid."
20+
21+
- name: Check referenced paths exist
22+
run: |
23+
echo "Checking referenced paths..."
24+
test -d skills || { echo "ERROR: skills/ directory missing"; exit 1; }
25+
test -d rules || { echo "ERROR: rules/ directory missing"; exit 1; }
26+
test -f assets/logo.png || { echo "ERROR: assets/logo.png missing"; exit 1; }
27+
echo "All referenced paths exist."
28+
29+
- name: Validate skill frontmatter
30+
run: |
31+
echo "Checking skill YAML frontmatter..."
32+
errors=0
33+
for skill in skills/*/SKILL.md; do
34+
name=$(echo "$skill" | sed 's|skills/\(.*\)/SKILL.md|\1|')
35+
if ! head -1 "$skill" | grep -q "^---$"; then
36+
echo "ERROR: $skill missing YAML frontmatter opening ---"
37+
errors=$((errors + 1))
38+
continue
39+
fi
40+
frontmatter=$(sed -n '/^---$/,/^---$/p' "$skill" | sed '1d;$d')
41+
if ! echo "$frontmatter" | grep -q "^name:"; then
42+
echo "ERROR: $skill missing 'name' in frontmatter"
43+
errors=$((errors + 1))
44+
fi
45+
if ! echo "$frontmatter" | grep -q "^description:"; then
46+
echo "ERROR: $skill missing 'description' in frontmatter"
47+
errors=$((errors + 1))
48+
fi
49+
done
50+
if [ $errors -gt 0 ]; then
51+
echo "$errors frontmatter error(s) found."
52+
exit 1
53+
fi
54+
echo "All skill frontmatter valid."
55+
56+
- name: Check skill name matches directory
57+
run: |
58+
echo "Checking skill names match directory names..."
59+
errors=0
60+
for skill in skills/*/SKILL.md; do
61+
dir_name=$(echo "$skill" | sed 's|skills/\(.*\)/SKILL.md|\1|')
62+
fm_name=$(sed -n '/^---$/,/^---$/p' "$skill" | sed '1d;$d' | grep "^name:" | sed 's/^name: *//')
63+
if [ "$dir_name" != "$fm_name" ]; then
64+
echo "ERROR: $skill has name '$fm_name' but directory is '$dir_name'"
65+
errors=$((errors + 1))
66+
fi
67+
done
68+
if [ $errors -gt 0 ]; then
69+
echo "$errors name mismatch(es) found."
70+
exit 1
71+
fi
72+
echo "All skill names match their directories."
73+
74+
- name: Validate rule frontmatter
75+
run: |
76+
echo "Checking rule YAML frontmatter..."
77+
errors=0
78+
for rule in rules/*.mdc; do
79+
if ! head -1 "$rule" | grep -q "^---$"; then
80+
echo "ERROR: $rule missing YAML frontmatter opening ---"
81+
errors=$((errors + 1))
82+
continue
83+
fi
84+
frontmatter=$(sed -n '/^---$/,/^---$/p' "$rule" | sed '1d;$d')
85+
if ! echo "$frontmatter" | grep -q "^description:"; then
86+
echo "ERROR: $rule missing 'description' in frontmatter"
87+
errors=$((errors + 1))
88+
fi
89+
if ! echo "$frontmatter" | grep -q "^alwaysApply:"; then
90+
echo "ERROR: $rule missing 'alwaysApply' in frontmatter"
91+
errors=$((errors + 1))
92+
fi
93+
done
94+
if [ $errors -gt 0 ]; then
95+
echo "$errors frontmatter error(s) found."
96+
exit 1
97+
fi
98+
echo "All rule frontmatter valid."
99+
100+
- name: Count components
101+
run: |
102+
skill_count=$(ls -d skills/*/SKILL.md 2>/dev/null | wc -l)
103+
rule_count=$(ls rules/*.mdc 2>/dev/null | wc -l)
104+
echo "Skills: $skill_count"
105+
echo "Rules: $rule_count"

.gitignore

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Environment and secrets
2+
.env
3+
.env.*
4+
!.env.example
5+
6+
# Node
7+
node_modules/
8+
9+
# OS files
10+
.DS_Store
11+
Thumbs.db
12+
Desktop.ini
13+
ehthumbs.db
14+
15+
# IDE (allow .cursor-plugin/)
16+
.vscode/
17+
.claude/
18+
*.swp
19+
*.swo
20+
*~
21+
22+
# Build artifacts
23+
dist/
24+
build/
25+
*.log
26+
27+
# Python
28+
__pycache__/
29+
*.pyc
30+
.pytest_cache/

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [0.1.0] - 2026-04-01
6+
7+
### Added
8+
9+
- Plugin scaffold with `.cursor-plugin/plugin.json`
10+
- 6 production skills: `plaid-link-setup`, `plaid-transaction-sync`, `plaid-webhook-handling`, `plaid-sandbox-testing`, `plaid-category-mapping`, `plaid-error-handling`
11+
- 11 stub skills for future versions
12+
- 3 production rules: `plaid-secrets`, `plaid-error-handling`, `plaid-env-safety`
13+
- 4 stub rules for future versions
14+
- MCP server scaffold with 30 tool stubs (`@tmhs/plaid-mcp`)
15+
- GitHub Actions: CI, Validate, CodeQL workflows
16+
- Full test suite: skills, rules, plugin manifest, docs consistency, internal links, roadmap
17+
- Documentation: README, CLAUDE.md, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, ROADMAP
18+
- CC-BY-NC-ND-4.0 license

0 commit comments

Comments
 (0)