Skip to content

Commit f423220

Browse files
committed
feat: initial release - Google AdSense MCP Server v0.1.0
- 11 MCP tools for AdSense data access - OAuth and service account authentication - SQLite caching with TTL-based invalidation - Rate limiting with exponential backoff - Read-only scope for safety - CLI commands: init, doctor, run - Multi-account support
0 parents  commit f423220

34 files changed

Lines changed: 7206 additions & 0 deletions

.github/copilot-instructions.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# AdSense-MCP Copilot Instructions
2+
3+
## Project Overview
4+
This is a **Model Context Protocol (MCP) server** that provides Google AdSense API access to AI clients (Claude, Cursor, VS Code Copilot). It's distributed as a CLI tool via npm (`adsense-mcp`) with OAuth/service account authentication.
5+
6+
## Architecture
7+
8+
```
9+
src/
10+
├── index.ts # Public exports for programmatic use
11+
├── types.ts # TypeScript types (single source of truth)
12+
├── cli/ # Commander-based CLI (`adsense-mcp init|doctor|run`)
13+
├── server/ # MCP server implementation
14+
│ ├── index.ts # Server factory with stdio transport
15+
│ ├── tools/ # MCP tools organized by domain
16+
│ └── resources/ # MCP resources
17+
├── adsense/
18+
│ ├── client.ts # AdSense API wrapper with all operations
19+
│ ├── rateLimiter.ts # Rate limiting with exponential backoff
20+
│ └── cache.ts # SQLite cache with TTL
21+
└── auth/ # OAuth2 + service account auth, token storage
22+
```
23+
24+
**Key data flows:**
25+
1. CLI commands → `createServer()` → MCP stdio transport
26+
2. Tool calls → `handleToolCall()` routes to domain handlers → `AdSenseClient` → Google API
27+
3. Tokens stored via `keytar` (OS keychain) with file fallback; config in `env-paths` directories
28+
29+
## Development Commands
30+
31+
```bash
32+
npm run build # tsup build (ESM, Node 18+)
33+
npm run dev # Watch mode
34+
npm run typecheck # tsc --noEmit
35+
npm run lint # eslint src/
36+
adsense-mcp doctor # Check auth and API access
37+
```
38+
39+
## Code Conventions
40+
41+
### Adding New MCP Tools
42+
1. Create tool definition in `src/server/tools/<domain>.ts` following the pattern:
43+
- Export handler function like `handle<Action>(args)`
44+
2. Register in `src/server/tools/index.ts`:
45+
- Add tool schema to `registerTools()` array
46+
- Add case to `handleToolCall()` switch
47+
3. Tool names use underscore notation: `adsense_earnings_summary`, `adsense_list_sites`
48+
49+
### Type Definitions
50+
- Define types in `src/types.ts`
51+
- Tool input schemas use plain JSON Schema format for MCP
52+
53+
### Error Handling Pattern
54+
```typescript
55+
try {
56+
const result = await client.someOperation();
57+
return { data: result };
58+
} catch (error: any) {
59+
return { error: error.message };
60+
}
61+
```
62+
63+
### Rate Limiting
64+
- AdSense API: 100 requests/minute/user
65+
- Use `rateLimiter.throttle()` before API calls
66+
- Use `withRetry()` wrapper for automatic exponential backoff
67+
68+
### Caching Strategy
69+
- Today's data: 5 minutes TTL (frequently changing)
70+
- Yesterday's data: 1 hour TTL
71+
- Historical data (>2 days): 24 hours TTL
72+
- Account/site info: 1 hour TTL
73+
74+
## Security Notes
75+
- **Read-only scope only** (`adsense.readonly`) - no write operations
76+
- Never log or expose tokens
77+
- Credentials stored in OS keychain, never in repo

.github/workflows/ci.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
node-version: [18, 20, 22]
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js ${{ matrix.node-version }}
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: ${{ matrix.node-version }}
24+
25+
- name: Install dependencies
26+
run: npm ci
27+
28+
- name: Run typecheck
29+
run: npm run typecheck
30+
31+
- name: Run lint
32+
run: npm run lint
33+
continue-on-error: true
34+
35+
- name: Build
36+
run: npm run build
37+
38+
- name: Test CLI
39+
run: node dist/cli/index.js --help

.github/workflows/publish.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Publish to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
publish:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
id-token: write
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: "20"
21+
registry-url: "https://registry.npmjs.org"
22+
23+
- name: Install dependencies
24+
run: npm ci
25+
26+
- name: Run typecheck
27+
run: npm run typecheck
28+
29+
- name: Build
30+
run: npm run build
31+
32+
- name: Publish to npm
33+
run: npm publish --provenance --access public
34+
env:
35+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build output
5+
dist/
6+
7+
# IDE
8+
.idea/
9+
.vscode/
10+
*.swp
11+
*.swo
12+
13+
# OS files
14+
.DS_Store
15+
Thumbs.db
16+
17+
# Environment
18+
.env
19+
.env.local
20+
.env.*.local
21+
22+
# Logs
23+
logs/
24+
*.log
25+
npm-debug.log*
26+
27+
# Test
28+
coverage/
29+
.nyc_output/
30+
31+
# Cache
32+
*.db
33+
*.sqlite
34+
35+
# Credentials (never commit!)
36+
credentials.json
37+
service-account.json
38+
tokens.json

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.1.0] - 2026-01-20
9+
10+
### Added
11+
- Initial release
12+
- **Earnings**: Real-time earnings summary (today, yesterday, 7 days, month)
13+
- **Reports**: Custom reports with dimensions and metrics
14+
- **Period Comparison**: Compare performance between two time periods
15+
- **Sites**: List sites with approval status (READY, GETTING_READY, etc.)
16+
- **Alerts**: Account alerts and warnings by severity
17+
- **Policy Issues**: Policy violations affecting monetization
18+
- **Payments**: Payment history and pending earnings
19+
- **Ad Units**: List all ad units across ad clients
20+
- **Ad Code**: Get HTML embed code for ad units
21+
- **Export**: CSV export for reports
22+
- **Caching**: SQLite cache with TTL-based invalidation
23+
- **Rate Limiting**: Exponential backoff with 100 req/min limit
24+
- **Authentication**: OAuth2 and service account support
25+
- **Secure Storage**: Tokens stored in OS keychain via keytar
26+
27+
### Tools (11 total)
28+
- `adsense_list_accounts` - List all AdSense accounts
29+
- `adsense_earnings_summary` - Quick earnings overview
30+
- `adsense_generate_report` - Custom performance reports
31+
- `adsense_compare_periods` - Compare two time periods
32+
- `adsense_list_sites` - Sites with approval status
33+
- `adsense_list_alerts` - Account alerts (INFO/WARNING/SEVERE)
34+
- `adsense_list_policy_issues` - Policy violations
35+
- `adsense_list_payments` - Payment history
36+
- `adsense_list_ad_units` - All ad units
37+
- `adsense_get_ad_code` - Get ad unit embed code
38+
- `adsense_export_csv` - Export report as CSV
39+
40+
### Security
41+
- Read-only scope (`adsense.readonly`) by design for safety
42+
- No write operations to prevent accidental changes

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024-present SuperZero11
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)