@semanticintent/semantic-chirp-intelligence-mcp 3.0.0
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.
- package/.env.example +8 -0
- package/LICENSE +21 -0
- package/README.md +250 -0
- package/authenticate.js +207 -0
- package/build/analyses/BreakoutAnalysis.js +386 -0
- package/build/analyses/GamesInHandAnalysis.js +257 -0
- package/build/analyses/IceAnalysis.js +316 -0
- package/build/analyses/LineupAnalysis.js +284 -0
- package/build/analyses/StreamingAnalysis.js +246 -0
- package/build/analyses/WeekendStreamAnalysis.js +599 -0
- package/build/config/chirp-styles.js +36 -0
- package/build/config/personality-modes.js +36 -0
- package/build/config/tool-metadata.js +113 -0
- package/build/domain/governance.js +322 -0
- package/build/domain/types.js +14 -0
- package/build/experimental/semantic-breakout-tool.js +188 -0
- package/build/experimental/semantic-intent-parser.js +222 -0
- package/build/experimental/semantic-tool-integration.js +146 -0
- package/build/experimental/test-parser.js +61 -0
- package/build/index.js +1549 -0
- package/build/services/ChirpIntelligence.js +213 -0
- package/build/services/YahooApiClient.js +309 -0
- package/build/template/AnalysisTemplate.js +167 -0
- package/build/types.js +2 -0
- package/package.json +50 -0
package/.env.example
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Get these from https://developer.yahoo.com/apps/create/
|
|
2
|
+
YAHOO_CLIENT_ID=your_client_id_here
|
|
3
|
+
YAHOO_CLIENT_SECRET=your_client_secret_here
|
|
4
|
+
|
|
5
|
+
# Your league and team IDs, from your team URL:
|
|
6
|
+
# https://hockey.fantasysports.yahoo.com/hockey/{LEAGUE_ID}/{TEAM_ID}
|
|
7
|
+
YAHOO_LEAGUE_ID=your_league_id_here
|
|
8
|
+
YAHOO_TEAM_ID=your_team_id_here
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 semanticintent
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# š Semantic CHIRP Intelligence MCP
|
|
2
|
+
|
|
3
|
+
> **Fantasy hockey intelligence that chirps you into championships.**
|
|
4
|
+
> A Model Context Protocol (MCP) server that turns your Yahoo Fantasy Hockey league into an AI advisor ā not just a data pipe, but a **Semantic Intent** brain that reads the ice and tells you the cold truth.
|
|
5
|
+
|
|
6
|
+
[](https://chirp.semanticintent.dev)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
š **Full documentation:** [chirp.semanticintent.dev](https://chirp.semanticintent.dev)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## What this is
|
|
17
|
+
|
|
18
|
+
Most fantasy MCP servers stop at "fetch my roster." This one is a **semantic intelligence layer**: every tool carries intent metadata, analyses run through a shared template, and results come back with a *point of view* ā schedule edges, streaming opportunities, and savage roster truths.
|
|
19
|
+
|
|
20
|
+
It's built on the same **Semantic Intent** philosophy as its sibling project, the temporal-intelligence brain [`@semanticintent/semantic-wake-intelligence-mcp`](https://github.com/semanticintent/semantic-wake-intelligence-mcp) ā here applied to the domain of fantasy hockey.
|
|
21
|
+
|
|
22
|
+
### Highlights
|
|
23
|
+
|
|
24
|
+
- āļø **ICE ā the Intent Chirp Engine** ā championship-level roster analysis with brutal honesty
|
|
25
|
+
- šļø **Schedule intelligence** ā games-in-hand edges and streaming windows (NHL public API for real schedules)
|
|
26
|
+
- š **Weekend stream classifier** ā tells desperation pickups apart from genuine multi-week opportunities
|
|
27
|
+
- šļø **Semantic Anchoring Governance** ā every tool declares its intent; a dashboard surfaces the health metrics
|
|
28
|
+
- š§© **Template Pattern architecture** ā analyses are composable, consistent, and testable
|
|
29
|
+
- š **Read-only & local** ā OAuth 2.0, minimum permissions, no third-party data egress
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
37
|
+
ā MCP Server (src/index.ts) ā stdio transport for Claude ā
|
|
38
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
|
|
39
|
+
ā Semantic config (src/config/) ā
|
|
40
|
+
ā ⢠tool-metadata.ts ā intent, discovery tags, chirp style ā
|
|
41
|
+
ā ⢠personality-modes.ts / chirp-styles.ts ā the voice ā
|
|
42
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
|
|
43
|
+
ā Intelligence layer (src/analyses/ + src/template/) ā
|
|
44
|
+
ā ⢠AnalysisTemplate ā shared Template Pattern base ā
|
|
45
|
+
ā ⢠Ice / Streaming / GamesInHand / WeekendStream / Lineup ā
|
|
46
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
|
|
47
|
+
ā Services (src/services/) ā
|
|
48
|
+
ā ⢠ChirpIntelligence ā turns data into chirp ā
|
|
49
|
+
ā ⢠YahooApiClient ā all Yahoo Fantasy API access ā
|
|
50
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
|
|
51
|
+
ā Domain (src/domain/) ā types + governance ā
|
|
52
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- **Semantic Anchoring Governance** ā every tool registers intent metadata (intent category, hockey context, discovery tags, chirp potential). See [`SEMANTIC_ANCHORING_GOVERNANCE.md`](./SEMANTIC_ANCHORING_GOVERNANCE.md). The `governance_dashboard` tool reports live health.
|
|
56
|
+
- **Template Pattern** ā analyses extend `AnalysisTemplate`, so each one produces output the same disciplined way. Adding an analysis is adding one class.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Available Tools
|
|
61
|
+
|
|
62
|
+
### Core data tools (read-only Yahoo Fantasy)
|
|
63
|
+
|
|
64
|
+
| Tool | Description |
|
|
65
|
+
|------|-------------|
|
|
66
|
+
| `get_team_roster` | Your current roster with players, positions, and status |
|
|
67
|
+
| `get_league_standings` | League standings ā all teams and their records |
|
|
68
|
+
| `get_current_matchup` | Your current week's matchup and status |
|
|
69
|
+
| `search_players` | Search free agents by position (C, LW, RW, D, G) |
|
|
70
|
+
| `get_player_stats` | Detailed stats for a player by ID |
|
|
71
|
+
| `get_weekly_stats` | Your week's stats vs. your opponent |
|
|
72
|
+
| `compare_matchup` | Category-by-category breakdown of your matchup |
|
|
73
|
+
| `optimize_lineup` | Lineup recommendations based on health and positions |
|
|
74
|
+
| `get_trending_players` | Most-added / most-owned players ā hot pickups |
|
|
75
|
+
| `debug_api_call` | Inspect raw Yahoo API responses for troubleshooting |
|
|
76
|
+
|
|
77
|
+
### CHIRP intelligence tools (Template Pattern + semantic analysis)
|
|
78
|
+
|
|
79
|
+
| Tool | Description |
|
|
80
|
+
|------|-------------|
|
|
81
|
+
| `ice` | āļø **Intent Chirp Engine** ā the flagship multi-mode advisor; ice-cold, championship-level analysis combining all insights |
|
|
82
|
+
| `get_roster_transaction_recommendations` | š ICE roster optimization ā savage, brutally honest lineup/transaction calls |
|
|
83
|
+
| `get_streaming_recommendations` | Schedule- and trend-aware waiver/streaming picks (weekly / weekend / daily strategies) |
|
|
84
|
+
| `get_games_in_hand` | Schedule-advantage analysis ā remaining games, you vs. opponent |
|
|
85
|
+
| `analyze_weekend_streams` | š Weekend stream classifier ā desperation filler vs. genuine multi-week upside (0ā100 upside score) |
|
|
86
|
+
| `governance_dashboard` | šļø Semantic Anchoring Governance health, analysis metrics, and violations |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Prerequisites
|
|
91
|
+
|
|
92
|
+
- **Node.js 20+**
|
|
93
|
+
- A **Yahoo account** with a Fantasy Hockey team
|
|
94
|
+
- An MCP client ā e.g. **Claude Desktop**
|
|
95
|
+
|
|
96
|
+
## Setup
|
|
97
|
+
|
|
98
|
+
### 1. Create a Yahoo app
|
|
99
|
+
|
|
100
|
+
Go to [developer.yahoo.com/apps/create](https://developer.yahoo.com/apps/create/) and create an app:
|
|
101
|
+
|
|
102
|
+
- **OAuth Client Type:** `Confidential Client`
|
|
103
|
+
- **Redirect URI:** `https://localhost:3000/callback` *(must match exactly)*
|
|
104
|
+
- **API Permissions:** `Fantasy Sports ā Read`
|
|
105
|
+
|
|
106
|
+
Copy your **Client ID** and **Client Secret**.
|
|
107
|
+
|
|
108
|
+
> š Treat the Client Secret like a password. Never commit it. If it ever leaks, **rotate it** by creating a new app and deleting the old one ā see [SECURITY.md](./SECURITY.md).
|
|
109
|
+
|
|
110
|
+
### 2. Find your league and team IDs
|
|
111
|
+
|
|
112
|
+
From your team URL `https://hockey.fantasysports.yahoo.com/hockey/{LEAGUE_ID}/{TEAM_ID}` ā the two numbers are your league and team IDs.
|
|
113
|
+
|
|
114
|
+
### 3. Install & configure
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
git clone https://github.com/semanticintent/semantic-chirp-intelligence-mcp.git
|
|
118
|
+
cd semantic-chirp-intelligence-mcp
|
|
119
|
+
npm install
|
|
120
|
+
cp .env.example .env # then fill in your credentials
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`.env`:
|
|
124
|
+
```
|
|
125
|
+
YAHOO_CLIENT_ID=your_client_id
|
|
126
|
+
YAHOO_CLIENT_SECRET=your_client_secret
|
|
127
|
+
YAHOO_LEAGUE_ID=your_league_id
|
|
128
|
+
YAHOO_TEAM_ID=your_team_id
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 4. Build
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm run build
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 5. Authenticate with Yahoo (one time)
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
node authenticate.js
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Open the printed URL, click through the self-signed-certificate warning (it's a local callback), sign in, and authorize. The token is saved to `.yahoo-oauth.json` (git-ignored). The server auto-refreshes it after that.
|
|
144
|
+
|
|
145
|
+
### 6. Add to Claude Desktop
|
|
146
|
+
|
|
147
|
+
Edit your Claude Desktop config:
|
|
148
|
+
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
149
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"mcpServers": {
|
|
154
|
+
"semantic-chirp-intelligence-mcp": {
|
|
155
|
+
"command": "node",
|
|
156
|
+
"args": ["/absolute/path/to/semantic-chirp-intelligence-mcp/build/index.js"],
|
|
157
|
+
"env": {
|
|
158
|
+
"YAHOO_CLIENT_ID": "your_client_id",
|
|
159
|
+
"YAHOO_CLIENT_SECRET": "your_client_secret",
|
|
160
|
+
"YAHOO_LEAGUE_ID": "your_league_id",
|
|
161
|
+
"YAHOO_TEAM_ID": "your_team_id",
|
|
162
|
+
"DOTENV_CONFIG_QUIET": "true"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Use an **absolute path** to `build/index.js` (forward slashes, even on Windows). Restart Claude Desktop ā the CHIRP tools will appear.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Usage
|
|
174
|
+
|
|
175
|
+
Once connected, just talk to Claude about your team:
|
|
176
|
+
|
|
177
|
+
- *"Run ICE on my roster ā what should I actually do this week?"*
|
|
178
|
+
- *"Where do I have a games-in-hand edge over my opponent?"*
|
|
179
|
+
- *"Find me streaming goalies for the weekend ā real value, not desperation pickups."*
|
|
180
|
+
- *"Am I winning my matchup? Which categories am I losing?"*
|
|
181
|
+
- *"Who are the hottest waiver adds in my league?"*
|
|
182
|
+
- *"Show me the governance dashboard."*
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Development
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
npm run build # compile TypeScript -> build/
|
|
190
|
+
npm run type-check # tsc --noEmit
|
|
191
|
+
npm test # run the vitest suite once
|
|
192
|
+
npm run test:watch # watch mode
|
|
193
|
+
npm run test:coverage
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Project structure
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
semantic-chirp-intelligence-mcp/
|
|
200
|
+
āāā src/
|
|
201
|
+
ā āāā index.ts # MCP server (stdio) + tool registration
|
|
202
|
+
ā āāā analyses/ # Template-Pattern analyses (Ice, Streaming, GamesInHand, WeekendStream, Lineup, Breakout)
|
|
203
|
+
ā āāā template/ # AnalysisTemplate base
|
|
204
|
+
ā āāā services/ # ChirpIntelligence, YahooApiClient
|
|
205
|
+
ā āāā config/ # tool-metadata, personality-modes, chirp-styles
|
|
206
|
+
ā āāā domain/ # types, governance
|
|
207
|
+
ā āāā experimental/ # semantic-intent parser experiments
|
|
208
|
+
āāā tests/ # vitest tests
|
|
209
|
+
āāā authenticate.js # one-time Yahoo OAuth helper
|
|
210
|
+
āāā docs/ # documentation (architecture, setup, dev notes)
|
|
211
|
+
āāā .env.example
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Security
|
|
217
|
+
|
|
218
|
+
- **Read-only** integration ā requests the minimum Yahoo `Read` permission; never modifies your roster or transactions.
|
|
219
|
+
- **Local-only** ā runs over stdio; the only network calls are to Yahoo's API (and the NHL public schedule API).
|
|
220
|
+
- **Secrets never committed** ā `.env` and `.yahoo-oauth.json` are git-ignored. See [SECURITY.md](./SECURITY.md) for the full policy and how to rotate a leaked credential.
|
|
221
|
+
|
|
222
|
+
## Part of Cormorant Foraging
|
|
223
|
+
|
|
224
|
+
ChirpIQX is the **Sound** (communication) dimension of [Cormorant Foraging](https://cormorantforaging.dev) ā a family of Semantic Intent intelligence systems, each mapping a different dimension:
|
|
225
|
+
|
|
226
|
+
| System | Dimension | Domain |
|
|
227
|
+
|--------|-----------|--------|
|
|
228
|
+
| **ChirpIQX** *(this repo)* | Sound | Fantasy hockey intelligence |
|
|
229
|
+
| **WakeIQX** | Time | [AI context temporal intelligence](https://github.com/semanticintent/semantic-wake-intelligence-mcp) |
|
|
230
|
+
| **PerchIQX** | Space | Database schema intelligence |
|
|
231
|
+
|
|
232
|
+
š Learn more at [chirp.semanticintent.dev](https://chirp.semanticintent.dev) Ā· [cormorantforaging.dev](https://cormorantforaging.dev)
|
|
233
|
+
|
|
234
|
+
## Contributing
|
|
235
|
+
|
|
236
|
+
Contributions welcome ā see [CONTRIBUTING.md](./CONTRIBUTING.md) and the [Code of Conduct](./CODE_OF_CONDUCT.md). New analyses should extend `AnalysisTemplate` and declare intent metadata in `tool-metadata.ts`.
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
[MIT](./LICENSE) Ā© semanticintent
|
|
241
|
+
|
|
242
|
+
## Acknowledgments
|
|
243
|
+
|
|
244
|
+
- [Model Context Protocol](https://modelcontextprotocol.io) by Anthropic
|
|
245
|
+
- [Yahoo Fantasy Sports API](https://developer.yahoo.com/fantasysports/)
|
|
246
|
+
- Sibling project: [`semantic-wake-intelligence-mcp`](https://github.com/semanticintent/semantic-wake-intelligence-mcp)
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
**š Now go win your league. ICE doesn't lie.**
|
package/authenticate.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// OAuth Helper Script for Yahoo Fantasy
|
|
2
|
+
// Run this ONCE to get your access token
|
|
3
|
+
// Usage: node authenticate.js
|
|
4
|
+
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as dotenv from 'dotenv';
|
|
7
|
+
import * as https from 'https';
|
|
8
|
+
import * as url from 'url';
|
|
9
|
+
import selfsigned from 'selfsigned';
|
|
10
|
+
|
|
11
|
+
dotenv.config();
|
|
12
|
+
|
|
13
|
+
const CLIENT_ID = process.env.YAHOO_CLIENT_ID;
|
|
14
|
+
const CLIENT_SECRET = process.env.YAHOO_CLIENT_SECRET;
|
|
15
|
+
const REDIRECT_URI = 'https://localhost:3000/callback';
|
|
16
|
+
const TOKEN_FILE = '.yahoo-oauth.json';
|
|
17
|
+
|
|
18
|
+
if (!CLIENT_ID || !CLIENT_SECRET) {
|
|
19
|
+
console.error('ā Missing YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET in .env');
|
|
20
|
+
console.error('š Please create a .env file with your Yahoo API credentials');
|
|
21
|
+
console.error(' Get them from: https://developer.yahoo.com/apps/create/');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Generate self-signed certificate for local HTTPS
|
|
26
|
+
console.log('š Generating self-signed certificate for HTTPS...');
|
|
27
|
+
const attrs = [{ name: 'commonName', value: 'localhost' }];
|
|
28
|
+
const pems = selfsigned.generate(attrs, {
|
|
29
|
+
keySize: 2048,
|
|
30
|
+
days: 365,
|
|
31
|
+
algorithm: 'sha256',
|
|
32
|
+
extensions: [
|
|
33
|
+
{
|
|
34
|
+
name: 'subjectAltName',
|
|
35
|
+
altNames: [
|
|
36
|
+
{ type: 2, value: 'localhost' },
|
|
37
|
+
{ type: 7, ip: '127.0.0.1' }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log('š Starting Yahoo OAuth flow...\n');
|
|
44
|
+
|
|
45
|
+
// HTTPS server options with self-signed certificate
|
|
46
|
+
const serverOptions = {
|
|
47
|
+
key: pems.private,
|
|
48
|
+
cert: pems.cert,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Create an HTTPS server to handle the callback
|
|
52
|
+
const server = https.createServer(serverOptions, async (req, res) => {
|
|
53
|
+
const parsedUrl = url.parse(req.url, true);
|
|
54
|
+
|
|
55
|
+
if (parsedUrl.pathname === '/') {
|
|
56
|
+
// Build Yahoo OAuth authorization URL
|
|
57
|
+
const authUrl = `https://api.login.yahoo.com/oauth2/request_auth?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&response_type=code&language=en-us`;
|
|
58
|
+
|
|
59
|
+
res.writeHead(302, { 'Location': authUrl });
|
|
60
|
+
res.end();
|
|
61
|
+
console.log('š Redirecting to Yahoo for authorization...');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (parsedUrl.pathname === '/callback') {
|
|
66
|
+
const authCode = parsedUrl.query.code;
|
|
67
|
+
|
|
68
|
+
if (!authCode) {
|
|
69
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
70
|
+
res.end('<h1>ā Error: No authorization code received</h1>');
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
server.close();
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}, 1000);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
console.log('š Exchanging authorization code for access token...');
|
|
80
|
+
|
|
81
|
+
// Exchange the code for a token
|
|
82
|
+
const tokenResponse = await fetch('https://api.login.yahoo.com/oauth2/get_token', {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
headers: {
|
|
85
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
86
|
+
'Authorization': 'Basic ' + Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')
|
|
87
|
+
},
|
|
88
|
+
body: new URLSearchParams({
|
|
89
|
+
grant_type: 'authorization_code',
|
|
90
|
+
redirect_uri: REDIRECT_URI,
|
|
91
|
+
code: authCode
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!tokenResponse.ok) {
|
|
96
|
+
throw new Error(`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const token = await tokenResponse.json();
|
|
100
|
+
console.log('š Token retrieved successfully');
|
|
101
|
+
|
|
102
|
+
// Save the token with timestamp
|
|
103
|
+
const tokenWithTimestamp = {
|
|
104
|
+
access_token: token.access_token,
|
|
105
|
+
refresh_token: token.refresh_token,
|
|
106
|
+
expires_in: token.expires_in,
|
|
107
|
+
token_type: token.token_type,
|
|
108
|
+
xoauth_yahoo_guid: token.xoauth_yahoo_guid,
|
|
109
|
+
timestamp: Date.now(),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
fs.writeFileSync(TOKEN_FILE, JSON.stringify(tokenWithTimestamp, null, 2));
|
|
113
|
+
console.log(`ā
Token saved to ${TOKEN_FILE}`);
|
|
114
|
+
|
|
115
|
+
// Success page
|
|
116
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
117
|
+
res.end(`
|
|
118
|
+
<html>
|
|
119
|
+
<head>
|
|
120
|
+
<title>š Authentication Successful - ICE Activated</title>
|
|
121
|
+
<style>
|
|
122
|
+
body {
|
|
123
|
+
font-family: Arial, sans-serif;
|
|
124
|
+
padding: 50px;
|
|
125
|
+
text-align: center;
|
|
126
|
+
background: linear-gradient(135deg, #0891b2 0%, #06b6d4 100%);
|
|
127
|
+
color: white;
|
|
128
|
+
}
|
|
129
|
+
.container {
|
|
130
|
+
background: white;
|
|
131
|
+
color: #333;
|
|
132
|
+
padding: 40px;
|
|
133
|
+
border-radius: 10px;
|
|
134
|
+
max-width: 500px;
|
|
135
|
+
margin: 0 auto;
|
|
136
|
+
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
|
|
137
|
+
}
|
|
138
|
+
h1 { color: #0891b2; }
|
|
139
|
+
.emoji { font-size: 48px; margin: 20px 0; }
|
|
140
|
+
code {
|
|
141
|
+
background: #f5f5f5;
|
|
142
|
+
padding: 2px 6px;
|
|
143
|
+
border-radius: 3px;
|
|
144
|
+
color: #0891b2;
|
|
145
|
+
}
|
|
146
|
+
</style>
|
|
147
|
+
</head>
|
|
148
|
+
<body>
|
|
149
|
+
<div class="container">
|
|
150
|
+
<div class="emoji">šā
āļø</div>
|
|
151
|
+
<h1>ICE Activated!</h1>
|
|
152
|
+
<p>Yahoo authentication successful. Intent Chirp Engine is ready to dominate.</p>
|
|
153
|
+
<p>You can close this window and return to your terminal.</p>
|
|
154
|
+
<hr>
|
|
155
|
+
<p><strong>Next steps:</strong></p>
|
|
156
|
+
<ol style="text-align: left; display: inline-block;">
|
|
157
|
+
<li>Server is built and ready</li>
|
|
158
|
+
<li>Test with: <code>npm start</code></li>
|
|
159
|
+
<li>Add to Claude Desktop config</li>
|
|
160
|
+
<li>Start getting chirped with winning insights</li>
|
|
161
|
+
</ol>
|
|
162
|
+
</div>
|
|
163
|
+
</body>
|
|
164
|
+
</html>
|
|
165
|
+
`);
|
|
166
|
+
|
|
167
|
+
// Close server after success
|
|
168
|
+
setTimeout(() => {
|
|
169
|
+
server.close();
|
|
170
|
+
console.log('\nš ICE is ready! Next steps:');
|
|
171
|
+
console.log(' 1. Test the server: npm start');
|
|
172
|
+
console.log(' 2. Add to Claude Desktop config (see ACTIVATION_STEPS.md)');
|
|
173
|
+
console.log(' 3. Start dominating your fantasy league with semantic chirps');
|
|
174
|
+
process.exit(0);
|
|
175
|
+
}, 1000);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error('ā Error during callback:', error);
|
|
178
|
+
res.writeHead(500, { 'Content-Type': 'text/html' });
|
|
179
|
+
res.end(`
|
|
180
|
+
<html>
|
|
181
|
+
<head><title>Authentication Failed</title></head>
|
|
182
|
+
<body style="font-family: Arial; padding: 50px; text-align: center;">
|
|
183
|
+
<h1 style="color: #f44336;">ā Authentication Failed</h1>
|
|
184
|
+
<p>Check the terminal for error details.</p>
|
|
185
|
+
</body>
|
|
186
|
+
</html>
|
|
187
|
+
`);
|
|
188
|
+
setTimeout(() => {
|
|
189
|
+
server.close();
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}, 1000);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
server.listen(3000, () => {
|
|
197
|
+
console.log('š HTTPS Server started on https://localhost:3000');
|
|
198
|
+
console.log('\nš Open this URL in your browser to start authentication:');
|
|
199
|
+
console.log(' https://localhost:3000/\n');
|
|
200
|
+
console.log('ā³ Waiting for authentication...\n');
|
|
201
|
+
|
|
202
|
+
// Helpful reminders
|
|
203
|
+
console.log('š” Make sure your Yahoo app has this redirect URI configured:');
|
|
204
|
+
console.log(' https://localhost:3000/callback\n');
|
|
205
|
+
console.log('ā ļø Your browser will show a security warning (self-signed cert)');
|
|
206
|
+
console.log(' Click "Advanced" ā "Proceed to localhost" to continue\n');
|
|
207
|
+
});
|