matimo 0.1.0-alpha.1 → 0.1.0-alpha.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 (88) hide show
  1. package/README.md +83 -28
  2. package/dist/core/schema.d.ts +1 -1
  3. package/dist/core/schema.d.ts.map +1 -1
  4. package/dist/core/schema.js +8 -3
  5. package/dist/core/schema.js.map +1 -1
  6. package/dist/core/tool-loader.d.ts.map +1 -1
  7. package/dist/core/tool-loader.js +15 -4
  8. package/dist/core/tool-loader.js.map +1 -1
  9. package/dist/core/tool-registry.d.ts.map +1 -1
  10. package/dist/core/tool-registry.js +5 -1
  11. package/dist/core/tool-registry.js.map +1 -1
  12. package/dist/decorators/tool-decorator.d.ts.map +1 -1
  13. package/dist/decorators/tool-decorator.js +7 -4
  14. package/dist/decorators/tool-decorator.js.map +1 -1
  15. package/dist/encodings/parameter-encoding.d.ts.map +1 -1
  16. package/dist/encodings/parameter-encoding.js +9 -2
  17. package/dist/encodings/parameter-encoding.js.map +1 -1
  18. package/dist/executors/command-executor.d.ts.map +1 -1
  19. package/dist/executors/command-executor.js +5 -1
  20. package/dist/executors/command-executor.js.map +1 -1
  21. package/dist/executors/http-executor.d.ts.map +1 -1
  22. package/dist/executors/http-executor.js +5 -1
  23. package/dist/executors/http-executor.js.map +1 -1
  24. package/package.json +4 -4
  25. package/tools/calculator/calculator.ts +78 -0
  26. package/tools/calculator/definition.yaml +71 -0
  27. package/tools/echo-tool/definition.yaml +35 -0
  28. package/tools/examples/calculator.yaml +54 -0
  29. package/tools/examples/echo-tool.yaml +35 -0
  30. package/tools/examples/http-client.yaml +66 -0
  31. package/tools/github/definition.yaml +41 -0
  32. package/tools/gmail/README.md +1189 -0
  33. package/tools/gmail/create-draft/definition.yaml +99 -0
  34. package/tools/gmail/definition.yaml +49 -0
  35. package/tools/gmail/delete-message/definition.yaml +42 -0
  36. package/tools/gmail/get-message/definition.yaml +89 -0
  37. package/tools/gmail/list-messages/definition.yaml +84 -0
  38. package/tools/gmail/send-email/definition.yaml +95 -0
  39. package/tools/http-client/definition.yaml +73 -0
  40. package/tools/slack/README.md +200 -0
  41. package/tools/slack/assets/icon.svg +9 -0
  42. package/tools/slack/assets/logo-dark.svg +14 -0
  43. package/tools/slack/assets/logo-light.svg +14 -0
  44. package/tools/slack/assets/logo.svg +14 -0
  45. package/tools/slack/definition.yaml +54 -0
  46. package/tools/slack/get-user/definition.yaml +31 -0
  47. package/tools/slack/list-channels/definition.yaml +46 -0
  48. package/tools/slack/send-message/definition.yaml +30 -0
  49. package/tools/slack/slack_add_reaction/definition.yaml +45 -0
  50. package/tools/slack/slack_create_channel/definition.yaml +41 -0
  51. package/tools/slack/slack_get_channel_history/definition.yaml +58 -0
  52. package/tools/slack/slack_get_reactions/definition.yaml +36 -0
  53. package/tools/slack/slack_get_thread_replies/definition.yaml +45 -0
  54. package/tools/slack/slack_get_user_info/definition.yaml +32 -0
  55. package/tools/slack/slack_join_channel/definition.yaml +35 -0
  56. package/tools/slack/slack_reply_to_message/definition.yaml +49 -0
  57. package/tools/slack/slack_search_messages/definition.yaml +46 -0
  58. package/tools/slack/slack_send_channel_message/definition.yaml +34 -0
  59. package/tools/slack/slack_send_dm/definition.yaml +37 -0
  60. package/tools/slack/slack_set_channel_topic/definition.yaml +40 -0
  61. package/tools/slack/slack_upload_file/definition.yaml +152 -0
  62. package/docs/Gemfile +0 -5
  63. package/docs/RELEASES.md +0 -69
  64. package/docs/ROADMAP.md +0 -138
  65. package/docs/_config.yml +0 -27
  66. package/docs/api-reference/ERRORS.md +0 -445
  67. package/docs/api-reference/SDK.md +0 -582
  68. package/docs/api-reference/TYPES.md +0 -415
  69. package/docs/architecture/OAUTH.md +0 -1366
  70. package/docs/architecture/OVERVIEW.md +0 -564
  71. package/docs/assets/logo.png +0 -0
  72. package/docs/community/COMMIT_GUIDELINES.md +0 -552
  73. package/docs/framework-integrations/LANGCHAIN.md +0 -286
  74. package/docs/getting-started/QUICK_START.md +0 -211
  75. package/docs/getting-started/YOUR_FIRST_TOOL.md +0 -217
  76. package/docs/getting-started/installation.md +0 -124
  77. package/docs/index.md +0 -288
  78. package/docs/tool-development/DECORATOR_GUIDE.md +0 -633
  79. package/docs/tool-development/OAUTH_LINK.md +0 -5
  80. package/docs/tool-development/PROVIDER_CONFIGURATION.md +0 -458
  81. package/docs/tool-development/TESTING.md +0 -412
  82. package/docs/tool-development/TOOL_SPECIFICATION.md +0 -793
  83. package/docs/tool-development/YAML_TOOLS.md +0 -65
  84. package/docs/troubleshooting/FAQ.md +0 -391
  85. package/docs/user-guide/AUTHENTICATION.md +0 -255
  86. package/docs/user-guide/DEVELOPMENT_STANDARDS.md +0 -698
  87. package/docs/user-guide/SDK_PATTERNS.md +0 -316
  88. package/docs/user-guide/TOOL_DISCOVERY.md +0 -209
@@ -0,0 +1,1189 @@
1
+ # Matimo Gmail Tools Ecosystem
2
+
3
+ Complete guide to Gmail tools in Matimo: OAuth2 setup, YAML architecture, tool ecosystem, and integration patterns.
4
+
5
+ ## 📋 Table of Contents
6
+ - [Ecosystem Overview](#ecosystem-overview)
7
+ - [YAML-Based Tool Architecture](#yaml-based-tool-architecture)
8
+ - [Quick Start](#quick-start)
9
+ - [Available Tools](#available-tools)
10
+ - [Integration Patterns](#integration-patterns)
11
+ - [Advanced Usage](#advanced-usage)
12
+ - [Security & Best Practices](#security--best-practices)
13
+
14
+ ## Ecosystem Overview
15
+
16
+ ### What is the Gmail Tool Ecosystem?
17
+
18
+ The Gmail tools are part of Matimo's universal AI tools ecosystem. Unlike traditional libraries where each tool requires custom code, **Gmail tools are defined once in YAML and work everywhere**:
19
+
20
+ ```
21
+ ┌─────────────────────────────────────────────────────────────┐
22
+ │ YAML Tool Definition │
23
+ │ (tools/gmail/send-email/definition.yaml) │
24
+ │ - What the tool does │
25
+ │ - Input parameters & validation │
26
+ │ - Authentication requirements │
27
+ │ - Output schema │
28
+ │ - Execution configuration (command/HTTP) │
29
+ └─────────────────────────────────────────────────────────────┘
30
+
31
+ ┌───────────────────┴────────────────────┐
32
+ ↓ ↓
33
+ SDK API MCP Server (comming soon)
34
+ (JavaScript) (Claude)
35
+ ↓ ↓
36
+ - matimo.execute() - Claude can use
37
+ - LangChain tools natively
38
+ - CrewAI agents
39
+ - Custom code
40
+ ```
41
+
42
+ **Key Principle: Define Once, Use Everywhere**
43
+ - ✅ One YAML file per tool
44
+ - ✅ Works with any framework (LangChain, CrewAI, custom code)
45
+ - ✅ No code changes needed to add/modify tools
46
+ - ✅ Scales to 1000s of tools
47
+
48
+ ### Why YAML?
49
+
50
+ YAML keeps tool definitions **maintainable, readable, and contributor-friendly**:
51
+
52
+ ```yaml
53
+ # Human-readable
54
+ name: send-email
55
+ description: Send an email via Gmail
56
+
57
+ # Parameters clearly defined
58
+ parameters:
59
+ to:
60
+ type: string
61
+ description: Recipient email address
62
+ required: true
63
+ subject:
64
+ type: string
65
+ required: true
66
+ body:
67
+ type: string
68
+ required: true
69
+
70
+ # Auth declared once (used everywhere)
71
+ authentication:
72
+ type: oauth2
73
+ provider: google
74
+
75
+ # Execution details (HTTP call)
76
+ execution:
77
+ type: http
78
+ method: POST
79
+ url: https://www.googleapis.com/gmail/v1/users/me/messages/send
80
+ headers:
81
+ Authorization: "Bearer {GMAIL_ACCESS_TOKEN}"
82
+
83
+ # Output schema for validation
84
+ output_schema:
85
+ type: object
86
+ properties:
87
+ id:
88
+ type: string
89
+ description: Message ID
90
+ ```
91
+
92
+ ### How Matimo Uses YAML
93
+
94
+ 1. **Load & Parse** - YAML → Tool object
95
+ 2. **Validate** - Check parameters against schema
96
+ 3. **Execute** - Run HTTP request with auth
97
+ 4. **Transform** - Apply parameter encodings (MIME, base64, etc.)
98
+ 5. **Return** - Validate output against schema
99
+
100
+ This is what makes Matimo **framework-agnostic** and **scalable**.
101
+
102
+ ## YAML-Based Tool Architecture
103
+
104
+ ### File Structure
105
+
106
+ ```
107
+ tools/gmail/
108
+ ├── README.md # This file
109
+ ├── send-email/
110
+ │ ├── definition.yaml # Tool definition
111
+ ├── list-messages/
112
+ │ ├── definition.yaml
113
+ ├── create-draft/
114
+ │ ├── definition.yaml
115
+ ├── get-message/
116
+ │ ├── definition.yaml
117
+ └── delete-message/
118
+ ├── definition.yaml
119
+ ```
120
+
121
+ ### Anatomy of a Tool Definition (YAML)
122
+
123
+ Every tool has these sections:
124
+
125
+ #### 1. **Metadata**
126
+ ```yaml
127
+ name: send-email
128
+ version: "1.0.0"
129
+ description: Send an email via Gmail
130
+ tags: [email, gmail, messaging]
131
+ ```
132
+
133
+ #### 2. **Parameters** (Input Schema)
134
+ ```yaml
135
+ parameters:
136
+ to:
137
+ type: string
138
+ description: Recipient email address
139
+ required: true
140
+ example: "user@example.com"
141
+
142
+ subject:
143
+ type: string
144
+ required: true
145
+ example: "Hello World"
146
+
147
+ body:
148
+ type: string
149
+ required: true
150
+ example: "This is the email body"
151
+
152
+ cc:
153
+ type: string
154
+ required: false # Optional
155
+ example: "cc@example.com"
156
+
157
+ is_html:
158
+ type: boolean
159
+ required: false
160
+ default: false
161
+ ```
162
+
163
+ #### 3. **Authentication** (Credentials)
164
+ ```yaml
165
+ authentication:
166
+ type: oauth2 # How to authenticate
167
+ provider: google # Which service
168
+ scopes: # Permissions needed
169
+ - gmail.readonly # Read emails
170
+ - gmail.send # Send emails
171
+ - gmail.compose # Create drafts
172
+ ```
173
+
174
+ Matimo auto-injects tokens from environment:
175
+ ```typescript
176
+ // No explicit token passing - Matimo handles it!
177
+ await matimo.execute('gmail-send-email', {
178
+ to: 'user@example.com',
179
+ subject: 'Hello',
180
+ body: 'Message'
181
+ // GMAIL_ACCESS_TOKEN auto-added from process.env
182
+ });
183
+ ```
184
+
185
+ #### 4. **Execution** (How to run the tool)
186
+ ```yaml
187
+ execution:
188
+ type: http # Command or HTTP
189
+ method: POST # HTTP method
190
+ url: https://www.googleapis.com/... # API endpoint
191
+
192
+ headers:
193
+ Authorization: "Bearer {GMAIL_ACCESS_TOKEN}" # Auth header
194
+ Content-Type: application/json
195
+
196
+ body:
197
+ # Parameter encoding: Convert params to Gmail's format
198
+ # Gmail requires MIME message in base64url
199
+ message:
200
+ raw: "{raw}" # Special encoding directive
201
+ ```
202
+
203
+ #### 5. **Parameter Encoding** (Transformation)
204
+ ```yaml
205
+ parameter_encoding:
206
+ - source: [to, subject, body, cc, bcc, is_html]
207
+ target: raw
208
+ encoding: mime_rfc2822_base64url # Convert to MIME format
209
+ ```
210
+
211
+ This is how Matimo handles complex transformations:
212
+ - 🔄 **mime_rfc2822_base64url** - Encode email as MIME message
213
+ - 🔗 **url_encoded** - URL-encode form data
214
+ - 📦 **json_compact** - Minify JSON
215
+
216
+ #### 6. **Output Schema** (Result Validation)
217
+ ```yaml
218
+ output_schema:
219
+ type: object
220
+ properties:
221
+ id:
222
+ type: string
223
+ description: "Gmail message ID"
224
+ threadId:
225
+ type: string
226
+ description: "Thread ID for grouping conversations"
227
+ required: [id, threadId]
228
+ ```
229
+
230
+ ### Why This Architecture Matters
231
+
232
+ | Aspect | Benefit |
233
+ |--------|---------|
234
+ | **Declarative** | Tool behavior defined in human-readable YAML |
235
+ | **Validated** | Schema validation at load time + execution time |
236
+ | **Reusable** | Same YAML works with any framework (SDK, MCP, REST) |
237
+ | **Maintainable** | Update tool = edit YAML, no code changes needed |
238
+ | **Scalable** | Add 1000s of tools without changing core code |
239
+ | **Secure** | Auth tokens never in source code or YAML |
240
+ | **Transparent** | LLMs can see tool definitions and understand them |
241
+
242
+ ## Provider YAML Architecture
243
+
244
+ ### Why Provider YAML?
245
+
246
+ In addition to individual tool definitions, Matimo uses **Provider YAML** files to centralize OAuth2 configuration and shared settings across all tools for a single provider (in this case, Google).
247
+
248
+ ```
249
+ tools/gmail/
250
+ ├── definition.yaml # ← PROVIDER YAML (Google OAuth2 config)
251
+ │ All Gmail tools reference this
252
+ ├── send-email/
253
+ │ ├── definition.yaml # Individual tool definition
254
+ │ └── ...
255
+ ├── create-draft/
256
+ │ ├── definition.yaml
257
+ │ └── ...
258
+ └── list-messages/
259
+ ├── definition.yaml
260
+ └── ...
261
+ ```
262
+
263
+ ### Provider YAML: `tools/gmail/definition.yaml`
264
+
265
+ The provider-level YAML file serves multiple purposes:
266
+
267
+ **1. Centralize OAuth2 Configuration**
268
+ ```yaml
269
+ name: google-provider
270
+ type: provider
271
+
272
+ provider:
273
+ name: google
274
+ displayName: Google
275
+
276
+ # OAuth2 endpoints - used by all Google-dependent tools
277
+ endpoints:
278
+ authorizationUrl: https://accounts.google.com/o/oauth2/v2/auth
279
+ tokenUrl: https://oauth2.googleapis.com/token
280
+ revokeUrl: https://oauth2.googleapis.com/revoke
281
+ ```
282
+
283
+ **Benefits:**
284
+ - ✅ **Single source of truth** - All Gmail tools reference these endpoints
285
+ - ✅ **Override capability** - Users can change endpoints via environment variables
286
+ - ✅ **Extensibility** - Easy to add new Google-dependent tools
287
+ - ✅ **Maintainability** - If Google changes endpoints, update once
288
+
289
+ **2. Define Standard Scopes**
290
+
291
+ The provider file defines OAuth2 scopes required by Gmail tools:
292
+
293
+ ```yaml
294
+ # From definition.yaml
295
+ scopes:
296
+ - gmail.readonly # Read emails
297
+ - gmail.send # Send emails
298
+ - gmail.compose # Create drafts
299
+ - gmail.modify # Delete/modify emails
300
+ ```
301
+
302
+ Each individual tool declares which scopes it needs:
303
+
304
+ ```yaml
305
+ # In send-email/definition.yaml
306
+ authentication:
307
+ type: oauth2
308
+ provider: google
309
+ scopes:
310
+ - gmail.send # This tool needs to send emails
311
+ ```
312
+
313
+ **3. Configuration Override Pattern**
314
+
315
+ The provider YAML enables this priority system:
316
+
317
+ ```
318
+ Priority (High → Low):
319
+ 1. Runtime configuration (programmatic)
320
+ 2. Environment variables: OAUTH_GOOGLE_AUTH_URL, etc.
321
+ 3. Provider YAML: definition.yaml
322
+ ```
323
+
324
+ Example - Change endpoints for custom proxy:
325
+
326
+ ```bash
327
+ # Option A: Environment variable (highest priority)
328
+ export OAUTH_GOOGLE_AUTH_URL="https://my-proxy.example.com/auth"
329
+
330
+ # Option B: Edit definition.yaml (lowest priority)
331
+ # endpoints:
332
+ # authorizationUrl: https://my-proxy.example.com/auth
333
+ ```
334
+
335
+ ### How Tool Definition References Provider
336
+
337
+ Each individual tool declares its dependency on the provider:
338
+
339
+ **send-email/definition.yaml:**
340
+ ```yaml
341
+ name: gmail-send-email
342
+ version: '1.0.0'
343
+
344
+ authentication:
345
+ type: oauth2
346
+ provider: google # ← References the provider
347
+ scopes:
348
+ - gmail.send # Specific scopes for this tool
349
+ - gmail.compose
350
+
351
+ execution:
352
+ type: http
353
+ url: https://www.googleapis.com/gmail/v1/users/me/messages/send
354
+ headers:
355
+ # Uses GMAIL_ACCESS_TOKEN from provider's OAuth2 flow
356
+ Authorization: "Bearer {GMAIL_ACCESS_TOKEN}"
357
+ ```
358
+
359
+ **Matimo's Resolution:**
360
+ 1. Load tool: `gmail-send-email`
361
+ 2. Read `authentication.provider: google`
362
+ 3. Find provider YAML: `tools/gmail/definition.yaml`
363
+ 4. Load OAuth2 endpoints and scopes from provider
364
+ 5. Merge with tool-specific requirements
365
+ 6. Ready to execute!
366
+
367
+ ### Multi-Provider Scenario
368
+
369
+ When Matimo has tools from multiple providers, provider YAML keeps them isolated:
370
+
371
+ ```
372
+ tools/
373
+ ├── gmail/
374
+ │ ├── definition.yaml # ← Provider: Google
375
+ │ ├── send-email/
376
+ │ ├── create-draft/
377
+ │ └── list-messages/
378
+
379
+ ├── slack/
380
+ │ ├── definition.yaml # ← Provider: Slack
381
+ │ ├── send-message/
382
+ │ ├── post-channel/
383
+ │ └── get-users/
384
+
385
+ └── github/
386
+ ├── definition.yaml # ← Provider: GitHub
387
+ ├── create-issue/
388
+ ├── list-repos/
389
+ └── create-pr/
390
+ ```
391
+
392
+ Each provider has:
393
+ - ✅ Its own OAuth2 endpoints
394
+ - ✅ Its own scopes/permissions
395
+ - ✅ Its own credentials (CLIENT_ID, CLIENT_SECRET)
396
+ - ✅ Its own authentication flow
397
+
398
+ Matimo loads all providers and their tools - **no code changes needed**.
399
+
400
+ ### Why Not Hardcode in Code?
401
+
402
+ ❌ **Bad approach:**
403
+ ```typescript
404
+ // Tools/Gmail.ts - Code changes for each provider
405
+ if (provider === 'google') {
406
+ authUrl = 'https://accounts.google.com/...';
407
+ scopes = ['gmail.readonly', 'gmail.send'];
408
+ }
409
+ if (provider === 'slack') {
410
+ authUrl = 'https://slack.com/oauth...';
411
+ scopes = ['chat:write', 'users:read'];
412
+ }
413
+ ```
414
+
415
+ **Problems:**
416
+ - Non-technical contributors can't add providers
417
+ - Code must be modified for each provider
418
+ - Doesn't scale to 100s of providers
419
+ - Risk of bugs during refactoring
420
+
421
+ ✅ **Good approach (Matimo):**
422
+ ```yaml
423
+ # tools/gmail/definition.yaml
424
+ provider: google
425
+ endpoints:
426
+ authorizationUrl: https://accounts.google.com/...
427
+ scopes:
428
+ - gmail.readonly
429
+ - gmail.send
430
+ ```
431
+
432
+ **Benefits:**
433
+ - Maintainers submit YAML, not code
434
+ - Matimo loads all providers dynamically
435
+ - Scales to 1000s of providers
436
+ - Single deployment handles all tools
437
+ - Contributors can add providers without code knowledge
438
+
439
+ ### Real-World Example: Adding GitHub Tools
440
+
441
+ To add GitHub tools to Matimo:
442
+
443
+ **Step 1:** Create provider file:
444
+ ```bash
445
+ tools/github/definition.yaml
446
+ ```
447
+
448
+ **Step 2:** Define GitHub OAuth2 endpoints:
449
+ ```yaml
450
+ name: github-provider
451
+ type: provider
452
+ provider:
453
+ name: github
454
+ endpoints:
455
+ authorizationUrl: https://github.com/login/oauth/authorize
456
+ tokenUrl: https://github.com/login/oauth/access_token
457
+ ```
458
+
459
+ **Step 3:** Add tool definitions:
460
+ ```bash
461
+ tools/github/create-issue/definition.yaml
462
+ tools/github/list-repos/definition.yaml
463
+ tools/github/create-pr/definition.yaml
464
+ ```
465
+
466
+ **Step 4:** Each tool references provider:
467
+ ```yaml
468
+ # In create-issue/definition.yaml
469
+ authentication:
470
+ type: oauth2
471
+ provider: github # ← Links to github/definition.yaml
472
+ scopes:
473
+ - repo
474
+ - issues
475
+ ```
476
+
477
+ **Done!** No code changes needed. Matimo automatically:
478
+ - ✅ Loads the provider
479
+ - ✅ Loads all GitHub tools
480
+ - ✅ Sets up OAuth2 with GitHub endpoints
481
+ - ✅ Makes tools available to SDK, MCP, REST API
482
+
483
+ This is the **"Define Once, Use Everywhere"** principle in action!
484
+
485
+ ## Quick Start
486
+
487
+ Get started with Gmail tools in 5 minutes.
488
+
489
+ ### 1️⃣ Get OAuth Token (2 minutes)
490
+
491
+ #### Easiest: Google OAuth Playground
492
+
493
+ 1. **Visit** https://developers.google.com/oauthplayground
494
+ 2. **Configure** (⚙️ settings, top right):
495
+ - ☑️ Check "Use your own OAuth credentials"
496
+ - Enter **Client ID** (from [Google Cloud Console](https://console.cloud.google.com/apis/credentials))
497
+ - Enter **Client Secret**
498
+ 3. **Select Scopes** (left panel):
499
+ ```
500
+ https://www.googleapis.com/auth/gmail.readonly # Read emails
501
+ https://www.googleapis.com/auth/gmail.send # Send emails
502
+ https://www.googleapis.com/auth/gmail.compose # Create drafts
503
+ ```
504
+ 4. **Authorize & Copy Token**:
505
+ - Click "Authorize APIs"
506
+ - Grant permission
507
+ - Copy the **Access Token** (starts with `ya29.a0...`)
508
+
509
+ #### Production: Set Up Your Own OAuth App
510
+
511
+ 1. Go to https://console.cloud.google.com
512
+ 2. Create project: "My Gmail App"
513
+ 3. Enable **Gmail API**:
514
+ - Search "Gmail API"
515
+ - Click "Enable"
516
+ 4. Create **OAuth 2.0 Credentials**:
517
+ - Credentials → "Create Credentials" → "OAuth 2.0 Client ID"
518
+ - App type: **Desktop app** (testing) or **Web application** (production)
519
+ - Add redirect URIs:
520
+ ```
521
+ http://localhost:3000/callback
522
+ http://localhost:3000/auth/gmail/callback
523
+ ```
524
+ - Download JSON credentials
525
+
526
+ ### 2️⃣ Set Environment Variable (1 minute)
527
+
528
+ #### Option A: `.env` file (Recommended)
529
+ ```bash
530
+ # Create .env in your project root
531
+ cat > .env << EOF
532
+ GMAIL_ACCESS_TOKEN=ya29.a0AfH6SMBx...your-token...
533
+ EOF
534
+
535
+ # Add to .gitignore
536
+ echo ".env" >> .gitignore
537
+ ```
538
+
539
+ #### Option B: Export in shell
540
+ ```bash
541
+ export GMAIL_ACCESS_TOKEN="ya29.a0AfH6SMBx...your-token..."
542
+ ```
543
+
544
+ ### 3️⃣ Test It! (2 minutes)
545
+
546
+ ```bash
547
+ cd /Users/sajesh/My\ Work\ Directory/matimo/examples/tools
548
+
549
+ # Install dependencies
550
+ pnpm install
551
+
552
+ # Run factory pattern test
553
+ pnpm run gmail:factory --email:youremail@gmail.com
554
+ ```
555
+
556
+ **Expected output:**
557
+ ```
558
+ 📬 Example 1: List Your Recent Messages
559
+ ✅ Found 5 recent messages
560
+
561
+ 📧 Example 2: Send Email
562
+ ✅ Email sent successfully!
563
+
564
+ ✏️ Example 3: Create Draft
565
+ ✅ Draft created successfully!
566
+ ```
567
+
568
+ ## Available Tools
569
+
570
+ ### Overview
571
+
572
+ | Tool | Purpose | Input | Output |
573
+ |------|---------|-------|--------|
574
+ | `gmail-list-messages` | List emails from inbox | `maxResults`, `query`, `labelIds` | `messages[]` |
575
+ | `gmail-get-message` | Get full email details | `message_id`, `format` | `id`, `payload`, `headers` |
576
+ | `gmail-send-email` | Send email | `to`, `subject`, `body`, `cc`, `bcc` | `id` |
577
+ | `gmail-create-draft` | Create draft email | `to`, `subject`, `body`, `cc`, `bcc` | `id` |
578
+ | `gmail-delete-message` | Delete email | `message_id` | `success` |
579
+
580
+ ### Tool Reference
581
+
582
+ #### 1. gmail-list-messages
583
+
584
+ **Description:** List recent emails from your inbox with optional filtering.
585
+
586
+ **Parameters:**
587
+ ```typescript
588
+ {
589
+ query?: string; // Gmail search syntax
590
+ // Examples:
591
+ // "from:alice@example.com"
592
+ // "subject:meeting"
593
+ // "is:unread"
594
+ // "is:starred"
595
+ maxResults?: number; // 1-500 (default: 10)
596
+ pageToken?: string; // For pagination
597
+ labelIds?: string[]; // Filter by labels
598
+ // Common: ["INBOX", "SENT", "DRAFT"]
599
+ includeSpamTrash?: boolean; // Include spam/trash
600
+ }
601
+ ```
602
+
603
+ **Returns:**
604
+ ```typescript
605
+ {
606
+ messages: Array<{
607
+ id: string; // Gmail message ID
608
+ threadId: string; // For conversation grouping
609
+ snippet: string; // Email preview
610
+ }>,
611
+ resultSizeEstimate: number;
612
+ }
613
+ ```
614
+
615
+ **Example:**
616
+ ```typescript
617
+ const result = await matimo.execute('gmail-list-messages', {
618
+ maxResults: 5,
619
+ query: 'from:alice@example.com'
620
+ });
621
+ ```
622
+
623
+ ---
624
+
625
+ #### 2. gmail-send-email
626
+
627
+ **Description:** Send an email via Gmail.
628
+
629
+ **Parameters:**
630
+ ```typescript
631
+ {
632
+ to: string; // Required: Recipient email
633
+ subject: string; // Required: Email subject
634
+ body: string; // Required: Email body
635
+ cc?: string; // Optional: CC recipient(s)
636
+ bcc?: string; // Optional: BCC recipient(s)
637
+ is_html?: boolean; // Optional: HTML body (default: false)
638
+ }
639
+ ```
640
+
641
+ **Returns:**
642
+ ```typescript
643
+ {
644
+ id: string; // Sent message ID
645
+ threadId: string; // Thread ID
646
+ labelIds: string[]; // ["SENT"]
647
+ }
648
+ ```
649
+
650
+ **How It Works:**
651
+ 1. Matimo converts `to`, `subject`, `body` → MIME message
652
+ 2. Encodes as base64url (required by Gmail API)
653
+ 3. Sends via POST to Gmail API
654
+ 4. Returns message ID
655
+
656
+ **Example:**
657
+ ```typescript
658
+ const result = await matimo.execute('gmail-send-email', {
659
+ to: 'user@example.com',
660
+ subject: 'Hello from Matimo',
661
+ body: 'This email was sent via Gmail tools!',
662
+ is_html: false
663
+ });
664
+ ```
665
+
666
+ ---
667
+
668
+ #### 3. gmail-create-draft
669
+
670
+ **Description:** Create a draft email (not sent).
671
+
672
+ **Parameters:**
673
+ ```typescript
674
+ {
675
+ to: string; // Required: Draft recipient
676
+ subject: string; // Required: Draft subject
677
+ body: string; // Required: Draft body
678
+ cc?: string; // Optional: CC recipient(s)
679
+ bcc?: string; // Optional: BCC recipient(s)
680
+ is_html?: boolean; // Optional: HTML body (default: false)
681
+ }
682
+ ```
683
+
684
+ **Returns:**
685
+ ```typescript
686
+ {
687
+ id: string; // Draft ID
688
+ message: {
689
+ id: string;
690
+ threadId: string;
691
+ labelIds: string[]; // ["DRAFT"]
692
+ }
693
+ }
694
+ ```
695
+
696
+ **Use Case:** AI agents generating email content for review before sending.
697
+
698
+ **Example:**
699
+ ```typescript
700
+ const result = await matimo.execute('gmail-create-draft', {
701
+ to: 'user@example.com',
702
+ subject: 'Weekly Summary',
703
+ body: 'Generated by AI agent...',
704
+ is_html: true
705
+ });
706
+ // User can manually review and send from Gmail
707
+ ```
708
+
709
+ ---
710
+
711
+ #### 4. gmail-get-message
712
+
713
+ **Description:** Get full details of a specific email.
714
+
715
+ **Parameters:**
716
+ ```typescript
717
+ {
718
+ message_id: string; // Required: Email ID (from list-messages)
719
+ format?: string; // Optional: "minimal" | "full" | "raw"
720
+ // Default: "full"
721
+ }
722
+ ```
723
+
724
+ **Returns:**
725
+ ```typescript
726
+ {
727
+ id: string;
728
+ threadId: string;
729
+ labelIds: string[];
730
+ snippet: string;
731
+ payload: {
732
+ mimeType: string;
733
+ headers: Array<{
734
+ name: string; // "Subject", "From", etc.
735
+ value: string;
736
+ }>,
737
+ parts?: Array<...>; // Email parts (attachments, etc.)
738
+ body: {
739
+ size: number;
740
+ data?: string; // Base64 encoded body (if format=full)
741
+ }
742
+ }
743
+ }
744
+ ```
745
+
746
+ **Example:**
747
+ ```typescript
748
+ const result = await matimo.execute('gmail-get-message', {
749
+ message_id: '18b8f4a2a1c5e3d2',
750
+ format: 'full'
751
+ });
752
+ ```
753
+
754
+ ---
755
+
756
+ #### 5. gmail-delete-message
757
+
758
+ **Description:** Delete an email (moves to trash).
759
+
760
+ **Parameters:**
761
+ ```typescript
762
+ {
763
+ message_id: string; // Required: Email ID to delete
764
+ }
765
+ ```
766
+
767
+ **Returns:**
768
+ ```typescript
769
+ {
770
+ success: boolean;
771
+ message_id: string;
772
+ }
773
+ ```
774
+
775
+ **Example:**
776
+ ```typescript
777
+ const result = await matimo.execute('gmail-delete-message', {
778
+ message_id: '18b8f4a2a1c5e3d2'
779
+ });
780
+ ```
781
+
782
+ ## Integration Patterns
783
+
784
+ ### Pattern 1: Factory Pattern (Direct SDK)
785
+
786
+ Use when you have explicit parameters:
787
+
788
+ ```typescript
789
+ import { MatimoInstance } from 'matimo';
790
+ import path from 'path';
791
+
792
+ const matimo = await MatimoInstance.init(path.join(__dirname, 'tools'));
793
+
794
+ // Tool executes, token auto-injected from GMAIL_ACCESS_TOKEN env var
795
+ const result = await matimo.execute('gmail-send-email', {
796
+ to: 'user@example.com',
797
+ subject: 'Hello',
798
+ body: 'Message'
799
+ });
800
+ ```
801
+
802
+ **When to use:** Scripts, cron jobs, simple automation
803
+
804
+ ---
805
+
806
+ ### Pattern 2: Decorator Pattern (LangChain Decorators)
807
+
808
+ Use when building agent frameworks:
809
+
810
+ ```typescript
811
+ import { tool } from 'langchain';
812
+
813
+ class EmailAgent {
814
+ @tool('gmail-send-email')
815
+ async sendEmail(to: string, subject: string, body: string) {
816
+ return undefined; // Matimo intercepts and executes
817
+ }
818
+ }
819
+ ```
820
+
821
+ **When to use:** Framework integration, reusable agents
822
+
823
+ ---
824
+
825
+ ### Pattern 3: AI Agent Pattern (OpenAI + LangChain)
826
+
827
+ Use when you want LLM to decide which tool to use:
828
+
829
+ ```typescript
830
+ import { createAgent } from 'langchain';
831
+ import { ChatOpenAI } from '@langchain/openai';
832
+
833
+ const agent = await createAgent({
834
+ model: new ChatOpenAI({ modelName: 'gpt-4o-mini' }),
835
+ tools: gmailTools,
836
+ });
837
+
838
+ // Natural language request
839
+ await agent.invoke({
840
+ messages: [{
841
+ role: 'user',
842
+ content: 'Send me a test email'
843
+ }]
844
+ });
845
+ // Agent decides which tool to use and calls it!
846
+ ```
847
+
848
+ **When to use:** Autonomous agents, natural language interfaces
849
+
850
+ ---
851
+
852
+ ## Advanced Usage
853
+
854
+ ### Gmail Search Query Syntax
855
+
856
+ Use powerful Gmail search in `list-messages`:
857
+
858
+ ```typescript
859
+ // Single condition
860
+ await matimo.execute('gmail-list-messages', {
861
+ query: 'from:alice@example.com',
862
+ maxResults: 10
863
+ });
864
+
865
+ // Multiple conditions
866
+ await matimo.execute('gmail-list-messages', {
867
+ query: 'from:alice@example.com subject:meeting is:unread',
868
+ maxResults: 10
869
+ });
870
+ ```
871
+
872
+ **Common search operators:**
873
+ ```
874
+ from:alice@example.com # From specific sender
875
+ to:bob@example.com # To specific recipient
876
+ subject:meeting # Keywords in subject
877
+ body:coffee # Keywords in body
878
+ has:attachment # Has attachments
879
+ is:unread # Unread emails
880
+ is:starred # Starred emails
881
+ is:important # Marked important
882
+ label:work # With specific label
883
+ before:2024/01/01 # Before date
884
+ after:2023/12/01 # After date
885
+ filename:pdf # Specific attachment type
886
+ ```
887
+
888
+ ---
889
+
890
+ ### Pagination
891
+
892
+ For large email lists, use pagination:
893
+
894
+ ```typescript
895
+ let pageToken: string | undefined = undefined;
896
+ let allMessages = [];
897
+
898
+ while (true) {
899
+ const result = await matimo.execute('gmail-list-messages', {
900
+ maxResults: 100,
901
+ pageToken: pageToken
902
+ });
903
+
904
+ allMessages = allMessages.concat(result.messages);
905
+
906
+ if (!result.nextPageToken) break;
907
+ pageToken = result.nextPageToken;
908
+ }
909
+
910
+ console.log(`Total messages: ${allMessages.length}`);
911
+ ```
912
+
913
+ ---
914
+
915
+ ### HTML Emails
916
+
917
+ Send formatted HTML emails:
918
+
919
+ ```typescript
920
+ await matimo.execute('gmail-send-email', {
921
+ to: 'user@example.com',
922
+ subject: 'HTML Email Example',
923
+ body: `
924
+ <h1>Hello!</h1>
925
+ <p>This is an <strong>HTML</strong> email.</p>
926
+ <a href="https://example.com">Click here</a>
927
+ `,
928
+ is_html: true // Enable HTML parsing
929
+ });
930
+ ```
931
+
932
+ ---
933
+
934
+ ### Multiple Recipients
935
+
936
+ Send to CC/BCC recipients:
937
+
938
+ ```typescript
939
+ await matimo.execute('gmail-send-email', {
940
+ to: 'primary@example.com',
941
+ cc: 'cc1@example.com,cc2@example.com', // Comma-separated
942
+ bcc: 'bcc@example.com',
943
+ subject: 'Team Update',
944
+ body: 'Status update for the team'
945
+ });
946
+ ```
947
+
948
+ ---
949
+
950
+ ### How Parameter Encoding Works
951
+
952
+ Gmail requires emails in MIME format (base64url). Matimo handles this automatically via YAML:
953
+
954
+ **Your code:**
955
+ ```typescript
956
+ await matimo.execute('gmail-send-email', {
957
+ to: 'user@example.com',
958
+ subject: 'Hello',
959
+ body: 'Message'
960
+ });
961
+ ```
962
+
963
+ **What Matimo does:**
964
+ ```
965
+ 1. Read parameters: to, subject, body
966
+ 2. Build MIME message:
967
+ From: <your-account>
968
+ To: user@example.com
969
+ Subject: Hello
970
+
971
+ Message
972
+
973
+ 3. Encode as base64url (required by Gmail API)
974
+ 4. Send as: POST /send with {message: {raw: "base64string"}}
975
+ ```
976
+
977
+ **This is defined in YAML:**
978
+ ```yaml
979
+ parameter_encoding:
980
+ - source: [to, subject, body, cc, bcc, is_html]
981
+ target: raw
982
+ encoding: mime_rfc2822_base64url # Handles all the above
983
+ ```
984
+
985
+ ---
986
+
987
+ ## Security & Best Practices
988
+
989
+ ### "Missing GMAIL_ACCESS_TOKEN"
990
+
991
+ **Problem:** Error when trying to use Gmail tools without token.
992
+
993
+ **Solution:**
994
+ ```bash
995
+ # Check if environment variable is set
996
+ echo $GMAIL_ACCESS_TOKEN
997
+
998
+ # Set it if missing
999
+ export GMAIL_ACCESS_TOKEN=ya29.a0AfH6SMBx...
1000
+ ```
1001
+
1002
+ ### "Invalid Credentials (401)"
1003
+
1004
+ **Problem:** Gmail API returns 401 Unauthorized.
1005
+
1006
+ **Possible causes:**
1007
+ 1. Token is expired (access tokens expire after ~1 hour)
1008
+ 2. Token has wrong scopes
1009
+ 3. Token is for wrong Google account
1010
+ 4. Application not authorized in Google Cloud
1011
+
1012
+ **Solution:**
1013
+ 1. Get a fresh token (especially if > 1 hour old)
1014
+ 2. Check scopes match your app's needs
1015
+ 3. Re-authenticate with the correct account
1016
+ 4. Verify app is authorized in Google Cloud Console
1017
+
1018
+ ### "Permission Denied (403)"
1019
+
1020
+ **Problem:** Gmail API returns 403 Forbidden.
1021
+
1022
+ **Possible causes:**
1023
+ 1. Token missing required scope
1024
+ 2. Trying to access another user's mailbox
1025
+ 3. Gmail API not enabled in Cloud project
1026
+ 4. Rate limit exceeded
1027
+
1028
+ **Solution:**
1029
+ 1. Add required scopes when getting token
1030
+ 2. Ensure token is for the account you're accessing
1031
+ 3. Enable Gmail API in Cloud Console
1032
+ 4. Wait before retrying (rate limited)
1033
+
1034
+ ### "Invalid Token Format"
1035
+
1036
+ **Problem:** Error when passing token parameter.
1037
+
1038
+ **Solution:**
1039
+ Ensure token is a string and properly passed:
1040
+ ```typescript
1041
+ // ✅ Correct
1042
+ GMAIL_ACCESS_TOKEN: process.env.GMAIL_ACCESS_TOKEN
1043
+
1044
+ // ❌ Wrong
1045
+ GMAIL_ACCESS_TOKEN: undefined // Missing env var
1046
+ GMAIL_ACCESS_TOKEN: { token: 'ya29...' } // Object instead of string
1047
+ ```
1048
+
1049
+ ## Security Best Practices
1050
+
1051
+ ### ✅ DO
1052
+
1053
+ - Store tokens in environment variables
1054
+ - Use `.env` files locally (not in git)
1055
+ - Rotate tokens regularly
1056
+ - Use minimum required scopes
1057
+ - Implement server-side token refresh (Phase 3)
1058
+ - Log token refresh events
1059
+ - Monitor token usage for suspicious activity
1060
+
1061
+ ### ❌ DON'T
1062
+
1063
+ - Hardcode tokens in source files
1064
+ - Commit `.env` files to git
1065
+ - Share tokens between users
1066
+ - Use full account access when limited scope available
1067
+ - Log full tokens (log truncated: `ya29.a0...`)
1068
+ - Expose tokens in error messages
1069
+ - Store tokens in localStorage (browser)
1070
+ - Use same token for multiple apps
1071
+
1072
+ ## Troubleshooting
1073
+
1074
+ # Use in script
1075
+ pnpm exec ts-node examples/gmail-oauth-usage.ts
1076
+
1077
+ # Or use in Node REPL
1078
+ node
1079
+ > process.env.GMAIL_ACCESS_TOKEN
1080
+ > // Use in matimo.execute()
1081
+ ```
1082
+
1083
+ ## API Reference
1084
+
1085
+ ### send-email
1086
+
1087
+ Sends an email via Gmail API.
1088
+
1089
+ **Parameters:**
1090
+ - `to` (required): Recipient email(s), comma-separated
1091
+ - `subject` (required): Email subject
1092
+ - `body` (required): Email body (plain text or HTML)
1093
+ - `cc` (optional): CC recipients
1094
+ - `bcc` (optional): BCC recipients
1095
+ - `is_html` (optional): Treat body as HTML (default: false)
1096
+ - `GMAIL_ACCESS_TOKEN` (required): OAuth access token
1097
+
1098
+ **Response:**
1099
+ ```typescript
1100
+ {
1101
+ id: string; // Message ID
1102
+ threadId: string; // Thread ID
1103
+ labelIds: string[]; // Applied labels
1104
+ }
1105
+ ```
1106
+
1107
+ ### list-messages
1108
+
1109
+ Lists emails from your mailbox.
1110
+
1111
+ **Parameters:**
1112
+ - `query` (optional): Search query (e.g., "from:user@example.com")
1113
+ - `maxResults` (optional): Max messages to return (1-500)
1114
+ - `pageToken` (optional): Token for pagination
1115
+ - `labelIds` (optional): Filter by label IDs
1116
+ - `includeSpamTrash` (optional): Include spam/trash
1117
+ - `GMAIL_ACCESS_TOKEN` (required): OAuth access token
1118
+
1119
+ **Response:**
1120
+ ```typescript
1121
+ {
1122
+ messages: Array<{ id: string; threadId: string }>;
1123
+ nextPageToken?: string; // For pagination
1124
+ resultSizeEstimate: number;
1125
+ }
1126
+ ```
1127
+
1128
+ ### get-message
1129
+
1130
+ Gets a specific message with full details.
1131
+
1132
+ **Parameters:**
1133
+ - `message_id` (required): Message ID to retrieve
1134
+ - `format` (optional): Response format ("minimal" | "full" | "raw")
1135
+ - `GMAIL_ACCESS_TOKEN` (required): OAuth access token
1136
+
1137
+ **Response:**
1138
+ ```typescript
1139
+ {
1140
+ id: string;
1141
+ threadId: string;
1142
+ headers: Record<string, string>;
1143
+ body: { data?: string };
1144
+ attachments?: any[];
1145
+ }
1146
+ ```
1147
+
1148
+ ### create-draft
1149
+
1150
+ Creates a draft email.
1151
+
1152
+ **Parameters:**
1153
+ - `to` (required): Draft recipient
1154
+ - `subject` (required): Draft subject
1155
+ - `body` (required): Draft body
1156
+ - `cc` (optional): CC recipients
1157
+ - `bcc` (optional): BCC recipients
1158
+ - `is_html` (optional): Treat body as HTML
1159
+ - `GMAIL_ACCESS_TOKEN` (required): OAuth access token
1160
+
1161
+ **Response:**
1162
+ ```typescript
1163
+ {
1164
+ id: string; // Draft ID
1165
+ }
1166
+ ```
1167
+
1168
+ ### delete-message
1169
+
1170
+ Permanently deletes a message.
1171
+
1172
+ **Parameters:**
1173
+ - `message_id` (required): Message ID to delete
1174
+ - `GMAIL_ACCESS_TOKEN` (required): OAuth access token
1175
+
1176
+ **Response:**
1177
+ ```typescript
1178
+ {
1179
+ success: boolean;
1180
+ }
1181
+ ```
1182
+
1183
+ ## Additional Resources
1184
+
1185
+ - [Gmail API Documentation](https://developers.google.com/gmail/api)
1186
+ - [Gmail API Authentication Guide](https://developers.google.com/gmail/api/auth/about-auth)
1187
+ - [OAuth 2.0 Playground](https://developers.google.com/oauthplayground)
1188
+ - [Google Cloud Console](https://console.cloud.google.com/)
1189
+ - [Matimo Documentation](../../README.md)