@dolusoft/hirebase-mcp 1.1.8 → 1.1.10
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/README.md +29 -23
- package/dist/application/ports/calendar-service.d.ts +24 -0
- package/dist/application/ports/calendar-service.js +2 -0
- package/dist/application/ports/calendar-service.js.map +1 -0
- package/dist/infrastructure/ai/openai-embedding-service.js +1 -1
- package/dist/infrastructure/calendar/google-calendar.service.d.ts +20 -0
- package/dist/infrastructure/calendar/google-calendar.service.js +241 -0
- package/dist/infrastructure/calendar/google-calendar.service.js.map +1 -0
- package/dist/infrastructure/calendar/index.d.ts +1 -0
- package/dist/infrastructure/calendar/index.js +2 -0
- package/dist/infrastructure/calendar/index.js.map +1 -0
- package/dist/infrastructure/config/app-config.d.ts +2 -0
- package/dist/infrastructure/config/app-config.js +3 -1
- package/dist/infrastructure/config/app-config.js.map +1 -1
- package/dist/interface/dashboard/public/200.html +1 -1
- package/dist/interface/dashboard/public/404.html +1 -1
- package/dist/interface/dashboard/public/_nuxt/builds/latest.json +1 -1
- package/dist/interface/dashboard/public/_nuxt/builds/meta/4d9b8de6-1292-42ca-8f07-c47ba5f61768.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/ec2a9f02-6137-4473-bc4f-0e48df1e085b.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/f4e23d88-bf4b-4110-976f-4e7a2c538e98.json +1 -0
- package/dist/interface/dashboard/public/index.html +1 -1
- package/dist/interface/dashboard/tool-wrapper.js +1 -1
- package/dist/interface/mcp/server.js +10 -0
- package/dist/interface/mcp/server.js.map +1 -1
- package/dist/interface/mcp/tools/authorize-calendar.d.ts +3 -0
- package/dist/interface/mcp/tools/authorize-calendar.js +20 -0
- package/dist/interface/mcp/tools/authorize-calendar.js.map +1 -0
- package/dist/interface/mcp/tools/create-calendar-event.d.ts +3 -0
- package/dist/interface/mcp/tools/create-calendar-event.js +46 -0
- package/dist/interface/mcp/tools/create-calendar-event.js.map +1 -0
- package/dist/interface/mcp/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,15 +23,16 @@ src/
|
|
|
23
23
|
|---|---|
|
|
24
24
|
| TypeScript 5.9 | Language |
|
|
25
25
|
| LanceDB | Vector database (embedded, serverless) |
|
|
26
|
-
| OpenAI `text-embedding-3-
|
|
26
|
+
| OpenAI `text-embedding-3-small` | 1536-dim embeddings |
|
|
27
27
|
| OpenAI `gpt-5-mini` | Structured CV extraction (Responses API) |
|
|
28
28
|
| MCP SDK | Model Context Protocol server |
|
|
29
29
|
| Nuxt 4 + Nuxt UI | Real-time dashboard |
|
|
30
30
|
| unpdf | PDF text extraction |
|
|
31
31
|
| mammoth | DOCX text extraction |
|
|
32
32
|
| Tesseract.js | OCR for image-based PDFs |
|
|
33
|
+
| Google Calendar API | Interview scheduling (OAuth2, zero dependencies) |
|
|
33
34
|
|
|
34
|
-
## MCP Tools (
|
|
35
|
+
## MCP Tools (29)
|
|
35
36
|
|
|
36
37
|
### CV Management
|
|
37
38
|
|
|
@@ -79,6 +80,15 @@ src/
|
|
|
79
80
|
|
|
80
81
|
**Pipeline statuses:** `new` → `contacted` → `unreachable` · `not_interested` · `interview_scheduled` → `no_show` · `interviewed` → `rejected` · `offer_sent` → `hired`
|
|
81
82
|
|
|
83
|
+
### Google Calendar
|
|
84
|
+
|
|
85
|
+
| Tool | Description |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `authorize_google_calendar` | OAuth2 authorization flow — opens browser for Google consent (one-time) |
|
|
88
|
+
| `create_calendar_event` | Create events for interviews, meetings, and follow-ups |
|
|
89
|
+
|
|
90
|
+
> Calendar tools only appear when `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` are configured.
|
|
91
|
+
|
|
82
92
|
### System
|
|
83
93
|
|
|
84
94
|
| Tool | Description |
|
|
@@ -104,7 +114,7 @@ CV File (PDF/DOCX/Scanned PDF)
|
|
|
104
114
|
[3] Chunk into sections
|
|
105
115
|
│ summary, each experience, education, skills, projects, certifications, full text
|
|
106
116
|
▼
|
|
107
|
-
[4] Generate embeddings (text-embedding-3-
|
|
117
|
+
[4] Generate embeddings (text-embedding-3-small, 1536d)
|
|
108
118
|
│
|
|
109
119
|
▼
|
|
110
120
|
[5] Store in LanceDB (candidates + cv_chunks + cv_versions)
|
|
@@ -163,7 +173,7 @@ LanceDB tables:
|
|
|
163
173
|
| Table | Purpose |
|
|
164
174
|
|---|---|
|
|
165
175
|
| `candidates` | Candidate profiles (name, email, skills, experience, loyalty score, tags) |
|
|
166
|
-
| `cv_chunks` | Searchable CV sections with
|
|
176
|
+
| `cv_chunks` | Searchable CV sections with 1536-dim vector embeddings |
|
|
167
177
|
| `cv_versions` | Archived CV versions for update history |
|
|
168
178
|
| `job_postings` | Job listings with required/preferred skills and status |
|
|
169
179
|
| `applications` | Pipeline records linking candidates to jobs with status tracking |
|
|
@@ -190,29 +200,20 @@ pnpm build
|
|
|
190
200
|
|
|
191
201
|
- Node.js >= 22
|
|
192
202
|
- OpenAI API Key
|
|
203
|
+
- Google Cloud OAuth2 credentials (optional, for calendar integration)
|
|
193
204
|
|
|
194
205
|
## MCP Configuration
|
|
195
206
|
|
|
196
207
|
### Claude Code (npx)
|
|
197
208
|
|
|
198
209
|
```bash
|
|
199
|
-
claude mcp add hirebase
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"mcpServers": {
|
|
207
|
-
"hirebase": {
|
|
208
|
-
"command": "npx",
|
|
209
|
-
"args": ["-y", "@dolusoft/hirebase-mcp"],
|
|
210
|
-
"env": {
|
|
211
|
-
"OPENAI_API_KEY": "sk-your-key"
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
210
|
+
claude mcp add hirebase -s user \
|
|
211
|
+
-e OPENAI_API_KEY=sk-your-key \
|
|
212
|
+
-e EMBEDDING_MODEL=text-embedding-3-small \
|
|
213
|
+
-e DASHBOARD_ENABLED=true \
|
|
214
|
+
-e GOOGLE_CLIENT_ID=your-client-id \
|
|
215
|
+
-e GOOGLE_CLIENT_SECRET=your-client-secret \
|
|
216
|
+
-- npx -y @dolusoft/hirebase-mcp
|
|
216
217
|
```
|
|
217
218
|
|
|
218
219
|
### Claude Desktop
|
|
@@ -227,7 +228,9 @@ Add to your Claude Desktop config (`claude_desktop_config.json`):
|
|
|
227
228
|
"args": ["-y", "@dolusoft/hirebase-mcp"],
|
|
228
229
|
"env": {
|
|
229
230
|
"OPENAI_API_KEY": "sk-your-key",
|
|
230
|
-
"LANCEDB_PATH": "./data/lancedb"
|
|
231
|
+
"LANCEDB_PATH": "./data/lancedb",
|
|
232
|
+
"GOOGLE_CLIENT_ID": "your-client-id",
|
|
233
|
+
"GOOGLE_CLIENT_SECRET": "your-client-secret"
|
|
231
234
|
}
|
|
232
235
|
}
|
|
233
236
|
}
|
|
@@ -240,10 +243,12 @@ Add to your Claude Desktop config (`claude_desktop_config.json`):
|
|
|
240
243
|
|---|---|---|
|
|
241
244
|
| `OPENAI_API_KEY` | *required* | OpenAI API key |
|
|
242
245
|
| `LANCEDB_PATH` | `./data/lancedb` | LanceDB storage path |
|
|
243
|
-
| `EMBEDDING_MODEL` | `text-embedding-3-
|
|
246
|
+
| `EMBEDDING_MODEL` | `text-embedding-3-small` | Embedding model |
|
|
244
247
|
| `EXTRACTION_MODEL` | `gpt-5-mini` | CV extraction model |
|
|
245
248
|
| `DASHBOARD_ENABLED` | `true` | Enable real-time dashboard |
|
|
246
249
|
| `DASHBOARD_PORT` | `0` (random) | Dashboard server port |
|
|
250
|
+
| `GOOGLE_CLIENT_ID` | — | Google OAuth2 client ID (for calendar) |
|
|
251
|
+
| `GOOGLE_CLIENT_SECRET` | — | Google OAuth2 client secret (for calendar) |
|
|
247
252
|
|
|
248
253
|
## Key Design Decisions
|
|
249
254
|
|
|
@@ -255,6 +260,7 @@ Add to your Claude Desktop config (`claude_desktop_config.json`):
|
|
|
255
260
|
- **Section-level chunking** — each work experience is a separate chunk for granular matching
|
|
256
261
|
- **OCR fallback** — image-based PDFs automatically processed with Tesseract.js
|
|
257
262
|
- **Composite scoring** — matching combines semantic, skill-based, and loyalty signals
|
|
263
|
+
- **Google Calendar** — zero-dependency OAuth2 + Calendar API using Node.js built-in `fetch`
|
|
258
264
|
|
|
259
265
|
## License
|
|
260
266
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface CalendarEventInput {
|
|
2
|
+
title: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
location?: string;
|
|
5
|
+
startTime: string;
|
|
6
|
+
endTime: string;
|
|
7
|
+
attendees?: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface CalendarEventResult {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
htmlLink: string;
|
|
13
|
+
startTime: string;
|
|
14
|
+
endTime: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ICalendarService {
|
|
17
|
+
isAuthorized(): Promise<boolean>;
|
|
18
|
+
authorize(): Promise<{
|
|
19
|
+
success: boolean;
|
|
20
|
+
message: string;
|
|
21
|
+
}>;
|
|
22
|
+
createEvent(event: CalendarEventInput): Promise<CalendarEventResult>;
|
|
23
|
+
deleteEvent(eventId: string): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-service.js","sourceRoot":"","sources":["../../../src/application/ports/calendar-service.ts"],"names":[],"mappings":""}
|
|
@@ -3,7 +3,7 @@ import { EmbeddingError } from '../../shared/errors/index.js';
|
|
|
3
3
|
export class OpenAiEmbeddingService {
|
|
4
4
|
client;
|
|
5
5
|
model;
|
|
6
|
-
constructor(apiKey, model = 'text-embedding-3-
|
|
6
|
+
constructor(apiKey, model = 'text-embedding-3-small') {
|
|
7
7
|
this.client = new OpenAI({ apiKey });
|
|
8
8
|
this.model = model;
|
|
9
9
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ICalendarService, CalendarEventInput, CalendarEventResult } from '../../application/ports/calendar-service.js';
|
|
2
|
+
export declare class GoogleCalendarService implements ICalendarService {
|
|
3
|
+
private clientId;
|
|
4
|
+
private clientSecret;
|
|
5
|
+
private tokenPath;
|
|
6
|
+
private tokens;
|
|
7
|
+
private tokensLoaded;
|
|
8
|
+
constructor(clientId: string, clientSecret: string, dataPath: string);
|
|
9
|
+
isAuthorized(): Promise<boolean>;
|
|
10
|
+
authorize(): Promise<{
|
|
11
|
+
success: boolean;
|
|
12
|
+
message: string;
|
|
13
|
+
}>;
|
|
14
|
+
createEvent(event: CalendarEventInput): Promise<CalendarEventResult>;
|
|
15
|
+
deleteEvent(eventId: string): Promise<void>;
|
|
16
|
+
private ensureTokensLoaded;
|
|
17
|
+
private saveTokens;
|
|
18
|
+
private getAccessToken;
|
|
19
|
+
private exchangeCodeForTokens;
|
|
20
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { createServer as createHttpServer } from 'node:http';
|
|
2
|
+
import { exec } from 'node:child_process';
|
|
3
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { join, dirname } from 'node:path';
|
|
6
|
+
const AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
|
|
7
|
+
const TOKEN_URL = 'https://oauth2.googleapis.com/token';
|
|
8
|
+
const CALENDAR_API = 'https://www.googleapis.com/calendar/v3';
|
|
9
|
+
const SCOPES = ['https://www.googleapis.com/auth/calendar.events'];
|
|
10
|
+
const AUTH_TIMEOUT_MS = 120_000;
|
|
11
|
+
const TOKEN_BUFFER_MS = 300_000; // Refresh 5 min before expiry
|
|
12
|
+
export class GoogleCalendarService {
|
|
13
|
+
clientId;
|
|
14
|
+
clientSecret;
|
|
15
|
+
tokenPath;
|
|
16
|
+
tokens = null;
|
|
17
|
+
tokensLoaded = false;
|
|
18
|
+
constructor(clientId, clientSecret, dataPath) {
|
|
19
|
+
this.clientId = clientId;
|
|
20
|
+
this.clientSecret = clientSecret;
|
|
21
|
+
this.tokenPath = join(dirname(dataPath), 'google-calendar-token.json');
|
|
22
|
+
}
|
|
23
|
+
async isAuthorized() {
|
|
24
|
+
await this.ensureTokensLoaded();
|
|
25
|
+
return this.tokens !== null && !!this.tokens.refresh_token;
|
|
26
|
+
}
|
|
27
|
+
async authorize() {
|
|
28
|
+
await this.ensureTokensLoaded();
|
|
29
|
+
if (this.tokens?.refresh_token) {
|
|
30
|
+
return { success: true, message: 'Already authorized with Google Calendar.' };
|
|
31
|
+
}
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
let resolved = false;
|
|
34
|
+
const httpServer = createHttpServer(async (req, res) => {
|
|
35
|
+
if (resolved)
|
|
36
|
+
return;
|
|
37
|
+
const url = new URL(req.url, 'http://localhost');
|
|
38
|
+
const code = url.searchParams.get('code');
|
|
39
|
+
const error = url.searchParams.get('error');
|
|
40
|
+
if (error) {
|
|
41
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
42
|
+
res.end(htmlPage('Yetkilendirme Başarısız', 'Erişim reddedildi. Bu pencereyi kapatabilirsiniz.'));
|
|
43
|
+
resolved = true;
|
|
44
|
+
httpServer.close();
|
|
45
|
+
resolve({ success: false, message: `Authorization denied: ${error}` });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (code) {
|
|
49
|
+
const port = httpServer.address().port;
|
|
50
|
+
try {
|
|
51
|
+
await this.exchangeCodeForTokens(code, `http://localhost:${port}`);
|
|
52
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
53
|
+
res.end(htmlPage('HireBase Yetkilendirildi!', 'Google Calendar bağlantısı başarılı. Bu pencereyi kapatabilirsiniz.'));
|
|
54
|
+
resolved = true;
|
|
55
|
+
httpServer.close();
|
|
56
|
+
resolve({ success: true, message: 'Google Calendar successfully authorized. Token saved.' });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
60
|
+
res.end(htmlPage('Hata', 'Token alınamadı. Lütfen tekrar deneyin.'));
|
|
61
|
+
resolved = true;
|
|
62
|
+
httpServer.close();
|
|
63
|
+
resolve({ success: false, message: `Token exchange failed: ${err.message}` });
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
res.writeHead(404);
|
|
68
|
+
res.end();
|
|
69
|
+
});
|
|
70
|
+
httpServer.listen(0, () => {
|
|
71
|
+
const port = httpServer.address().port;
|
|
72
|
+
const redirectUri = `http://localhost:${port}`;
|
|
73
|
+
const authUrl = new URL(AUTH_URL);
|
|
74
|
+
authUrl.searchParams.set('client_id', this.clientId);
|
|
75
|
+
authUrl.searchParams.set('redirect_uri', redirectUri);
|
|
76
|
+
authUrl.searchParams.set('response_type', 'code');
|
|
77
|
+
authUrl.searchParams.set('scope', SCOPES.join(' '));
|
|
78
|
+
authUrl.searchParams.set('access_type', 'offline');
|
|
79
|
+
authUrl.searchParams.set('prompt', 'consent');
|
|
80
|
+
openBrowser(authUrl.toString());
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
if (!resolved) {
|
|
83
|
+
resolved = true;
|
|
84
|
+
httpServer.close();
|
|
85
|
+
resolve({ success: false, message: 'Authorization timed out after 120 seconds.' });
|
|
86
|
+
}
|
|
87
|
+
}, AUTH_TIMEOUT_MS);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async createEvent(event) {
|
|
92
|
+
const accessToken = await this.getAccessToken();
|
|
93
|
+
const body = {
|
|
94
|
+
summary: event.title,
|
|
95
|
+
description: event.description,
|
|
96
|
+
location: event.location,
|
|
97
|
+
start: {
|
|
98
|
+
dateTime: event.startTime,
|
|
99
|
+
timeZone: 'Europe/Istanbul',
|
|
100
|
+
},
|
|
101
|
+
end: {
|
|
102
|
+
dateTime: event.endTime,
|
|
103
|
+
timeZone: 'Europe/Istanbul',
|
|
104
|
+
},
|
|
105
|
+
attendees: event.attendees?.map((email) => ({ email })),
|
|
106
|
+
reminders: {
|
|
107
|
+
useDefault: false,
|
|
108
|
+
overrides: [
|
|
109
|
+
{ method: 'popup', minutes: 30 },
|
|
110
|
+
{ method: 'popup', minutes: 10 },
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
const response = await fetch(`${CALENDAR_API}/calendars/primary/events`, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
Authorization: `Bearer ${accessToken}`,
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
},
|
|
120
|
+
body: JSON.stringify(body),
|
|
121
|
+
});
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
const error = await response.text();
|
|
124
|
+
throw new Error(`Failed to create calendar event: ${error}`);
|
|
125
|
+
}
|
|
126
|
+
const data = (await response.json());
|
|
127
|
+
return {
|
|
128
|
+
id: data.id,
|
|
129
|
+
title: data.summary,
|
|
130
|
+
htmlLink: data.htmlLink,
|
|
131
|
+
startTime: data.start.dateTime,
|
|
132
|
+
endTime: data.end.dateTime,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
async deleteEvent(eventId) {
|
|
136
|
+
const accessToken = await this.getAccessToken();
|
|
137
|
+
const response = await fetch(`${CALENDAR_API}/calendars/primary/events/${eventId}`, {
|
|
138
|
+
method: 'DELETE',
|
|
139
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
140
|
+
});
|
|
141
|
+
if (!response.ok && response.status !== 404) {
|
|
142
|
+
const error = await response.text();
|
|
143
|
+
throw new Error(`Failed to delete calendar event: ${error}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// ── Private helpers ──────────────────────────────────────────────
|
|
147
|
+
async ensureTokensLoaded() {
|
|
148
|
+
if (this.tokensLoaded)
|
|
149
|
+
return;
|
|
150
|
+
try {
|
|
151
|
+
if (existsSync(this.tokenPath)) {
|
|
152
|
+
const data = await readFile(this.tokenPath, 'utf-8');
|
|
153
|
+
this.tokens = JSON.parse(data);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
this.tokens = null;
|
|
158
|
+
}
|
|
159
|
+
this.tokensLoaded = true;
|
|
160
|
+
}
|
|
161
|
+
async saveTokens(tokens) {
|
|
162
|
+
this.tokens = tokens;
|
|
163
|
+
const dir = dirname(this.tokenPath);
|
|
164
|
+
if (!existsSync(dir)) {
|
|
165
|
+
await mkdir(dir, { recursive: true });
|
|
166
|
+
}
|
|
167
|
+
await writeFile(this.tokenPath, JSON.stringify(tokens, null, 2));
|
|
168
|
+
}
|
|
169
|
+
async getAccessToken() {
|
|
170
|
+
await this.ensureTokensLoaded();
|
|
171
|
+
if (!this.tokens?.refresh_token) {
|
|
172
|
+
throw new Error('Not authorized. Call authorize_google_calendar first.');
|
|
173
|
+
}
|
|
174
|
+
// Return current token if still valid
|
|
175
|
+
if (this.tokens.expires_at && Date.now() < this.tokens.expires_at - TOKEN_BUFFER_MS) {
|
|
176
|
+
return this.tokens.access_token;
|
|
177
|
+
}
|
|
178
|
+
// Refresh the token
|
|
179
|
+
const response = await fetch(TOKEN_URL, {
|
|
180
|
+
method: 'POST',
|
|
181
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
182
|
+
body: new URLSearchParams({
|
|
183
|
+
client_id: this.clientId,
|
|
184
|
+
client_secret: this.clientSecret,
|
|
185
|
+
refresh_token: this.tokens.refresh_token,
|
|
186
|
+
grant_type: 'refresh_token',
|
|
187
|
+
}),
|
|
188
|
+
});
|
|
189
|
+
if (!response.ok) {
|
|
190
|
+
const error = await response.text();
|
|
191
|
+
throw new Error(`Token refresh failed: ${error}`);
|
|
192
|
+
}
|
|
193
|
+
const data = (await response.json());
|
|
194
|
+
this.tokens.access_token = data.access_token;
|
|
195
|
+
this.tokens.expires_at = Date.now() + data.expires_in * 1000;
|
|
196
|
+
await this.saveTokens(this.tokens);
|
|
197
|
+
return data.access_token;
|
|
198
|
+
}
|
|
199
|
+
async exchangeCodeForTokens(code, redirectUri) {
|
|
200
|
+
const response = await fetch(TOKEN_URL, {
|
|
201
|
+
method: 'POST',
|
|
202
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
203
|
+
body: new URLSearchParams({
|
|
204
|
+
code,
|
|
205
|
+
client_id: this.clientId,
|
|
206
|
+
client_secret: this.clientSecret,
|
|
207
|
+
redirect_uri: redirectUri,
|
|
208
|
+
grant_type: 'authorization_code',
|
|
209
|
+
}),
|
|
210
|
+
});
|
|
211
|
+
if (!response.ok) {
|
|
212
|
+
const error = await response.text();
|
|
213
|
+
throw new Error(error);
|
|
214
|
+
}
|
|
215
|
+
const data = (await response.json());
|
|
216
|
+
await this.saveTokens({
|
|
217
|
+
access_token: data.access_token,
|
|
218
|
+
refresh_token: data.refresh_token,
|
|
219
|
+
token_type: data.token_type,
|
|
220
|
+
expires_at: Date.now() + data.expires_in * 1000,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// ── Utilities ──────────────────────────────────────────────────────
|
|
225
|
+
function openBrowser(url) {
|
|
226
|
+
const cmd = process.platform === 'win32'
|
|
227
|
+
? `start "" "${url}"`
|
|
228
|
+
: process.platform === 'darwin'
|
|
229
|
+
? `open "${url}"`
|
|
230
|
+
: `xdg-open "${url}"`;
|
|
231
|
+
exec(cmd);
|
|
232
|
+
}
|
|
233
|
+
function htmlPage(title, message) {
|
|
234
|
+
return `<!DOCTYPE html>
|
|
235
|
+
<html><head><meta charset="utf-8"><title>HireBase</title>
|
|
236
|
+
<style>body{font-family:system-ui;display:flex;justify-content:center;align-items:center;min-height:100vh;margin:0;background:#f8fafc}
|
|
237
|
+
.card{text-align:center;padding:3rem;border-radius:1rem;background:white;box-shadow:0 4px 24px rgba(0,0,0,.08)}
|
|
238
|
+
h1{color:#0f172a;margin-bottom:.5rem}p{color:#64748b}</style>
|
|
239
|
+
</head><body><div class="card"><h1>${title}</h1><p>${message}</p></div></body></html>`;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=google-calendar.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-calendar.service.js","sourceRoot":"","sources":["../../../src/infrastructure/calendar/google-calendar.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GoogleCalendarService } from './google-calendar.service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/calendar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -6,10 +6,12 @@ export function loadConfig() {
|
|
|
6
6
|
return {
|
|
7
7
|
openaiApiKey,
|
|
8
8
|
lancedbPath: process.env.LANCEDB_PATH ?? './data/lancedb',
|
|
9
|
-
embeddingModel: process.env.EMBEDDING_MODEL ?? 'text-embedding-3-small',
|
|
9
|
+
embeddingModel: process.env.EMBEDDING_MODEL ?? 'text-embedding-3-small', // Production uses small (1536d)
|
|
10
10
|
extractionModel: process.env.EXTRACTION_MODEL ?? 'gpt-5-mini',
|
|
11
11
|
dashboardEnabled: process.env.DASHBOARD_ENABLED !== 'false',
|
|
12
12
|
dashboardPort: parseInt(process.env.DASHBOARD_PORT ?? '0', 10),
|
|
13
|
+
googleClientId: process.env.GOOGLE_CLIENT_ID,
|
|
14
|
+
googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
13
15
|
};
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=app-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../src/infrastructure/config/app-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../src/infrastructure/config/app-config.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,UAAU;IACxB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAChD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO;QACL,YAAY;QACZ,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,gBAAgB;QACzD,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,EAAE,gCAAgC;QACzG,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,YAAY;QAC7D,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,OAAO;QAC3D,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,EAAE,EAAE,CAAC;QAC9D,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5C,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;KACrD,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Bl31cpjT.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CdJZeyak.js"><script type="module" src="/_nuxt/CdJZeyak.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Bl31cpjT.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CdJZeyak.js"><script type="module" src="/_nuxt/CdJZeyak.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildId:"4d9b8de6-1292-42ca-8f07-c47ba5f61768",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1771932385539,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Bl31cpjT.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CdJZeyak.js"><script type="module" src="/_nuxt/CdJZeyak.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Bl31cpjT.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CdJZeyak.js"><script type="module" src="/_nuxt/CdJZeyak.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildId:"4d9b8de6-1292-42ca-8f07-c47ba5f61768",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1771932385540,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"4d9b8de6-1292-42ca-8f07-c47ba5f61768","timestamp":1771932381046}
|
package/dist/interface/dashboard/public/_nuxt/builds/meta/4d9b8de6-1292-42ca-8f07-c47ba5f61768.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"4d9b8de6-1292-42ca-8f07-c47ba5f61768","timestamp":1771932381046,"prerendered":[]}
|
package/dist/interface/dashboard/public/_nuxt/builds/meta/ec2a9f02-6137-4473-bc4f-0e48df1e085b.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"ec2a9f02-6137-4473-bc4f-0e48df1e085b","timestamp":1771927503106,"prerendered":[]}
|
package/dist/interface/dashboard/public/_nuxt/builds/meta/f4e23d88-bf4b-4110-976f-4e7a2c538e98.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"f4e23d88-bf4b-4110-976f-4e7a2c538e98","timestamp":1771932335753,"prerendered":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Bl31cpjT.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CdJZeyak.js"><script type="module" src="/_nuxt/CdJZeyak.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Bl31cpjT.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CdJZeyak.js"><script type="module" src="/_nuxt/CdJZeyak.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/",buildId:"4d9b8de6-1292-42ca-8f07-c47ba5f61768",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1771932385540,false]</script></body></html>
|
|
@@ -9,7 +9,7 @@ const MUTATING_TOOLS = new Set([
|
|
|
9
9
|
'add_job_posting',
|
|
10
10
|
]);
|
|
11
11
|
const RESULT_PREVIEW_LIMIT = 500;
|
|
12
|
-
const SEARCH_RESULT_LIMIT =
|
|
12
|
+
const SEARCH_RESULT_LIMIT = 50_000;
|
|
13
13
|
function truncate(text, max) {
|
|
14
14
|
return text.length > max ? text.slice(0, max) + '…' : text;
|
|
15
15
|
}
|
|
@@ -12,6 +12,7 @@ import { DocxParser } from '../../infrastructure/parsers/docx-parser.js';
|
|
|
12
12
|
import { OpenAiEmbeddingService } from '../../infrastructure/ai/openai-embedding-service.js';
|
|
13
13
|
import { OpenAiStructuredExtractor } from '../../infrastructure/ai/openai-structured-extractor.js';
|
|
14
14
|
import { CsvExportService } from '../../infrastructure/export/csv-export-service.js';
|
|
15
|
+
import { GoogleCalendarService } from '../../infrastructure/calendar/google-calendar.service.js';
|
|
15
16
|
import { DashboardEventBus } from '../dashboard/event-bus.js';
|
|
16
17
|
import { wrapAllRegisteredTools } from '../dashboard/tool-wrapper.js';
|
|
17
18
|
import { startDashboardServer } from '../dashboard/server.js';
|
|
@@ -42,6 +43,8 @@ import { registerSetPendingActionTool } from './tools/set-pending-action.js';
|
|
|
42
43
|
import { registerGetPipelineTool } from './tools/get-pipeline.js';
|
|
43
44
|
import { registerGetCandidateHistoryTool } from './tools/get-candidate-history.js';
|
|
44
45
|
import { registerGetPendingActionsTool } from './tools/get-pending-actions.js';
|
|
46
|
+
import { registerAuthorizeCalendarTool } from './tools/authorize-calendar.js';
|
|
47
|
+
import { registerCreateCalendarEventTool } from './tools/create-calendar-event.js';
|
|
45
48
|
export async function createServer() {
|
|
46
49
|
const config = loadConfig();
|
|
47
50
|
configureVectorDimension(config.embeddingModel);
|
|
@@ -56,6 +59,10 @@ export async function createServer() {
|
|
|
56
59
|
const embeddingService = new OpenAiEmbeddingService(config.openaiApiKey, config.embeddingModel);
|
|
57
60
|
const extractor = new OpenAiStructuredExtractor(config.openaiApiKey, config.extractionModel);
|
|
58
61
|
const exportService = new CsvExportService();
|
|
62
|
+
let calendarService;
|
|
63
|
+
if (config.googleClientId && config.googleClientSecret) {
|
|
64
|
+
calendarService = new GoogleCalendarService(config.googleClientId, config.googleClientSecret, config.lancedbPath);
|
|
65
|
+
}
|
|
59
66
|
const deps = {
|
|
60
67
|
candidateRepo,
|
|
61
68
|
chunkRepo,
|
|
@@ -67,6 +74,7 @@ export async function createServer() {
|
|
|
67
74
|
embeddingService,
|
|
68
75
|
extractor,
|
|
69
76
|
exportService,
|
|
77
|
+
calendarService,
|
|
70
78
|
};
|
|
71
79
|
const server = new McpServer({
|
|
72
80
|
name: 'hirebase',
|
|
@@ -99,6 +107,8 @@ export async function createServer() {
|
|
|
99
107
|
registerGetPipelineTool(server, deps);
|
|
100
108
|
registerGetCandidateHistoryTool(server, deps);
|
|
101
109
|
registerGetPendingActionsTool(server, deps);
|
|
110
|
+
registerAuthorizeCalendarTool(server, deps);
|
|
111
|
+
registerCreateCalendarEventTool(server, deps);
|
|
102
112
|
if (config.dashboardEnabled) {
|
|
103
113
|
const eventBus = new DashboardEventBus();
|
|
104
114
|
wrapAllRegisteredTools(server, eventBus, deps);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/interface/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AACrG,OAAO,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAC9G,OAAO,EAAE,sBAAsB,EAAE,MAAM,8DAA8D,CAAC;AACtG,OAAO,EAAE,wBAAwB,EAAE,MAAM,gEAAgE,CAAC;AAC1G,OAAO,EAAE,2BAA2B,EAAE,MAAM,oEAAoE,CAAC;AACjH,OAAO,EAAE,4BAA4B,EAAE,MAAM,oEAAoE,CAAC;AAClH,OAAO,EAAE,iCAAiC,EAAE,MAAM,0EAA0E,CAAC;AAC7H,OAAO,EAAE,SAAS,EAAE,MAAM,4CAA4C,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qDAAqD,CAAC;AAC7F,OAAO,EAAE,yBAAyB,EAAE,MAAM,wDAAwD,CAAC;AACnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/interface/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function registerAuthorizeCalendarTool(server, deps) {
|
|
2
|
+
if (!deps.calendarService)
|
|
3
|
+
return;
|
|
4
|
+
server.tool('authorize_google_calendar', 'Authorize HireBase to access Google Calendar. Opens browser for Google OAuth consent. Required once before creating calendar events.', {}, async () => {
|
|
5
|
+
try {
|
|
6
|
+
const result = await deps.calendarService.authorize();
|
|
7
|
+
return {
|
|
8
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
9
|
+
isError: !result.success,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return {
|
|
14
|
+
content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
|
|
15
|
+
isError: true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=authorize-calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize-calendar.js","sourceRoot":"","sources":["../../../../src/interface/mcp/tools/authorize-calendar.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,6BAA6B,CAAC,MAAiB,EAAE,IAAkB;IACjF,IAAI,CAAC,IAAI,CAAC,eAAe;QAAE,OAAO;IAElC,MAAM,CAAC,IAAI,CACT,2BAA2B,EAC3B,sIAAsI,EACtI,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAgB,CAAC,SAAS,EAAE,CAAC;YACvD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC3E,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO;aACzB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBAC/F,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
export function registerCreateCalendarEventTool(server, deps) {
|
|
3
|
+
if (!deps.calendarService)
|
|
4
|
+
return;
|
|
5
|
+
server.tool('create_calendar_event', 'Create an event in Google Calendar. Use for scheduling interviews, meetings, and follow-ups.', {
|
|
6
|
+
title: z.string().describe('Event title (e.g., "Görüşme - Cemre Özer")'),
|
|
7
|
+
start_time: z
|
|
8
|
+
.string()
|
|
9
|
+
.describe('Start time in ISO 8601 format (e.g., "2026-02-26T11:30:00+03:00")'),
|
|
10
|
+
end_time: z
|
|
11
|
+
.string()
|
|
12
|
+
.describe('End time in ISO 8601 format (e.g., "2026-02-26T12:30:00+03:00")'),
|
|
13
|
+
description: z.string().optional().describe('Event description with details'),
|
|
14
|
+
location: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Event location (e.g., "WhatsApp Online", "Dolusoft Ofis")'),
|
|
18
|
+
attendees: z
|
|
19
|
+
.array(z.string())
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('List of attendee email addresses'),
|
|
22
|
+
}, async ({ title, start_time, end_time, description, location, attendees }) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = await deps.calendarService.createEvent({
|
|
25
|
+
title,
|
|
26
|
+
startTime: start_time,
|
|
27
|
+
endTime: end_time,
|
|
28
|
+
description,
|
|
29
|
+
location,
|
|
30
|
+
attendees,
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{ type: 'text', text: JSON.stringify({ error: error.message }) },
|
|
40
|
+
],
|
|
41
|
+
isError: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=create-calendar-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-calendar-event.js","sourceRoot":"","sources":["../../../../src/interface/mcp/tools/create-calendar-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAG3B,MAAM,UAAU,+BAA+B,CAAC,MAAiB,EAAE,IAAkB;IACnF,IAAI,CAAC,IAAI,CAAC,eAAe;QAAE,OAAO;IAElC,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,8FAA8F,EAC9F;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;QACxE,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,CAAC,mEAAmE,CAAC;QAChF,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,CAAC,iEAAiE,CAAC;QAC9E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC7E,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,2DAA2D,CAAC;QACxE,SAAS,EAAE,CAAC;aACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,kCAAkC,CAAC;KAChD,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;QAC1E,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAgB,CAAC,WAAW,CAAC;gBACrD,KAAK;gBACL,SAAS,EAAE,UAAU;gBACrB,OAAO,EAAE,QAAQ;gBACjB,WAAW;gBACX,QAAQ;gBACR,SAAS;aACV,CAAC,CAAC;YACH,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC,EAAE;iBACrF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -5,6 +5,7 @@ import type { IDocumentParser } from '../../application/ports/document-parser.js
|
|
|
5
5
|
import type { IEmbeddingService } from '../../application/ports/embedding-service.js';
|
|
6
6
|
import type { IStructuredExtractor } from '../../application/ports/structured-extractor.js';
|
|
7
7
|
import type { IExportService } from '../../application/ports/export-service.js';
|
|
8
|
+
import type { ICalendarService } from '../../application/ports/calendar-service.js';
|
|
8
9
|
import type { IJobPostingRepository } from '../../domain/repositories/job-posting-repository.js';
|
|
9
10
|
import type { IApplicationRepository } from '../../domain/repositories/application-repository.js';
|
|
10
11
|
import type { IApplicationEventRepository } from '../../domain/repositories/application-event-repository.js';
|
|
@@ -22,5 +23,6 @@ export interface Dependencies {
|
|
|
22
23
|
embeddingService: IEmbeddingService;
|
|
23
24
|
extractor: IStructuredExtractor;
|
|
24
25
|
exportService: IExportService;
|
|
26
|
+
calendarService?: ICalendarService;
|
|
25
27
|
}
|
|
26
28
|
export {};
|