@wolpertingerlabs/drawlatch 1.0.0-alpha.1

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 (95) hide show
  1. package/CONNECTIONS.md +197 -0
  2. package/INGESTORS.md +790 -0
  3. package/LICENSE +21 -0
  4. package/README.md +685 -0
  5. package/dist/cli/generate-keys.d.ts +15 -0
  6. package/dist/cli/generate-keys.js +107 -0
  7. package/dist/connections/anthropic.json +16 -0
  8. package/dist/connections/bluesky.json +26 -0
  9. package/dist/connections/devin.json +15 -0
  10. package/dist/connections/discord-bot.json +24 -0
  11. package/dist/connections/discord-oauth.json +16 -0
  12. package/dist/connections/github.json +25 -0
  13. package/dist/connections/google-ai.json +15 -0
  14. package/dist/connections/google.json +28 -0
  15. package/dist/connections/hex.json +14 -0
  16. package/dist/connections/lichess.json +15 -0
  17. package/dist/connections/linear.json +29 -0
  18. package/dist/connections/mastodon.json +25 -0
  19. package/dist/connections/notion.json +33 -0
  20. package/dist/connections/openai.json +16 -0
  21. package/dist/connections/openrouter.json +16 -0
  22. package/dist/connections/reddit.json +28 -0
  23. package/dist/connections/slack.json +23 -0
  24. package/dist/connections/stripe.json +25 -0
  25. package/dist/connections/telegram.json +26 -0
  26. package/dist/connections/trello.json +25 -0
  27. package/dist/connections/twitch.json +28 -0
  28. package/dist/connections/x.json +27 -0
  29. package/dist/mcp/server.d.ts +13 -0
  30. package/dist/mcp/server.js +258 -0
  31. package/dist/remote/ingestors/base-ingestor.d.ts +65 -0
  32. package/dist/remote/ingestors/base-ingestor.js +132 -0
  33. package/dist/remote/ingestors/discord/discord-gateway.d.ts +58 -0
  34. package/dist/remote/ingestors/discord/discord-gateway.js +341 -0
  35. package/dist/remote/ingestors/discord/index.d.ts +3 -0
  36. package/dist/remote/ingestors/discord/index.js +3 -0
  37. package/dist/remote/ingestors/discord/types.d.ts +56 -0
  38. package/dist/remote/ingestors/discord/types.js +68 -0
  39. package/dist/remote/ingestors/index.d.ts +16 -0
  40. package/dist/remote/ingestors/index.js +20 -0
  41. package/dist/remote/ingestors/manager.d.ts +65 -0
  42. package/dist/remote/ingestors/manager.js +201 -0
  43. package/dist/remote/ingestors/poll/index.d.ts +2 -0
  44. package/dist/remote/ingestors/poll/index.js +2 -0
  45. package/dist/remote/ingestors/poll/poll-ingestor.d.ts +78 -0
  46. package/dist/remote/ingestors/poll/poll-ingestor.js +283 -0
  47. package/dist/remote/ingestors/registry.d.ts +32 -0
  48. package/dist/remote/ingestors/registry.js +46 -0
  49. package/dist/remote/ingestors/ring-buffer.d.ts +33 -0
  50. package/dist/remote/ingestors/ring-buffer.js +62 -0
  51. package/dist/remote/ingestors/slack/index.d.ts +3 -0
  52. package/dist/remote/ingestors/slack/index.js +3 -0
  53. package/dist/remote/ingestors/slack/socket-mode.d.ts +48 -0
  54. package/dist/remote/ingestors/slack/socket-mode.js +267 -0
  55. package/dist/remote/ingestors/slack/types.d.ts +70 -0
  56. package/dist/remote/ingestors/slack/types.js +72 -0
  57. package/dist/remote/ingestors/types.d.ts +138 -0
  58. package/dist/remote/ingestors/types.js +13 -0
  59. package/dist/remote/ingestors/webhook/base-webhook-ingestor.d.ts +112 -0
  60. package/dist/remote/ingestors/webhook/base-webhook-ingestor.js +119 -0
  61. package/dist/remote/ingestors/webhook/github-types.d.ts +45 -0
  62. package/dist/remote/ingestors/webhook/github-types.js +65 -0
  63. package/dist/remote/ingestors/webhook/github-webhook-ingestor.d.ts +43 -0
  64. package/dist/remote/ingestors/webhook/github-webhook-ingestor.js +86 -0
  65. package/dist/remote/ingestors/webhook/index.d.ts +8 -0
  66. package/dist/remote/ingestors/webhook/index.js +12 -0
  67. package/dist/remote/ingestors/webhook/stripe-types.d.ts +57 -0
  68. package/dist/remote/ingestors/webhook/stripe-types.js +108 -0
  69. package/dist/remote/ingestors/webhook/stripe-webhook-ingestor.d.ts +47 -0
  70. package/dist/remote/ingestors/webhook/stripe-webhook-ingestor.js +90 -0
  71. package/dist/remote/ingestors/webhook/trello-types.d.ts +90 -0
  72. package/dist/remote/ingestors/webhook/trello-types.js +81 -0
  73. package/dist/remote/ingestors/webhook/trello-webhook-ingestor.d.ts +60 -0
  74. package/dist/remote/ingestors/webhook/trello-webhook-ingestor.js +126 -0
  75. package/dist/remote/server.d.ts +103 -0
  76. package/dist/remote/server.js +536 -0
  77. package/dist/shared/config.d.ts +213 -0
  78. package/dist/shared/config.js +269 -0
  79. package/dist/shared/connections.d.ts +72 -0
  80. package/dist/shared/connections.js +103 -0
  81. package/dist/shared/crypto/channel.d.ts +95 -0
  82. package/dist/shared/crypto/channel.js +175 -0
  83. package/dist/shared/crypto/index.d.ts +3 -0
  84. package/dist/shared/crypto/index.js +3 -0
  85. package/dist/shared/crypto/keys.d.ts +92 -0
  86. package/dist/shared/crypto/keys.js +143 -0
  87. package/dist/shared/logger.d.ts +30 -0
  88. package/dist/shared/logger.js +74 -0
  89. package/dist/shared/protocol/handshake.d.ts +116 -0
  90. package/dist/shared/protocol/handshake.js +214 -0
  91. package/dist/shared/protocol/index.d.ts +3 -0
  92. package/dist/shared/protocol/index.js +2 -0
  93. package/dist/shared/protocol/messages.d.ts +46 -0
  94. package/dist/shared/protocol/messages.js +8 -0
  95. package/package.json +105 -0
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Key generation CLI.
4
+ *
5
+ * Generates Ed25519 (signing) + X25519 (key exchange) keypairs for either
6
+ * the local MCP proxy or the remote server, and saves them with correct
7
+ * file permissions (0600 for private keys, 0644 for public keys).
8
+ *
9
+ * Usage:
10
+ * npx tsx src/cli/generate-keys.ts local # Generate MCP proxy keys
11
+ * npx tsx src/cli/generate-keys.ts remote # Generate remote server keys
12
+ * npx tsx src/cli/generate-keys.ts --dir /path/to/keys # Custom directory
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=generate-keys.d.ts.map
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Key generation CLI.
4
+ *
5
+ * Generates Ed25519 (signing) + X25519 (key exchange) keypairs for either
6
+ * the local MCP proxy or the remote server, and saves them with correct
7
+ * file permissions (0600 for private keys, 0644 for public keys).
8
+ *
9
+ * Usage:
10
+ * npx tsx src/cli/generate-keys.ts local # Generate MCP proxy keys
11
+ * npx tsx src/cli/generate-keys.ts remote # Generate remote server keys
12
+ * npx tsx src/cli/generate-keys.ts --dir /path/to/keys # Custom directory
13
+ */
14
+ import { generateKeyBundle, saveKeyBundle, loadKeyBundle, fingerprint, extractPublicKeys, } from '../shared/crypto/index.js';
15
+ import { getLocalKeysDir, getRemoteKeysDir, getConfigDir } from '../shared/config.js';
16
+ import fs from 'node:fs';
17
+ import path from 'node:path';
18
+ function usage() {
19
+ console.log(`
20
+ Drawlatch key generation
21
+
22
+ Usage:
23
+ generate-keys local [alias] Generate MCP proxy (local) keypair
24
+ Alias defaults to "default" if omitted.
25
+ Keys are stored in keys/local/<alias>/
26
+ generate-keys remote Generate remote server keypair
27
+ generate-keys --dir <path> Generate keypair in a custom directory
28
+ generate-keys show <path> Show fingerprint of an existing keypair
29
+
30
+ Keys are saved as PEM files:
31
+ <dir>/signing.pub.pem Ed25519 public key (safe to share)
32
+ <dir>/signing.key.pem Ed25519 private key (keep secret!)
33
+ <dir>/exchange.pub.pem X25519 public key (safe to share)
34
+ <dir>/exchange.key.pem X25519 private key (keep secret!)
35
+ `);
36
+ }
37
+ function generateAndSave(targetDir, label) {
38
+ // Check if keys already exist
39
+ if (fs.existsSync(path.join(targetDir, 'signing.key.pem'))) {
40
+ console.error(`\n⚠️ Keys already exist in ${targetDir}`);
41
+ console.error(' Delete them first if you want to regenerate.');
42
+ const existing = loadKeyBundle(targetDir);
43
+ const fp = fingerprint(extractPublicKeys(existing));
44
+ console.log(`\n Existing fingerprint: ${fp}\n`);
45
+ process.exit(1);
46
+ }
47
+ console.log(`\nGenerating ${label} keypair...`);
48
+ const bundle = generateKeyBundle();
49
+ saveKeyBundle(bundle, targetDir);
50
+ const pub = extractPublicKeys(bundle);
51
+ const fp = fingerprint(pub);
52
+ console.log(`\n✓ Keys saved to: ${targetDir}`);
53
+ console.log(` Fingerprint: ${fp}`);
54
+ console.log(`\n Files:`);
55
+ console.log(` ${path.join(targetDir, 'signing.pub.pem')} (public, share this)`);
56
+ console.log(` ${path.join(targetDir, 'signing.key.pem')} (PRIVATE, protect this)`);
57
+ console.log(` ${path.join(targetDir, 'exchange.pub.pem')} (public, share this)`);
58
+ console.log(` ${path.join(targetDir, 'exchange.key.pem')} (PRIVATE, protect this)`);
59
+ console.log('');
60
+ }
61
+ function showFingerprint(dir) {
62
+ const bundle = loadKeyBundle(dir);
63
+ const pub = extractPublicKeys(bundle);
64
+ console.log(`Fingerprint: ${fingerprint(pub)}`);
65
+ }
66
+ // ── Main ───────────────────────────────────────────────────────────────────
67
+ const args = process.argv.slice(2);
68
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
69
+ usage();
70
+ process.exit(0);
71
+ }
72
+ // Ensure base config directory exists
73
+ fs.mkdirSync(getConfigDir(), { recursive: true, mode: 0o700 });
74
+ if (args[0] === 'local') {
75
+ const alias = args[1] && !args[1].startsWith('-') ? args[1] : 'default';
76
+ const localKeysDir = getLocalKeysDir();
77
+ const targetDir = path.join(localKeysDir, alias);
78
+ // Check for legacy flat key layout (PEM files directly in keys/local/)
79
+ const legacyKeyPath = path.join(localKeysDir, 'signing.key.pem');
80
+ if (fs.existsSync(legacyKeyPath)) {
81
+ console.error(`\n⚠️ Legacy key layout detected: PEM files found directly in ${localKeysDir}\n` +
82
+ ` Local keys are now stored per-alias: keys/local/<alias>/\n` +
83
+ ` To migrate, move your existing keys:\n\n` +
84
+ ` mkdir -p ${targetDir}\n` +
85
+ ` mv ${localKeysDir}/signing.* ${targetDir}/\n` +
86
+ ` mv ${localKeysDir}/exchange.* ${targetDir}/\n\n` +
87
+ ` Then update localKeysDir in your proxy.config.json to point to:\n` +
88
+ ` ${targetDir}\n`);
89
+ process.exit(1);
90
+ }
91
+ generateAndSave(targetDir, `MCP proxy (local) — alias "${alias}"`);
92
+ }
93
+ else if (args[0] === 'remote') {
94
+ generateAndSave(getRemoteKeysDir(), 'remote server');
95
+ }
96
+ else if (args[0] === '--dir' && args[1]) {
97
+ generateAndSave(args[1], 'custom');
98
+ }
99
+ else if (args[0] === 'show' && args[1]) {
100
+ showFingerprint(args[1]);
101
+ }
102
+ else {
103
+ console.error(`Unknown argument: ${args[0]}`);
104
+ usage();
105
+ process.exit(1);
106
+ }
107
+ //# sourceMappingURL=generate-keys.js.map
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "Anthropic API",
3
+ "description": "Anthropic Claude API — messages, models, and more. Auth is handled automatically via the ANTHROPIC_API_KEY environment variable. Uses x-api-key header (not Bearer token). The anthropic-version header is set to 2023-06-01.",
4
+ "docsUrl": "https://docs.anthropic.com/en/api",
5
+ "headers": {
6
+ "x-api-key": "${ANTHROPIC_API_KEY}",
7
+ "anthropic-version": "2023-06-01",
8
+ "Content-Type": "application/json"
9
+ },
10
+ "secrets": {
11
+ "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://api.anthropic.com/**"
15
+ ]
16
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "Bluesky API (AT Protocol)",
3
+ "description": "Bluesky API via the AT Protocol — posts, feeds, profiles, notifications, social graph, and more. Auth is handled automatically via the BLUESKY_ACCESS_TOKEN environment variable (JWT Bearer token). Obtain a token by POSTing to com.atproto.server.createSession with your handle and an App Password. Tokens expire after ~2 hours — rotate externally using the refresh token. Both bsky.social (authenticated PDS) and public.api.bsky.app (public read-only API) are allowlisted. For self-hosted PDS instances, override with a custom connector. Includes a poll ingestor that fetches notifications — use poll_events to retrieve them.",
4
+ "docsUrl": "https://docs.bsky.app/",
5
+ "headers": {
6
+ "Authorization": "Bearer ${BLUESKY_ACCESS_TOKEN}"
7
+ },
8
+ "secrets": {
9
+ "BLUESKY_ACCESS_TOKEN": "${BLUESKY_ACCESS_TOKEN}"
10
+ },
11
+ "allowedEndpoints": [
12
+ "https://bsky.social/xrpc/**",
13
+ "https://public.api.bsky.app/xrpc/**"
14
+ ],
15
+ "ingestor": {
16
+ "type": "poll",
17
+ "poll": {
18
+ "url": "https://bsky.social/xrpc/app.bsky.notification.listNotifications?limit=25",
19
+ "intervalMs": 60000,
20
+ "method": "GET",
21
+ "responsePath": "notifications",
22
+ "deduplicateBy": "uri",
23
+ "eventType": "notification"
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "Devin API",
3
+ "description": "Devin AI API — sessions, knowledge, and machine management. Auth is handled automatically via the DEVIN_API_KEY environment variable.",
4
+ "docsUrl": "https://docs.devin.ai/api-reference/overview",
5
+ "headers": {
6
+ "Authorization": "Bearer ${DEVIN_API_KEY}",
7
+ "Content-Type": "application/json"
8
+ },
9
+ "secrets": {
10
+ "DEVIN_API_KEY": "${DEVIN_API_KEY}"
11
+ },
12
+ "allowedEndpoints": [
13
+ "https://api.devin.ai/**"
14
+ ]
15
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "Discord Bot API",
3
+ "description": "Discord Bot API (v10) — guilds, channels, messages, users, roles, and more. Auth is handled automatically via the DISCORD_BOT_TOKEN environment variable. Uses the 'Bot' authorization prefix. For OAuth2 user-scoped access, use the 'discord-oauth' connection instead. Includes a Gateway ingestor for real-time events (messages, reactions, etc.) — use poll_events to retrieve them.",
4
+ "docsUrl": "https://discord.com/developers/docs/intro",
5
+ "openApiUrl": "https://raw.githubusercontent.com/discord/discord-api-spec/main/specs/openapi.json",
6
+ "headers": {
7
+ "Authorization": "Bot ${DISCORD_BOT_TOKEN}",
8
+ "Content-Type": "application/json"
9
+ },
10
+ "secrets": {
11
+ "DISCORD_BOT_TOKEN": "${DISCORD_BOT_TOKEN}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://discord.com/api/v10/**"
15
+ ],
16
+ "ingestor": {
17
+ "type": "websocket",
18
+ "websocket": {
19
+ "gatewayUrl": "wss://gateway.discord.gg/?v=10&encoding=json",
20
+ "protocol": "discord",
21
+ "intents": 3276799
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "Discord OAuth2 API",
3
+ "description": "Discord OAuth2 API (v10) — user identity, guilds, connections, and other user-scoped data. Auth is handled automatically via the DISCORD_OAUTH_TOKEN environment variable (OAuth2 Bearer access token). Access is limited to the scopes the user authorized. For full bot access, use the 'discord-bot' connection instead.",
4
+ "docsUrl": "https://discord.com/developers/docs/topics/oauth2",
5
+ "openApiUrl": "https://raw.githubusercontent.com/discord/discord-api-spec/main/specs/openapi.json",
6
+ "headers": {
7
+ "Authorization": "Bearer ${DISCORD_OAUTH_TOKEN}",
8
+ "Content-Type": "application/json"
9
+ },
10
+ "secrets": {
11
+ "DISCORD_OAUTH_TOKEN": "${DISCORD_OAUTH_TOKEN}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://discord.com/api/v10/**"
15
+ ]
16
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "GitHub API",
3
+ "description": "GitHub REST API — repositories, issues, pull requests, users, organizations, and more. Auth is handled automatically via the GITHUB_TOKEN environment variable. Includes a webhook ingestor for real-time events (push, pull_request, issues, etc.) — set GITHUB_WEBHOOK_SECRET and use poll_events to retrieve them.",
4
+ "docsUrl": "https://docs.github.com/en/rest",
5
+ "openApiUrl": "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json",
6
+ "headers": {
7
+ "Authorization": "Bearer ${GITHUB_TOKEN}",
8
+ "Accept": "application/vnd.github+json",
9
+ "X-GitHub-Api-Version": "2022-11-28",
10
+ "User-Agent": "drawlatch"
11
+ },
12
+ "secrets": {
13
+ "GITHUB_TOKEN": "${GITHUB_TOKEN}",
14
+ "GITHUB_WEBHOOK_SECRET": "${GITHUB_WEBHOOK_SECRET}"
15
+ },
16
+ "allowedEndpoints": ["https://api.github.com/**"],
17
+ "ingestor": {
18
+ "type": "webhook",
19
+ "webhook": {
20
+ "path": "github",
21
+ "signatureHeader": "X-Hub-Signature-256",
22
+ "signatureSecret": "GITHUB_WEBHOOK_SECRET"
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "Google AI (Gemini) API",
3
+ "description": "Google AI Gemini API — chat completions, embeddings, image generation, token counting, and more. Auth is handled automatically via the GOOGLE_AI_API_KEY environment variable. Uses x-goog-api-key header (not Bearer token). This is separate from the 'google' connection which covers Google Workspace APIs (Sheets, Drive, etc.).",
4
+ "docsUrl": "https://ai.google.dev/api",
5
+ "headers": {
6
+ "x-goog-api-key": "${GOOGLE_AI_API_KEY}",
7
+ "Content-Type": "application/json"
8
+ },
9
+ "secrets": {
10
+ "GOOGLE_AI_API_KEY": "${GOOGLE_AI_API_KEY}"
11
+ },
12
+ "allowedEndpoints": [
13
+ "https://generativelanguage.googleapis.com/**"
14
+ ]
15
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "Google APIs",
3
+ "description": "Google APIs — Sheets, Docs, Drive, Calendar, Gmail, and more. Auth is handled automatically via the GOOGLE_API_TOKEN environment variable (OAuth2 access token or service account token). Multiple Google API domains are allowlisted.",
4
+ "docsUrl": "https://developers.google.com/apis-explorer",
5
+ "headers": {
6
+ "Authorization": "Bearer ${GOOGLE_API_TOKEN}"
7
+ },
8
+ "secrets": {
9
+ "GOOGLE_API_TOKEN": "${GOOGLE_API_TOKEN}"
10
+ },
11
+ "allowedEndpoints": [
12
+ "https://www.googleapis.com/**",
13
+ "https://sheets.googleapis.com/**",
14
+ "https://docs.googleapis.com/**",
15
+ "https://drive.googleapis.com/**",
16
+ "https://calendar-json.googleapis.com/**",
17
+ "https://gmail.googleapis.com/**",
18
+ "https://slides.googleapis.com/**",
19
+ "https://people.googleapis.com/**",
20
+ "https://tasks.googleapis.com/**",
21
+ "https://admin.googleapis.com/**",
22
+ "https://chat.googleapis.com/**",
23
+ "https://forms.googleapis.com/**",
24
+ "https://youtube.googleapis.com/**",
25
+ "https://youtubeanalytics.googleapis.com/**",
26
+ "https://cloudresourcemanager.googleapis.com/**"
27
+ ]
28
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "Hex API",
3
+ "description": "Hex API — projects, runs, users, groups, collections, and data connections. Auth is handled automatically via the HEX_TOKEN environment variable.",
4
+ "docsUrl": "https://learn.hex.tech/docs/api/api-overview",
5
+ "headers": {
6
+ "Authorization": "Bearer ${HEX_TOKEN}"
7
+ },
8
+ "secrets": {
9
+ "HEX_TOKEN": "${HEX_TOKEN}"
10
+ },
11
+ "allowedEndpoints": [
12
+ "https://app.hex.tech/api/**"
13
+ ]
14
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "Lichess API",
3
+ "description": "Lichess Opening Explorer, Cloud Evaluation, and authenticated API — query master and rated game statistics by opening move sequence, get cached Stockfish engine evaluations by FEN position, and access authenticated endpoints (account info, game history, player-specific opening analysis, etc.). Set LICHESS_API_TOKEN to a personal access token for authenticated routes; public endpoints (Opening Explorer, Cloud Eval) work without it.",
4
+ "docsUrl": "https://lichess.org/api",
5
+ "headers": {
6
+ "Authorization": "Bearer ${LICHESS_API_TOKEN}"
7
+ },
8
+ "secrets": {
9
+ "LICHESS_API_TOKEN": "${LICHESS_API_TOKEN}"
10
+ },
11
+ "allowedEndpoints": [
12
+ "https://explorer.lichess.ovh/**",
13
+ "https://lichess.org/api/**"
14
+ ]
15
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "Linear API",
3
+ "description": "Linear GraphQL API — issues, projects, teams, cycles, and more. Auth is handled automatically via the LINEAR_API_KEY environment variable. All requests are GraphQL queries sent as POST to https://api.linear.app/graphql. Includes a poll ingestor that periodically fetches recently updated issues — use poll_events to retrieve them.",
4
+ "docsUrl": "https://developers.linear.app/docs/graphql/working-with-the-graphql-api",
5
+ "headers": {
6
+ "Authorization": "${LINEAR_API_KEY}",
7
+ "Content-Type": "application/json"
8
+ },
9
+ "secrets": {
10
+ "LINEAR_API_KEY": "${LINEAR_API_KEY}"
11
+ },
12
+ "allowedEndpoints": [
13
+ "https://api.linear.app/**"
14
+ ],
15
+ "ingestor": {
16
+ "type": "poll",
17
+ "poll": {
18
+ "url": "https://api.linear.app/graphql",
19
+ "intervalMs": 60000,
20
+ "method": "POST",
21
+ "body": {
22
+ "query": "{ issues(orderBy: updatedAt, first: 50) { nodes { id identifier title state { name } priority updatedAt createdAt assignee { name } } } }"
23
+ },
24
+ "responsePath": "data.issues.nodes",
25
+ "deduplicateBy": "id",
26
+ "eventType": "issue_updated"
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "Mastodon API",
3
+ "description": "Mastodon API — statuses (toots), timelines, notifications, accounts, search, and more. Auth is handled automatically via the MASTODON_ACCESS_TOKEN environment variable (OAuth2 Bearer token from your instance's Development settings). This template targets mastodon.social — for other instances, override with a custom connector using the same auth pattern but different allowedEndpoints. Includes a poll ingestor that fetches the home timeline — use poll_events to retrieve them.",
4
+ "docsUrl": "https://docs.joinmastodon.org/api/",
5
+ "headers": {
6
+ "Authorization": "Bearer ${MASTODON_ACCESS_TOKEN}"
7
+ },
8
+ "secrets": {
9
+ "MASTODON_ACCESS_TOKEN": "${MASTODON_ACCESS_TOKEN}"
10
+ },
11
+ "allowedEndpoints": [
12
+ "https://mastodon.social/api/v1/**",
13
+ "https://mastodon.social/api/v2/**"
14
+ ],
15
+ "ingestor": {
16
+ "type": "poll",
17
+ "poll": {
18
+ "url": "https://mastodon.social/api/v1/timelines/home?limit=20",
19
+ "intervalMs": 60000,
20
+ "method": "GET",
21
+ "deduplicateBy": "id",
22
+ "eventType": "status"
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "Notion API",
3
+ "description": "Notion API — pages, databases, blocks, users, search, and more. Auth is handled automatically via the NOTION_API_KEY environment variable (internal integration token). The Notion-Version header is set to 2022-06-28. Includes a poll ingestor that periodically searches for recently edited pages — use poll_events to retrieve them.",
4
+ "docsUrl": "https://developers.notion.com/reference",
5
+ "headers": {
6
+ "Authorization": "Bearer ${NOTION_API_KEY}",
7
+ "Notion-Version": "2022-06-28",
8
+ "Content-Type": "application/json"
9
+ },
10
+ "secrets": {
11
+ "NOTION_API_KEY": "${NOTION_API_KEY}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://api.notion.com/**"
15
+ ],
16
+ "ingestor": {
17
+ "type": "poll",
18
+ "poll": {
19
+ "url": "https://api.notion.com/v1/search",
20
+ "intervalMs": 60000,
21
+ "method": "POST",
22
+ "body": {
23
+ "sort": {
24
+ "direction": "descending",
25
+ "timestamp": "last_edited_time"
26
+ }
27
+ },
28
+ "responsePath": "results",
29
+ "deduplicateBy": "id",
30
+ "eventType": "page_updated"
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "OpenAI API",
3
+ "description": "OpenAI API — chat completions, embeddings, images, audio, files, fine-tuning, and more. Auth is handled automatically via the OPENAI_API_KEY environment variable.",
4
+ "docsUrl": "https://platform.openai.com/docs/api-reference",
5
+ "openApiUrl": "https://raw.githubusercontent.com/openai/openai-openapi/master/openapi.yaml",
6
+ "headers": {
7
+ "Authorization": "Bearer ${OPENAI_API_KEY}",
8
+ "Content-Type": "application/json"
9
+ },
10
+ "secrets": {
11
+ "OPENAI_API_KEY": "${OPENAI_API_KEY}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://api.openai.com/**"
15
+ ]
16
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "OpenRouter API",
3
+ "description": "OpenRouter unified LLM API — chat completions, models, generation stats, and more. Auth is handled automatically via the OPENROUTER_API_KEY environment variable.",
4
+ "docsUrl": "https://openrouter.ai/docs/api-reference",
5
+ "openApiUrl": "https://openrouter.ai/openapi.json",
6
+ "headers": {
7
+ "Authorization": "Bearer ${OPENROUTER_API_KEY}",
8
+ "Content-Type": "application/json"
9
+ },
10
+ "secrets": {
11
+ "OPENROUTER_API_KEY": "${OPENROUTER_API_KEY}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://openrouter.ai/api/**"
15
+ ]
16
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "Reddit API",
3
+ "description": "Reddit API — subreddits, posts, comments, users, search, and more. Auth is handled automatically via the REDDIT_ACCESS_TOKEN environment variable (OAuth2 Bearer token). A User-Agent header is required by Reddit and set via REDDIT_USER_AGENT. Obtain an OAuth2 token by registering a 'script' app at https://www.reddit.com/prefs/apps and using the client credentials grant. Tokens expire after 1 hour — rotate externally. Includes a poll ingestor that fetches new posts from a configurable subreddit — set REDDIT_SUBREDDIT and use poll_events to retrieve them.",
4
+ "docsUrl": "https://www.reddit.com/dev/api/",
5
+ "headers": {
6
+ "Authorization": "Bearer ${REDDIT_ACCESS_TOKEN}",
7
+ "User-Agent": "${REDDIT_USER_AGENT}"
8
+ },
9
+ "secrets": {
10
+ "REDDIT_ACCESS_TOKEN": "${REDDIT_ACCESS_TOKEN}",
11
+ "REDDIT_USER_AGENT": "${REDDIT_USER_AGENT}",
12
+ "REDDIT_SUBREDDIT": "${REDDIT_SUBREDDIT}"
13
+ },
14
+ "allowedEndpoints": [
15
+ "https://oauth.reddit.com/**"
16
+ ],
17
+ "ingestor": {
18
+ "type": "poll",
19
+ "poll": {
20
+ "url": "https://oauth.reddit.com/r/${REDDIT_SUBREDDIT}/new?limit=25",
21
+ "intervalMs": 60000,
22
+ "method": "GET",
23
+ "responsePath": "data.children",
24
+ "deduplicateBy": "data.name",
25
+ "eventType": "new_post"
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "Slack API",
3
+ "description": "Slack Web API — messages, channels, users, reactions, files, and more. Auth is handled automatically via the SLACK_BOT_TOKEN environment variable. Real-time events via Socket Mode require SLACK_APP_TOKEN.",
4
+ "docsUrl": "https://docs.slack.dev/apis/web-api",
5
+ "openApiUrl": "https://raw.githubusercontent.com/slackapi/slack-api-specs/master/web-api/slack_web_openapi_v2.json",
6
+ "headers": {
7
+ "Authorization": "Bearer ${SLACK_BOT_TOKEN}"
8
+ },
9
+ "secrets": {
10
+ "SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}",
11
+ "SLACK_APP_TOKEN": "${SLACK_APP_TOKEN}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://slack.com/api/**"
15
+ ],
16
+ "ingestor": {
17
+ "type": "websocket",
18
+ "websocket": {
19
+ "gatewayUrl": "https://slack.com/api/apps.connections.open",
20
+ "protocol": "slack"
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "Stripe API",
3
+ "description": "Stripe payments API — customers, charges, payment intents, subscriptions, invoices, and more. Auth is handled automatically via the STRIPE_SECRET_KEY environment variable. Includes a webhook ingestor for real-time events (payment_intent.succeeded, invoice.paid, etc.) — set STRIPE_WEBHOOK_SECRET and use poll_events to retrieve them. Note: Stripe uses application/x-www-form-urlencoded for request bodies, not JSON.",
4
+ "docsUrl": "https://docs.stripe.com/api",
5
+ "openApiUrl": "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json",
6
+ "headers": {
7
+ "Authorization": "Bearer ${STRIPE_SECRET_KEY}"
8
+ },
9
+ "secrets": {
10
+ "STRIPE_SECRET_KEY": "${STRIPE_SECRET_KEY}",
11
+ "STRIPE_WEBHOOK_SECRET": "${STRIPE_WEBHOOK_SECRET}"
12
+ },
13
+ "allowedEndpoints": [
14
+ "https://api.stripe.com/**"
15
+ ],
16
+ "ingestor": {
17
+ "type": "webhook",
18
+ "webhook": {
19
+ "path": "stripe",
20
+ "protocol": "stripe",
21
+ "signatureHeader": "Stripe-Signature",
22
+ "signatureSecret": "STRIPE_WEBHOOK_SECRET"
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "Telegram Bot API",
3
+ "description": "Telegram Bot API — messages, chats, users, inline queries, payments, and more. Auth uses a bot token embedded in the URL path — include /bot${TELEGRAM_BOT_TOKEN}/ in your request URLs. The placeholder is resolved automatically from the route's secrets. Create a bot via @BotFather on Telegram to obtain a token. Includes a poll ingestor that fetches new updates via getUpdates — use poll_events to retrieve them.",
4
+ "docsUrl": "https://core.telegram.org/bots/api",
5
+ "headers": {
6
+ "Content-Type": "application/json"
7
+ },
8
+ "secrets": {
9
+ "TELEGRAM_BOT_TOKEN": "${TELEGRAM_BOT_TOKEN}"
10
+ },
11
+ "resolveSecretsInBody": true,
12
+ "allowedEndpoints": [
13
+ "https://api.telegram.org/**"
14
+ ],
15
+ "ingestor": {
16
+ "type": "poll",
17
+ "poll": {
18
+ "url": "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates?limit=25&timeout=0",
19
+ "intervalMs": 30000,
20
+ "method": "GET",
21
+ "responsePath": "result",
22
+ "deduplicateBy": "update_id",
23
+ "eventType": "update"
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "Trello API",
3
+ "description": "Trello boards, lists, and cards API. Authentication uses query parameters — include ?key=${TRELLO_API_KEY}&token=${TRELLO_TOKEN} in your request URLs. The placeholders are resolved automatically from the route's secrets. Includes a webhook ingestor for real-time events (card updates, list changes, board activity, etc.) — set TRELLO_API_SECRET and TRELLO_CALLBACK_URL, then use poll_events to retrieve them.",
4
+ "docsUrl": "https://developer.atlassian.com/cloud/trello/rest/",
5
+ "headers": {},
6
+ "secrets": {
7
+ "TRELLO_API_KEY": "${TRELLO_API_KEY}",
8
+ "TRELLO_TOKEN": "${TRELLO_TOKEN}",
9
+ "TRELLO_API_SECRET": "${TRELLO_API_SECRET}",
10
+ "TRELLO_CALLBACK_URL": "${TRELLO_CALLBACK_URL}"
11
+ },
12
+ "allowedEndpoints": [
13
+ "https://api.trello.com/**"
14
+ ],
15
+ "ingestor": {
16
+ "type": "webhook",
17
+ "webhook": {
18
+ "path": "trello",
19
+ "protocol": "trello",
20
+ "signatureHeader": "X-Trello-Webhook",
21
+ "signatureSecret": "TRELLO_API_SECRET",
22
+ "callbackUrl": "${TRELLO_CALLBACK_URL}"
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "Twitch API",
3
+ "description": "Twitch Helix API — streams, users, channels, clips, videos, chat, and more. Auth requires both a Bearer token and Client-Id header, handled automatically via TWITCH_ACCESS_TOKEN and TWITCH_CLIENT_ID environment variables. Register an application at https://dev.twitch.tv/console/apps to obtain credentials. Includes a poll ingestor that fetches followed live streams — set TWITCH_USER_ID and use poll_events to retrieve them.",
4
+ "docsUrl": "https://dev.twitch.tv/docs/api/reference/",
5
+ "headers": {
6
+ "Authorization": "Bearer ${TWITCH_ACCESS_TOKEN}",
7
+ "Client-Id": "${TWITCH_CLIENT_ID}"
8
+ },
9
+ "secrets": {
10
+ "TWITCH_ACCESS_TOKEN": "${TWITCH_ACCESS_TOKEN}",
11
+ "TWITCH_CLIENT_ID": "${TWITCH_CLIENT_ID}",
12
+ "TWITCH_USER_ID": "${TWITCH_USER_ID}"
13
+ },
14
+ "allowedEndpoints": [
15
+ "https://api.twitch.tv/helix/**"
16
+ ],
17
+ "ingestor": {
18
+ "type": "poll",
19
+ "poll": {
20
+ "url": "https://api.twitch.tv/helix/streams/followed?user_id=${TWITCH_USER_ID}&first=20",
21
+ "intervalMs": 60000,
22
+ "method": "GET",
23
+ "responsePath": "data",
24
+ "deduplicateBy": "id",
25
+ "eventType": "stream_online"
26
+ }
27
+ }
28
+ }