@seven.io/mcp 1.0.3

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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +129 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/client.d.ts +18 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +88 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +245 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/oauth/flow.d.ts +12 -0
  16. package/dist/oauth/flow.d.ts.map +1 -0
  17. package/dist/oauth/flow.js +132 -0
  18. package/dist/oauth/flow.js.map +1 -0
  19. package/dist/oauth/pkce.d.ts +17 -0
  20. package/dist/oauth/pkce.d.ts.map +1 -0
  21. package/dist/oauth/pkce.js +39 -0
  22. package/dist/oauth/pkce.js.map +1 -0
  23. package/dist/oauth/refresh.d.ts +22 -0
  24. package/dist/oauth/refresh.d.ts.map +1 -0
  25. package/dist/oauth/refresh.js +53 -0
  26. package/dist/oauth/refresh.js.map +1 -0
  27. package/dist/oauth/server.d.ts +18 -0
  28. package/dist/oauth/server.d.ts.map +1 -0
  29. package/dist/oauth/server.js +553 -0
  30. package/dist/oauth/server.js.map +1 -0
  31. package/dist/oauth/tokens.d.ts +33 -0
  32. package/dist/oauth/tokens.d.ts.map +1 -0
  33. package/dist/oauth/tokens.js +104 -0
  34. package/dist/oauth/tokens.js.map +1 -0
  35. package/dist/tools/account.d.ts +68 -0
  36. package/dist/tools/account.d.ts.map +1 -0
  37. package/dist/tools/account.js +59 -0
  38. package/dist/tools/account.js.map +1 -0
  39. package/dist/tools/contacts.d.ts +101 -0
  40. package/dist/tools/contacts.d.ts.map +1 -0
  41. package/dist/tools/contacts.js +111 -0
  42. package/dist/tools/contacts.js.map +1 -0
  43. package/dist/tools/groups.d.ts +65 -0
  44. package/dist/tools/groups.d.ts.map +1 -0
  45. package/dist/tools/groups.js +86 -0
  46. package/dist/tools/groups.js.map +1 -0
  47. package/dist/tools/lookup.d.ts +22 -0
  48. package/dist/tools/lookup.d.ts.map +1 -0
  49. package/dist/tools/lookup.js +88 -0
  50. package/dist/tools/lookup.js.map +1 -0
  51. package/dist/tools/numbers.d.ts +79 -0
  52. package/dist/tools/numbers.d.ts.map +1 -0
  53. package/dist/tools/numbers.js +106 -0
  54. package/dist/tools/numbers.js.map +1 -0
  55. package/dist/tools/rcs.d.ts +100 -0
  56. package/dist/tools/rcs.d.ts.map +1 -0
  57. package/dist/tools/rcs.js +86 -0
  58. package/dist/tools/rcs.js.map +1 -0
  59. package/dist/tools/sender.d.ts +25 -0
  60. package/dist/tools/sender.d.ts.map +1 -0
  61. package/dist/tools/sender.js +25 -0
  62. package/dist/tools/sender.js.map +1 -0
  63. package/dist/tools/sms.d.ts +110 -0
  64. package/dist/tools/sms.d.ts.map +1 -0
  65. package/dist/tools/sms.js +95 -0
  66. package/dist/tools/sms.js.map +1 -0
  67. package/dist/tools/status.d.ts +81 -0
  68. package/dist/tools/status.d.ts.map +1 -0
  69. package/dist/tools/status.js +88 -0
  70. package/dist/tools/status.js.map +1 -0
  71. package/dist/tools/subaccounts.d.ts +108 -0
  72. package/dist/tools/subaccounts.d.ts.map +1 -0
  73. package/dist/tools/subaccounts.js +98 -0
  74. package/dist/tools/subaccounts.js.map +1 -0
  75. package/dist/tools/voice.d.ts +57 -0
  76. package/dist/tools/voice.d.ts.map +1 -0
  77. package/dist/tools/voice.js +54 -0
  78. package/dist/tools/voice.js.map +1 -0
  79. package/dist/tools/webhooks.d.ts +60 -0
  80. package/dist/tools/webhooks.d.ts.map +1 -0
  81. package/dist/tools/webhooks.js +58 -0
  82. package/dist/tools/webhooks.js.map +1 -0
  83. package/dist/types.d.ts +69 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +2 -0
  86. package/dist/types.js.map +1 -0
  87. package/package.json +49 -0
package/dist/index.js ADDED
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { SevenClient } from './client.js';
6
+ import * as fs from 'fs';
7
+ // Import all tool definitions and handlers
8
+ import { rcsTools, sendRCS, deleteRCS, rcsEvents } from './tools/rcs.js';
9
+ import { smsTools, sendSMS, deleteSMS } from './tools/sms.js';
10
+ import { voiceTools, sendVoice, hangupVoice } from './tools/voice.js';
11
+ import { accountTools, getBalance, getPricing, getAnalytics } from './tools/account.js';
12
+ import { lookupTools, lookupFormat, lookupRCS, lookupHLR, lookupMNP, lookupCNAM } from './tools/lookup.js';
13
+ import { statusTools, getStatus, getLogbookSent, getLogbookReceived, getLogbookVoice } from './tools/status.js';
14
+ import { numbersTools, getAvailableNumbers, orderNumber, getActiveNumbers, getNumber, updateNumber, deleteNumber } from './tools/numbers.js';
15
+ import { contactsTools, listContacts, createContact, getContact, updateContact, deleteContact } from './tools/contacts.js';
16
+ import { groupsTools, listGroups, createGroup, getGroup, updateGroup, deleteGroup } from './tools/groups.js';
17
+ import { subaccountsTools, listSubaccounts, createSubaccount, updateSubaccount, transferCredits, deleteSubaccount } from './tools/subaccounts.js';
18
+ import { webhooksTools, listWebhooks, createWebhook, deleteWebhook } from './tools/webhooks.js';
19
+ import { senderTools, validateSender } from './tools/sender.js';
20
+ const API_KEY = process.env.SEVEN_API_KEY;
21
+ const CLIENT_ID = 'seven-mcp'; // Static OAuth client ID
22
+ const LOG_FILE = process.env.SEVEN_LOG_FILE;
23
+ // API key is optional when OAuth is available
24
+ if (!API_KEY && !CLIENT_ID) {
25
+ throw new Error('Authentication configuration error');
26
+ }
27
+ // Debug logging helper - only logs if SEVEN_LOG_FILE is set
28
+ function debugLog(message, data) {
29
+ if (LOG_FILE) {
30
+ const timestamp = new Date().toISOString();
31
+ const logEntry = `[${timestamp}] ${message}${data ? ': ' + JSON.stringify(data) : ''}\n`;
32
+ fs.appendFileSync(LOG_FILE, logEntry);
33
+ }
34
+ }
35
+ const client = new SevenClient({
36
+ apiKey: API_KEY,
37
+ clientId: CLIENT_ID
38
+ });
39
+ const server = new Server({
40
+ name: 'mcp-seven',
41
+ version: '1.0.0',
42
+ }, {
43
+ capabilities: {
44
+ tools: {},
45
+ },
46
+ });
47
+ // Combine all tools
48
+ const allTools = [
49
+ ...rcsTools,
50
+ ...smsTools,
51
+ ...voiceTools,
52
+ ...accountTools,
53
+ ...lookupTools,
54
+ ...statusTools,
55
+ ...numbersTools,
56
+ ...contactsTools,
57
+ ...groupsTools,
58
+ ...subaccountsTools,
59
+ ...webhooksTools,
60
+ ...senderTools,
61
+ ];
62
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
63
+ tools: allTools,
64
+ }));
65
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
66
+ try {
67
+ const { name, arguments: args = {} } = request.params;
68
+ // Log incoming request
69
+ debugLog(`Tool request: ${name}`, args);
70
+ let result;
71
+ switch (name) {
72
+ // RCS tools
73
+ case 'send_rcs':
74
+ result = await sendRCS(client, args);
75
+ break;
76
+ case 'delete_rcs':
77
+ result = await deleteRCS(client, args.id);
78
+ break;
79
+ case 'rcs_events':
80
+ result = await rcsEvents(client, args.event_data);
81
+ break;
82
+ // SMS tools
83
+ case 'send_sms':
84
+ result = await sendSMS(client, args);
85
+ break;
86
+ case 'delete_sms':
87
+ result = await deleteSMS(client, args.ids);
88
+ break;
89
+ // Voice tools
90
+ case 'send_voice':
91
+ if (!args.to || !args.text) {
92
+ throw new Error('send_voice requires "to" and "text" parameters');
93
+ }
94
+ result = await sendVoice(client, args);
95
+ break;
96
+ case 'hangup_voice':
97
+ result = await hangupVoice(client, args.call_id);
98
+ break;
99
+ // Account tools
100
+ case 'get_balance':
101
+ result = await getBalance(client);
102
+ break;
103
+ case 'get_pricing':
104
+ result = await getPricing(client, args);
105
+ break;
106
+ case 'get_analytics':
107
+ result = await getAnalytics(client, args);
108
+ break;
109
+ // Lookup tools
110
+ case 'lookup_format':
111
+ result = await lookupFormat(client, args);
112
+ break;
113
+ case 'lookup_rcs':
114
+ result = await lookupRCS(client, args);
115
+ break;
116
+ case 'lookup_hlr':
117
+ result = await lookupHLR(client, args);
118
+ break;
119
+ case 'lookup_mnp':
120
+ result = await lookupMNP(client, args);
121
+ break;
122
+ case 'lookup_cnam':
123
+ result = await lookupCNAM(client, args);
124
+ break;
125
+ // Status & Logbook tools
126
+ case 'get_status':
127
+ result = await getStatus(client, args);
128
+ break;
129
+ case 'get_logbook_sent':
130
+ result = await getLogbookSent(client, args);
131
+ break;
132
+ case 'get_logbook_received':
133
+ result = await getLogbookReceived(client, args);
134
+ break;
135
+ case 'get_logbook_voice':
136
+ result = await getLogbookVoice(client, args);
137
+ break;
138
+ // Numbers tools
139
+ case 'get_available_numbers':
140
+ result = await getAvailableNumbers(client, args);
141
+ break;
142
+ case 'order_number':
143
+ result = await orderNumber(client, args);
144
+ break;
145
+ case 'get_active_numbers':
146
+ result = await getActiveNumbers(client);
147
+ break;
148
+ case 'get_number':
149
+ result = await getNumber(client, args.number);
150
+ break;
151
+ case 'update_number':
152
+ result = await updateNumber(client, args.number, args.config);
153
+ break;
154
+ case 'delete_number':
155
+ result = await deleteNumber(client, args.number);
156
+ break;
157
+ // Contacts tools
158
+ case 'list_contacts':
159
+ result = await listContacts(client);
160
+ break;
161
+ case 'create_contact':
162
+ result = await createContact(client, args);
163
+ break;
164
+ case 'get_contact':
165
+ result = await getContact(client, args.id);
166
+ break;
167
+ case 'update_contact':
168
+ const { id: contactId, ...contactParams } = args;
169
+ result = await updateContact(client, contactId, contactParams);
170
+ break;
171
+ case 'delete_contact':
172
+ result = await deleteContact(client, args.id);
173
+ break;
174
+ // Groups tools
175
+ case 'list_groups':
176
+ result = await listGroups(client);
177
+ break;
178
+ case 'create_group':
179
+ result = await createGroup(client, args);
180
+ break;
181
+ case 'get_group':
182
+ result = await getGroup(client, args.id);
183
+ break;
184
+ case 'update_group':
185
+ const { id: groupId, ...groupParams } = args;
186
+ result = await updateGroup(client, groupId, groupParams);
187
+ break;
188
+ case 'delete_group':
189
+ result = await deleteGroup(client, args.id);
190
+ break;
191
+ // Subaccounts tools
192
+ case 'list_subaccounts':
193
+ result = await listSubaccounts(client);
194
+ break;
195
+ case 'create_subaccount':
196
+ result = await createSubaccount(client, args);
197
+ break;
198
+ case 'update_subaccount':
199
+ result = await updateSubaccount(client, args);
200
+ break;
201
+ case 'transfer_credits':
202
+ result = await transferCredits(client, args);
203
+ break;
204
+ case 'delete_subaccount':
205
+ result = await deleteSubaccount(client, args.id);
206
+ break;
207
+ // Webhooks tools
208
+ case 'list_webhooks':
209
+ result = await listWebhooks(client);
210
+ break;
211
+ case 'create_webhook':
212
+ result = await createWebhook(client, args);
213
+ break;
214
+ case 'delete_webhook':
215
+ result = await deleteWebhook(client, args.id);
216
+ break;
217
+ // Sender tools
218
+ case 'validate_sender':
219
+ result = await validateSender(client, args);
220
+ break;
221
+ default:
222
+ throw new Error(`Unknown tool: ${name}`);
223
+ }
224
+ // Log response and return
225
+ debugLog(`Tool response: ${name}`, result);
226
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
227
+ }
228
+ catch (error) {
229
+ debugLog(`Tool error: ${request.params.name}`, { error: error.message });
230
+ return {
231
+ content: [{ type: 'text', text: `Error: ${error.message}` }],
232
+ isError: true,
233
+ };
234
+ }
235
+ });
236
+ async function main() {
237
+ const transport = new StdioServerTransport();
238
+ await server.connect(transport);
239
+ console.error('Seven.io MCP Server running on stdio');
240
+ }
241
+ main().catch((error) => {
242
+ console.error('Fatal error:', error);
243
+ process.exit(1);
244
+ });
245
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { OAuthTokens } from './tokens.js';
2
+ export interface OAuthConfig {
3
+ clientId: string;
4
+ scope?: string;
5
+ }
6
+ /**
7
+ * Perform complete OAuth 2.0 authorization code flow with PKCE
8
+ * @param config - OAuth configuration
9
+ * @returns OAuth tokens
10
+ */
11
+ export declare function performOAuthFlow(config: OAuthConfig): Promise<OAuthTokens>;
12
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,WAAW,EAAE,MAAM,aAAa,CAAC;AAMvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiCD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CA0DhF"}
@@ -0,0 +1,132 @@
1
+ import axios from 'axios';
2
+ import open from 'open';
3
+ import readline from 'readline';
4
+ import { generateCodeVerifier, generateCodeChallenge, generateState } from './pkce.js';
5
+ import { startCallbackServer, findAvailablePort } from './server.js';
6
+ import { storeTokens } from './tokens.js';
7
+ const AUTHORIZE_ENDPOINT = 'https://oauth.seven.io/authorize';
8
+ const TOKEN_ENDPOINT = 'https://oauth.seven.io/token';
9
+ const ME_ENDPOINT = 'https://oauth.seven.io/me';
10
+ /**
11
+ * Wait for user to press ENTER
12
+ */
13
+ async function waitForEnter() {
14
+ const rl = readline.createInterface({
15
+ input: process.stdin,
16
+ output: process.stdout
17
+ });
18
+ return new Promise((resolve) => {
19
+ rl.question('Press ENTER to open your browser for authentication...', () => {
20
+ rl.close();
21
+ resolve();
22
+ });
23
+ });
24
+ }
25
+ /**
26
+ * Perform complete OAuth 2.0 authorization code flow with PKCE
27
+ * @param config - OAuth configuration
28
+ * @returns OAuth tokens
29
+ */
30
+ export async function performOAuthFlow(config) {
31
+ // Generate PKCE parameters
32
+ const codeVerifier = generateCodeVerifier();
33
+ const codeChallenge = generateCodeChallenge(codeVerifier);
34
+ const state = generateState();
35
+ console.log('\n🔐 Starting OAuth authentication flow...');
36
+ // Find an available port from the configured OAuth ports (7177, 9437, 8659)
37
+ const port = await findAvailablePort();
38
+ console.log(`📡 Starting callback server on port ${port}...`);
39
+ // Start the callback server on the available port
40
+ const callbackPromise = startCallbackServer(port, state);
41
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
42
+ // Build authorization URL
43
+ const authUrl = new URL(AUTHORIZE_ENDPOINT);
44
+ authUrl.searchParams.set('response_type', 'code');
45
+ authUrl.searchParams.set('client_id', config.clientId);
46
+ authUrl.searchParams.set('redirect_uri', redirectUri);
47
+ authUrl.searchParams.set('code_challenge', codeChallenge);
48
+ authUrl.searchParams.set('code_challenge_method', 'S256');
49
+ authUrl.searchParams.set('state', state);
50
+ if (config.scope) {
51
+ authUrl.searchParams.set('scope', config.scope);
52
+ }
53
+ // Wait for user confirmation
54
+ await waitForEnter();
55
+ console.log('🌐 Opening browser for authentication...');
56
+ await open(authUrl.toString());
57
+ console.log('⏳ Waiting for authorization (complete login in your browser)...');
58
+ // Wait for callback
59
+ const { code } = await callbackPromise;
60
+ console.log('✅ Authorization received!');
61
+ console.log('🔄 Exchanging authorization code for tokens...');
62
+ // Exchange authorization code for tokens
63
+ const tokens = await exchangeCodeForTokens(config.clientId, code, codeVerifier, redirectUri);
64
+ console.log('👤 Fetching user information...');
65
+ // Fetch user info to get account details
66
+ const userInfo = await fetchUserInfo(tokens.access_token);
67
+ console.log(`✨ Authenticated as: ${userInfo.email || userInfo.user_id}`);
68
+ // Store tokens securely with user-specific account
69
+ await storeTokens(tokens, userInfo.email || userInfo.user_id);
70
+ return tokens;
71
+ }
72
+ /**
73
+ * Fetch user information using the access token
74
+ * @param accessToken - OAuth access token
75
+ * @returns User information
76
+ */
77
+ async function fetchUserInfo(accessToken) {
78
+ try {
79
+ const response = await axios.get(ME_ENDPOINT, {
80
+ headers: {
81
+ 'Authorization': `Bearer ${accessToken}`,
82
+ },
83
+ });
84
+ return response.data;
85
+ }
86
+ catch (error) {
87
+ // Return a default user if /me endpoint fails
88
+ return {
89
+ user_id: 'default',
90
+ email: 'oauth-user',
91
+ };
92
+ }
93
+ }
94
+ /**
95
+ * Exchange authorization code for access token using PKCE
96
+ * @param clientId - OAuth client ID
97
+ * @param code - Authorization code from callback
98
+ * @param codeVerifier - PKCE code verifier
99
+ * @param redirectUri - The redirect URI used in the authorization request
100
+ * @returns OAuth tokens
101
+ */
102
+ async function exchangeCodeForTokens(clientId, code, codeVerifier, redirectUri) {
103
+ try {
104
+ const params = {
105
+ grant_type: 'authorization_code',
106
+ client_id: clientId,
107
+ code: code,
108
+ redirect_uri: redirectUri,
109
+ code_verifier: codeVerifier,
110
+ };
111
+ const response = await axios.post(TOKEN_ENDPOINT, new URLSearchParams(params).toString(), {
112
+ headers: {
113
+ 'Content-Type': 'application/x-www-form-urlencoded',
114
+ },
115
+ });
116
+ const expiresAt = Math.floor(Date.now() / 1000) + response.data.expires_in;
117
+ return {
118
+ access_token: response.data.access_token,
119
+ refresh_token: response.data.refresh_token,
120
+ expires_at: expiresAt,
121
+ token_type: response.data.token_type,
122
+ scope: response.data.scope,
123
+ };
124
+ }
125
+ catch (error) {
126
+ if (error.response) {
127
+ throw new Error(`Failed to exchange code for tokens: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
128
+ }
129
+ throw new Error(`Failed to exchange code for tokens: ${error.message}`);
130
+ }
131
+ }
132
+ //# sourceMappingURL=flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Generate a cryptographically random code verifier for PKCE
3
+ * @returns Base64URL-encoded random string (43-128 characters)
4
+ */
5
+ export declare function generateCodeVerifier(): string;
6
+ /**
7
+ * Generate code challenge from code verifier using SHA256
8
+ * @param verifier - The code verifier to hash
9
+ * @returns Base64URL-encoded SHA256 hash of the verifier
10
+ */
11
+ export declare function generateCodeChallenge(verifier: string): string;
12
+ /**
13
+ * Generate a cryptographically random state parameter
14
+ * @returns Random state string for CSRF protection
15
+ */
16
+ export declare function generateState(): string;
17
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/oauth/pkce.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAGtC"}
@@ -0,0 +1,39 @@
1
+ import crypto from 'crypto';
2
+ /**
3
+ * Generate a cryptographically random code verifier for PKCE
4
+ * @returns Base64URL-encoded random string (43-128 characters)
5
+ */
6
+ export function generateCodeVerifier() {
7
+ const buffer = crypto.randomBytes(32);
8
+ return base64URLEncode(buffer);
9
+ }
10
+ /**
11
+ * Generate code challenge from code verifier using SHA256
12
+ * @param verifier - The code verifier to hash
13
+ * @returns Base64URL-encoded SHA256 hash of the verifier
14
+ */
15
+ export function generateCodeChallenge(verifier) {
16
+ const hash = crypto.createHash('sha256').update(verifier).digest();
17
+ return base64URLEncode(hash);
18
+ }
19
+ /**
20
+ * Generate a cryptographically random state parameter
21
+ * @returns Random state string for CSRF protection
22
+ */
23
+ export function generateState() {
24
+ const buffer = crypto.randomBytes(16);
25
+ return base64URLEncode(buffer);
26
+ }
27
+ /**
28
+ * Base64URL encode a buffer (URL-safe base64 without padding)
29
+ * @param buffer - Buffer to encode
30
+ * @returns Base64URL-encoded string
31
+ */
32
+ function base64URLEncode(buffer) {
33
+ return buffer
34
+ .toString('base64')
35
+ .replace(/\+/g, '-')
36
+ .replace(/\//g, '_')
37
+ .replace(/=/g, '');
38
+ }
39
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/oauth/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;IACnE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO,MAAM;SACV,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { OAuthTokens } from './tokens.js';
2
+ export interface RefreshTokenResponse {
3
+ access_token: string;
4
+ expires_in: number;
5
+ refresh_token: string;
6
+ token_type: string;
7
+ scope?: string;
8
+ }
9
+ /**
10
+ * Refresh OAuth access token using refresh token
11
+ * @param clientId - OAuth client ID
12
+ * @param refreshToken - Current refresh token
13
+ * @returns New OAuth tokens
14
+ */
15
+ export declare function refreshAccessToken(clientId: string, refreshToken: string): Promise<OAuthTokens>;
16
+ /**
17
+ * Get valid access token, refreshing if necessary
18
+ * @param clientId - OAuth client ID
19
+ * @returns Valid access token
20
+ */
21
+ export declare function getValidAccessToken(clientId: string): Promise<string>;
22
+ //# sourceMappingURL=refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/oauth/refresh.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAA0C,MAAM,aAAa,CAAC;AAIlF,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,CAiCtB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa3E"}
@@ -0,0 +1,53 @@
1
+ import axios from 'axios';
2
+ import { storeTokens, getTokens, isTokenExpired } from './tokens.js';
3
+ const TOKEN_ENDPOINT = 'https://oauth.seven.io/token';
4
+ /**
5
+ * Refresh OAuth access token using refresh token
6
+ * @param clientId - OAuth client ID
7
+ * @param refreshToken - Current refresh token
8
+ * @returns New OAuth tokens
9
+ */
10
+ export async function refreshAccessToken(clientId, refreshToken) {
11
+ try {
12
+ const response = await axios.post(TOKEN_ENDPOINT, new URLSearchParams({
13
+ grant_type: 'refresh_token',
14
+ client_id: clientId,
15
+ refresh_token: refreshToken,
16
+ }).toString(), {
17
+ headers: {
18
+ 'Content-Type': 'application/x-www-form-urlencoded',
19
+ },
20
+ });
21
+ const expiresAt = Math.floor(Date.now() / 1000) + response.data.expires_in;
22
+ const newTokens = {
23
+ access_token: response.data.access_token,
24
+ refresh_token: response.data.refresh_token,
25
+ expires_at: expiresAt,
26
+ token_type: response.data.token_type,
27
+ scope: response.data.scope,
28
+ };
29
+ // Store new tokens
30
+ await storeTokens(newTokens);
31
+ return newTokens;
32
+ }
33
+ catch (error) {
34
+ throw new Error(`Failed to refresh access token: ${error.message}`);
35
+ }
36
+ }
37
+ /**
38
+ * Get valid access token, refreshing if necessary
39
+ * @param clientId - OAuth client ID
40
+ * @returns Valid access token
41
+ */
42
+ export async function getValidAccessToken(clientId) {
43
+ let tokens = await getTokens();
44
+ if (!tokens) {
45
+ throw new Error('No OAuth tokens found. Please run: npx seven-mcp login');
46
+ }
47
+ // Refresh if expired or expiring soon
48
+ if (isTokenExpired(tokens)) {
49
+ tokens = await refreshAccessToken(clientId, tokens.refresh_token);
50
+ }
51
+ return tokens.access_token;
52
+ }
53
+ //# sourceMappingURL=refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/oauth/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAe,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElF,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAUtD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAAgB,EAChB,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,cAAc,EACd,IAAI,eAAe,CAAC;YAClB,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;SAC5B,CAAC,CAAC,QAAQ,EAAE,EACb;YACE,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;aACpD;SACF,CACF,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;QAE3E,MAAM,SAAS,GAAgB;YAC7B,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,YAAY;YACxC,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,aAAa;YAC1C,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU;YACpC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK;SAC3B,CAAC;QAEF,mBAAmB;QACnB,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC;QAE7B,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,IAAI,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IAE/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,sCAAsC;IACtC,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,MAAM,CAAC,YAAY,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface CallbackResult {
2
+ code: string;
3
+ state: string;
4
+ }
5
+ export declare const OAUTH_PORTS: number[];
6
+ /**
7
+ * Start a temporary HTTP server to receive OAuth callback
8
+ * @param port - Port to listen on (default: 7177)
9
+ * @param expectedState - Expected state parameter for CSRF protection
10
+ * @returns Promise that resolves with authorization code when callback is received
11
+ */
12
+ export declare function startCallbackServer(port: number | undefined, expectedState: string): Promise<CallbackResult>;
13
+ /**
14
+ * Find an available port from the OAuth ports list
15
+ * @returns The first available port
16
+ */
17
+ export declare function findAvailablePort(): Promise<number>;
18
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/oauth/server.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAID,eAAO,MAAM,WAAW,UAAqB,CAAC;AAE9C;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,YAAO,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC,CAwgBzB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAwBzD"}