@frontmcp/skills 1.0.4 → 1.1.0-beta.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.
- package/catalog/frontmcp-authorities/SKILL.md +272 -0
- package/catalog/frontmcp-authorities/references/authority-profiles.md +262 -0
- package/catalog/frontmcp-authorities/references/claims-mapping.md +266 -0
- package/catalog/frontmcp-authorities/references/custom-evaluators.md +420 -0
- package/catalog/frontmcp-authorities/references/rbac-abac-rebac.md +391 -0
- package/catalog/frontmcp-channels/SKILL.md +122 -0
- package/catalog/frontmcp-channels/examples/channel-sources/agent-notify.md +70 -0
- package/catalog/frontmcp-channels/examples/channel-sources/app-errors.md +71 -0
- package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +102 -0
- package/catalog/frontmcp-channels/examples/channel-sources/job-completion.md +79 -0
- package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +106 -0
- package/catalog/frontmcp-channels/examples/channel-sources/service-connector.md +136 -0
- package/catalog/frontmcp-channels/examples/channel-sources/webhook-github.md +85 -0
- package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +133 -0
- package/catalog/frontmcp-channels/references/channel-sources.md +214 -0
- package/catalog/frontmcp-channels/references/channel-two-way.md +195 -0
- package/catalog/frontmcp-config/SKILL.md +20 -18
- package/catalog/frontmcp-config/examples/configure-auth/multi-app-auth.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth/public-mode-setup.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth/remote-oauth-with-vault.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth-modes/transparent-jwt-validation.md +1 -2
- package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +121 -0
- package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +64 -0
- package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +113 -0
- package/catalog/frontmcp-config/examples/configure-elicitation/basic-confirmation-gate.md +1 -2
- package/catalog/frontmcp-config/examples/configure-elicitation/distributed-elicitation-redis.md +1 -2
- package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -2
- package/catalog/frontmcp-config/examples/configure-http/unix-socket-local.md +1 -2
- package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +69 -0
- package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +91 -0
- package/catalog/frontmcp-config/examples/configure-throttle/distributed-redis-throttle.md +1 -2
- package/catalog/frontmcp-config/examples/configure-throttle/per-tool-rate-limit.md +1 -2
- package/catalog/frontmcp-config/examples/configure-throttle/server-level-rate-limit.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/legacy-preset-nodejs.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +1 -2
- package/catalog/frontmcp-config/references/configure-deployment-targets.md +214 -0
- package/catalog/frontmcp-config/references/configure-elicitation.md +1 -2
- package/catalog/frontmcp-config/references/configure-security-headers.md +198 -0
- package/catalog/frontmcp-deployment/SKILL.md +1 -0
- package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -2
- package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -2
- package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +117 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -3
- package/catalog/frontmcp-deployment/examples/build-for-sdk/create-flat-config.md +1 -2
- package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +3 -3
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +1 -2
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +106 -0
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/stdio-binary-with-env.md +107 -0
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/stdio-npx.md +89 -0
- package/catalog/frontmcp-deployment/references/build-for-mcpb.md +209 -0
- package/catalog/frontmcp-deployment/references/build-for-sdk.md +1 -2
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +225 -0
- package/catalog/frontmcp-development/examples/create-agent/basic-agent-with-tools.md +3 -6
- package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -2
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +2 -4
- package/catalog/frontmcp-development/examples/create-agent-llm-config/anthropic-config.md +1 -2
- package/catalog/frontmcp-development/examples/create-agent-llm-config/openai-config.md +1 -2
- package/catalog/frontmcp-development/examples/create-job/basic-report-job.md +1 -2
- package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +2 -3
- package/catalog/frontmcp-development/examples/create-job/job-with-retry.md +1 -2
- package/catalog/frontmcp-development/examples/create-plugin-hooks/tool-level-hooks-and-stage-replacement.md +2 -5
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +4 -3
- package/catalog/frontmcp-development/examples/create-skill-with-tools/directory-skill-with-tools.md +2 -3
- package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +2 -2
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool-annotations/destructive-delete-tool.md +2 -4
- package/catalog/frontmcp-development/examples/create-tool-annotations/readonly-query-tool.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/primitive-and-media-outputs.md +3 -6
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-raw-shape-output.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-schema-advanced-output.md +2 -4
- package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +3 -5
- package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +5 -5
- package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +4 -6
- package/catalog/frontmcp-development/examples/official-plugins/cache-and-feature-flags.md +3 -5
- package/catalog/frontmcp-development/examples/official-plugins/production-multi-plugin-setup.md +4 -5
- package/catalog/frontmcp-development/examples/official-plugins/remember-plugin-session-memory.md +3 -5
- package/catalog/frontmcp-development/references/create-agent.md +4 -7
- package/catalog/frontmcp-development/references/create-job.md +3 -6
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +12 -16
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +2 -3
- package/catalog/frontmcp-development/references/create-tool.md +93 -23
- package/catalog/frontmcp-development/references/create-workflow.md +2 -3
- package/catalog/frontmcp-development/references/decorators-guide.md +32 -36
- package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +4 -4
- package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -4
- package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +4 -3
- package/catalog/frontmcp-guides/SKILL.md +3 -3
- package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +4 -5
- package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +4 -3
- package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +4 -4
- package/catalog/frontmcp-guides/examples/example-weather-api/weather-tool-with-schemas.md +1 -2
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +22 -17
- package/catalog/frontmcp-guides/references/example-task-manager.md +16 -11
- package/catalog/frontmcp-guides/references/example-weather-api.md +6 -3
- package/catalog/frontmcp-observability/examples/telemetry-api/tool-custom-spans.md +2 -3
- package/catalog/frontmcp-observability/examples/tracing-setup/basic-tracing.md +4 -3
- package/catalog/frontmcp-observability/references/telemetry-api.md +2 -3
- package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -2
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +3 -4
- package/catalog/frontmcp-production-readiness/examples/distributed-ha/ha-kubernetes-3-replicas.md +229 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/cross-platform-crypto.md +2 -3
- package/catalog/frontmcp-production-readiness/examples/production-cli-binary/stdio-transport-error-handling.md +1 -2
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -4
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/workers-runtime-constraints.md +2 -3
- package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +3 -2
- package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +2 -2
- package/catalog/frontmcp-production-readiness/examples/production-vercel/stateless-serverless-design.md +3 -3
- package/catalog/frontmcp-production-readiness/references/distributed-ha.md +194 -0
- package/catalog/frontmcp-setup/SKILL.md +11 -11
- package/catalog/frontmcp-setup/examples/project-structure-standalone/feature-folder-organization.md +5 -3
- package/catalog/frontmcp-setup/examples/project-structure-standalone/minimal-standalone-layout.md +4 -2
- package/catalog/frontmcp-setup/examples/setup-project/basic-node-server.md +4 -2
- package/catalog/frontmcp-setup/examples/setup-project/vercel-serverless-server.md +4 -2
- package/catalog/frontmcp-setup/examples/setup-redis/hybrid-vercel-kv-with-pubsub.md +8 -7
- package/catalog/frontmcp-setup/references/setup-project.md +10 -9
- package/catalog/frontmcp-setup/references/setup-redis.md +19 -16
- package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +1 -3
- package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +1 -3
- package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +2 -2
- package/catalog/frontmcp-testing/references/test-direct-client.md +1 -3
- package/catalog/frontmcp-testing/references/test-tool-unit.md +2 -2
- package/catalog/skills-manifest.json +325 -3
- package/package.json +1 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: channel-sources
|
|
3
|
+
description: Configure different channel source types - webhooks, app events, agent/job completion, service connectors, file watchers, and manual push
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Channel Sources
|
|
7
|
+
|
|
8
|
+
Every channel has a source that determines how events flow into it. FrontMCP supports seven source types, each optimized for a different integration pattern.
|
|
9
|
+
|
|
10
|
+
## Webhook Source
|
|
11
|
+
|
|
12
|
+
Registers an HTTP POST endpoint. External services (GitHub, CI/CD, monitoring) send payloads to this endpoint.
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
@Channel({
|
|
16
|
+
name: 'ci-alerts',
|
|
17
|
+
description: 'CI/CD pipeline notifications',
|
|
18
|
+
source: { type: 'webhook', path: '/hooks/ci' },
|
|
19
|
+
})
|
|
20
|
+
class CIAlertChannel extends ChannelContext {
|
|
21
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
22
|
+
const { body } = payload as WebhookPayload;
|
|
23
|
+
const data = body as { pipeline: string; status: string; url: string };
|
|
24
|
+
return {
|
|
25
|
+
content: `CI pipeline "${data.pipeline}" ${data.status}.\nDetails: ${data.url}`,
|
|
26
|
+
meta: { pipeline: data.pipeline, status: data.status },
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## App Event Source
|
|
33
|
+
|
|
34
|
+
Subscribes to the in-process `ChannelEventBus`. Your application code emits events, and the channel transforms them into notifications.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
@Channel({
|
|
38
|
+
name: 'error-alerts',
|
|
39
|
+
description: 'Application error notifications',
|
|
40
|
+
source: { type: 'app-event', event: 'app:error' },
|
|
41
|
+
})
|
|
42
|
+
class ErrorAlertChannel extends ChannelContext {
|
|
43
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
44
|
+
const error = payload as { message: string; stack?: string; level: string };
|
|
45
|
+
return {
|
|
46
|
+
content: `Application Error: ${error.message}\n${error.stack ?? ''}`,
|
|
47
|
+
meta: { severity: error.level },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// In your application code:
|
|
53
|
+
scope.channelEventBus.emit('app:error', {
|
|
54
|
+
message: 'Connection refused',
|
|
55
|
+
stack: 'Error: ECONNREFUSED...',
|
|
56
|
+
level: 'critical',
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Agent Completion Source
|
|
61
|
+
|
|
62
|
+
Automatically pushes when registered agents finish execution. Optionally filter by agent IDs.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
@Channel({
|
|
66
|
+
name: 'agent-done',
|
|
67
|
+
description: 'Notifies when AI agents complete their tasks',
|
|
68
|
+
source: {
|
|
69
|
+
type: 'agent-completion',
|
|
70
|
+
agentIds: ['code-reviewer', 'test-writer'],
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
class AgentDoneChannel extends ChannelContext {
|
|
74
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
75
|
+
const event = payload as {
|
|
76
|
+
agentId: string;
|
|
77
|
+
status: string;
|
|
78
|
+
durationMs: number;
|
|
79
|
+
output?: string;
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
content: `Agent "${event.agentId}" finished (${event.status}) in ${event.durationMs}ms.${
|
|
83
|
+
event.output ? `\nResult: ${event.output}` : ''
|
|
84
|
+
}`,
|
|
85
|
+
meta: { agentId: event.agentId, status: event.status },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Job Completion Source
|
|
92
|
+
|
|
93
|
+
Pushes when background jobs or workflows complete. Optionally filter by job names.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
@Channel({
|
|
97
|
+
name: 'job-done',
|
|
98
|
+
description: 'Background job completion notifications',
|
|
99
|
+
source: {
|
|
100
|
+
type: 'job-completion',
|
|
101
|
+
jobNames: ['daily-report', 'data-sync'],
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
class JobDoneChannel extends ChannelContext {
|
|
105
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
106
|
+
const event = payload as {
|
|
107
|
+
jobName: string;
|
|
108
|
+
status: string;
|
|
109
|
+
durationMs: number;
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
content: `Job "${event.jobName}" ${event.status} (${event.durationMs}ms)`,
|
|
113
|
+
meta: { jobName: event.jobName, status: event.status },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Service Connector Source
|
|
120
|
+
|
|
121
|
+
Maintains a persistent connection to an external service. Claude sends outbound messages via channel-contributed tools, and incoming messages trigger `onEvent()`.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
@Channel({
|
|
125
|
+
name: 'whatsapp',
|
|
126
|
+
source: { type: 'service', service: 'whatsapp-business' },
|
|
127
|
+
tools: [SendWhatsAppTool], // Auto-registered for Claude to call
|
|
128
|
+
twoWay: true,
|
|
129
|
+
})
|
|
130
|
+
class WhatsAppChannel extends ChannelContext {
|
|
131
|
+
async onConnect(): Promise<void> {
|
|
132
|
+
// Establish connection, start listening for incoming messages
|
|
133
|
+
this.client.on('message', (msg) => this.pushIncoming(msg));
|
|
134
|
+
}
|
|
135
|
+
async onDisconnect(): Promise<void> {
|
|
136
|
+
/* tear down */
|
|
137
|
+
}
|
|
138
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
139
|
+
/* transform */
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## File Watcher Source
|
|
145
|
+
|
|
146
|
+
Watches file system paths for changes and pushes notifications. Uses `onConnect()` to start the watcher.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
@Channel({
|
|
150
|
+
name: 'log-watcher',
|
|
151
|
+
source: {
|
|
152
|
+
type: 'file-watcher',
|
|
153
|
+
paths: ['./logs/app.log', './logs/error.log'],
|
|
154
|
+
events: ['change', 'create'],
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
class LogWatcherChannel extends ChannelContext {
|
|
158
|
+
async onConnect(): Promise<void> {
|
|
159
|
+
// Start watching files, call pushIncoming() on changes
|
|
160
|
+
}
|
|
161
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
162
|
+
const event = payload as { file: string; content: string };
|
|
163
|
+
return { content: `[${event.file}] ${event.content}`, meta: { file: event.file } };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Manual Source
|
|
169
|
+
|
|
170
|
+
No automatic wiring. Push notifications programmatically via `scope.channelNotifications.send()`.
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const StatusChannel = channel({
|
|
174
|
+
name: 'status-updates',
|
|
175
|
+
description: 'Manual status broadcast',
|
|
176
|
+
source: { type: 'manual' },
|
|
177
|
+
})((payload) => ({
|
|
178
|
+
content: `Status: ${(payload as { message: string }).message}`,
|
|
179
|
+
}));
|
|
180
|
+
|
|
181
|
+
// Push from anywhere with scope access:
|
|
182
|
+
scope.channelNotifications.send('status-updates', 'Server maintenance starting in 5 minutes');
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Replay Buffer
|
|
186
|
+
|
|
187
|
+
Enable event buffering so events are preserved when Claude Code is not connected:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
@Channel({
|
|
191
|
+
name: 'ci-alerts',
|
|
192
|
+
source: { type: 'webhook', path: '/hooks/ci' },
|
|
193
|
+
replay: { enabled: true, maxEvents: 100 },
|
|
194
|
+
})
|
|
195
|
+
class CIAlertChannel extends ChannelContext {
|
|
196
|
+
/* ... */
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Buffered events are replayed when a new session connects, with `replayed: "true"` in meta.
|
|
201
|
+
|
|
202
|
+
## Examples
|
|
203
|
+
|
|
204
|
+
| Example | Level | Description |
|
|
205
|
+
| ----------------------------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
206
|
+
| [`webhook-github`](../examples/channel-sources/webhook-github.md) | Basic | Forward GitHub webhook events (PRs, pushes, CI) into Claude Code |
|
|
207
|
+
| [`app-errors`](../examples/channel-sources/app-errors.md) | Basic | Forward application errors to Claude Code via the in-process event bus |
|
|
208
|
+
| [`agent-notify`](../examples/channel-sources/agent-notify.md) | Intermediate | Notify Claude Code when AI agents complete their tasks |
|
|
209
|
+
| [`job-completion`](../examples/channel-sources/job-completion.md) | Intermediate | Notify Claude Code when background jobs and workflows complete |
|
|
210
|
+
| [`service-connector`](../examples/channel-sources/service-connector.md) | Advanced | Build a persistent service connector that lets Claude send and receive messages through WhatsApp, Telegram, or any messaging API |
|
|
211
|
+
| [`file-watcher`](../examples/channel-sources/file-watcher.md) | Intermediate | Watch files for changes and notify Claude Code in real-time |
|
|
212
|
+
| [`replay-buffer`](../examples/channel-sources/replay-buffer.md) | Advanced | Buffer channel events so Claude Code receives them when it connects, even if events occurred while offline |
|
|
213
|
+
|
|
214
|
+
> See all examples in [`examples/channel-sources/`](../examples/channel-sources/)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: channel-two-way
|
|
3
|
+
description: Build two-way chat bridges connecting WhatsApp, Telegram, Slack, and Discord to Claude Code
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Two-Way Channels (Chat Bridges)
|
|
7
|
+
|
|
8
|
+
Two-way channels let external users communicate with Claude Code through messaging platforms. Claude receives messages as channel events and replies using the auto-registered `channel-reply` tool.
|
|
9
|
+
|
|
10
|
+
## Architecture
|
|
11
|
+
|
|
12
|
+
1. **Incoming**: External message arrives (WhatsApp, Telegram, Slack webhook)
|
|
13
|
+
2. **Transform**: `onEvent()` converts to `ChannelNotification`
|
|
14
|
+
3. **Push**: Notification sent to Claude Code session
|
|
15
|
+
4. **Reply**: Claude calls `channel-reply` tool with response text
|
|
16
|
+
5. **Forward**: `onReply()` sends the reply back to the external platform
|
|
17
|
+
|
|
18
|
+
## WhatsApp Business API Bridge
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Channel, ChannelContext, ChannelNotification } from '@frontmcp/sdk';
|
|
22
|
+
|
|
23
|
+
// Store verified senders for security
|
|
24
|
+
const allowedSenders = new Set<string>();
|
|
25
|
+
|
|
26
|
+
@Channel({
|
|
27
|
+
name: 'whatsapp',
|
|
28
|
+
description: 'WhatsApp Business API bridge for Claude Code',
|
|
29
|
+
source: { type: 'webhook', path: '/hooks/whatsapp' },
|
|
30
|
+
twoWay: true,
|
|
31
|
+
meta: { platform: 'whatsapp' },
|
|
32
|
+
})
|
|
33
|
+
export class WhatsAppChannel extends ChannelContext {
|
|
34
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
35
|
+
const { body } = payload as { body: Record<string, unknown> };
|
|
36
|
+
|
|
37
|
+
// WhatsApp Cloud API webhook payload structure
|
|
38
|
+
const entry = (body as any).entry?.[0];
|
|
39
|
+
const change = entry?.changes?.[0];
|
|
40
|
+
const message = change?.value?.messages?.[0];
|
|
41
|
+
const contact = change?.value?.contacts?.[0];
|
|
42
|
+
|
|
43
|
+
if (!message || !contact) {
|
|
44
|
+
return { content: 'WhatsApp: received non-message webhook (status update)' };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const sender = contact.wa_id;
|
|
48
|
+
const senderName = contact.profile?.name ?? sender;
|
|
49
|
+
|
|
50
|
+
// Security: only allow verified senders
|
|
51
|
+
if (!allowedSenders.has(sender)) {
|
|
52
|
+
this.logger.warn(`WhatsApp: rejecting message from unverified sender ${sender}`);
|
|
53
|
+
return {
|
|
54
|
+
content: `WhatsApp: message from unverified sender ${senderName} (${sender}). Add to allowlist to process.`,
|
|
55
|
+
meta: { sender, sender_name: senderName, verified: 'false' },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const text = message.text?.body ?? '[non-text message]';
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
content: `${senderName}: ${text}`,
|
|
63
|
+
meta: {
|
|
64
|
+
sender,
|
|
65
|
+
sender_name: senderName,
|
|
66
|
+
message_id: message.id,
|
|
67
|
+
chat_id: sender,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async onReply(reply: string, meta?: Record<string, string>): Promise<void> {
|
|
73
|
+
const chatId = meta?.chat_id;
|
|
74
|
+
if (!chatId) {
|
|
75
|
+
this.logger.warn('WhatsApp reply: no chat_id in meta');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Send via WhatsApp Cloud API
|
|
80
|
+
const token = process.env['WHATSAPP_TOKEN'];
|
|
81
|
+
const phoneNumberId = process.env['WHATSAPP_PHONE_ID'];
|
|
82
|
+
|
|
83
|
+
await fetch(`https://graph.facebook.com/v18.0/${phoneNumberId}/messages`, {
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: {
|
|
86
|
+
Authorization: `Bearer ${token}`,
|
|
87
|
+
'Content-Type': 'application/json',
|
|
88
|
+
},
|
|
89
|
+
body: JSON.stringify({
|
|
90
|
+
messaging_product: 'whatsapp',
|
|
91
|
+
to: chatId,
|
|
92
|
+
text: { body: reply },
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Telegram Bot Bridge
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
@Channel({
|
|
103
|
+
name: 'telegram',
|
|
104
|
+
description: 'Telegram bot bridge for Claude Code',
|
|
105
|
+
source: { type: 'webhook', path: '/hooks/telegram' },
|
|
106
|
+
twoWay: true,
|
|
107
|
+
meta: { platform: 'telegram' },
|
|
108
|
+
})
|
|
109
|
+
export class TelegramChannel extends ChannelContext {
|
|
110
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
111
|
+
const { body } = payload as { body: Record<string, unknown> };
|
|
112
|
+
const update = body as {
|
|
113
|
+
message?: {
|
|
114
|
+
chat: { id: number };
|
|
115
|
+
from: { username?: string; first_name: string; id: number };
|
|
116
|
+
text?: string;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const msg = update.message;
|
|
121
|
+
if (!msg?.text) {
|
|
122
|
+
return { content: 'Telegram: non-text update received' };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const sender = msg.from.username ?? msg.from.first_name;
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
content: `${sender}: ${msg.text}`,
|
|
129
|
+
meta: {
|
|
130
|
+
chat_id: String(msg.chat.id),
|
|
131
|
+
sender: String(msg.from.id),
|
|
132
|
+
sender_name: sender,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async onReply(reply: string, meta?: Record<string, string>): Promise<void> {
|
|
138
|
+
const chatId = meta?.chat_id;
|
|
139
|
+
if (!chatId) return;
|
|
140
|
+
|
|
141
|
+
const token = process.env['TELEGRAM_BOT_TOKEN'];
|
|
142
|
+
await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: { 'Content-Type': 'application/json' },
|
|
145
|
+
body: JSON.stringify({ chat_id: chatId, text: reply }),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Security Best Practices
|
|
152
|
+
|
|
153
|
+
### Sender Gating
|
|
154
|
+
|
|
155
|
+
Always validate individual sender identity, not room/group membership:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// Good: check individual sender
|
|
159
|
+
if (!allowedSenders.has(senderId)) {
|
|
160
|
+
return { content: 'Rejected: unverified sender', meta: { verified: 'false' } };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Bad: trust anyone in a group chat
|
|
164
|
+
if (isGroupMember(chatId)) {
|
|
165
|
+
/* dangerous */
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Webhook Verification
|
|
170
|
+
|
|
171
|
+
Validate webhook signatures for each platform:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// WhatsApp: verify X-Hub-Signature-256 header
|
|
175
|
+
// Telegram: verify secret_token parameter
|
|
176
|
+
// Slack: verify X-Slack-Signature header
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Pairing Codes
|
|
180
|
+
|
|
181
|
+
For bootstrapping trust, use pairing codes:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// 1. User sends "/pair ABC123" in chat
|
|
185
|
+
// 2. Server verifies code, adds sender to allowlist
|
|
186
|
+
// 3. Future messages from this sender are trusted
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Examples
|
|
190
|
+
|
|
191
|
+
| Example | Level | Description |
|
|
192
|
+
| ------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------- |
|
|
193
|
+
| [`whatsapp-bridge`](../examples/channel-two-way/whatsapp-bridge.md) | Advanced | Full WhatsApp Business API bridge allowing users to chat with Claude Code via WhatsApp |
|
|
194
|
+
|
|
195
|
+
> See all examples in [`examples/channel-two-way/`](../examples/channel-two-way/)
|
|
@@ -52,24 +52,26 @@ Entry point for configuring FrontMCP servers. This skill helps you find the righ
|
|
|
52
52
|
|
|
53
53
|
## Scenario Routing Table
|
|
54
54
|
|
|
55
|
-
| Scenario | Skill | Description
|
|
56
|
-
| -------------------------------------------------------------- | -------------------------------------- |
|
|
57
|
-
| Choose between SSE, Streamable HTTP, or stdio | `configure-transport` | Transport protocol selection with distributed session options
|
|
58
|
-
| Set up CORS, port, base path, or request limits | `configure-http` | HTTP server options for Streamable HTTP and SSE transports
|
|
59
|
-
| Add rate limiting, concurrency, or IP filtering | `configure-throttle` | Server-level and per-tool throttle configuration
|
|
60
|
-
| Enable tools to ask users for input | `configure-elicitation` | Elicitation schemas, stores, and multi-step flows
|
|
61
|
-
| Set up authentication (public, transparent, local, remote) | `configure-auth` | OAuth flows, credential vault, multi-app auth
|
|
62
|
-
| Configure session storage backends | `configure-session` | Memory, Redis, Vercel KV, and custom session stores
|
|
63
|
-
| Add Redis for production storage | `setup-redis` | Docker Redis, Vercel KV, pub/sub for subscriptions
|
|
64
|
-
| Add SQLite for local development | `setup-sqlite` | SQLite with WAL mode, migration helpers
|
|
65
|
-
| Understand auth mode details (public/transparent/local/remote) | `configure-auth-modes` | Authentication mode details (public, transparent, local, remote)
|
|
66
|
-
| Fine-tune guard configuration for throttling | `configure-throttle-guard-config` | Advanced guard configuration for throttling
|
|
67
|
-
| Use transport protocol presets | `configure-transport-protocol-presets` | Transport protocol preset configurations
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
55
|
+
| Scenario | Skill | Description |
|
|
56
|
+
| -------------------------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------- |
|
|
57
|
+
| Choose between SSE, Streamable HTTP, or stdio | `configure-transport` | Transport protocol selection with distributed session options |
|
|
58
|
+
| Set up CORS, port, base path, or request limits | `configure-http` | HTTP server options for Streamable HTTP and SSE transports |
|
|
59
|
+
| Add rate limiting, concurrency, or IP filtering | `configure-throttle` | Server-level and per-tool throttle configuration |
|
|
60
|
+
| Enable tools to ask users for input | `configure-elicitation` | Elicitation schemas, stores, and multi-step flows |
|
|
61
|
+
| Set up authentication (public, transparent, local, remote) | `configure-auth` | OAuth flows, credential vault, multi-app auth |
|
|
62
|
+
| Configure session storage backends | `configure-session` | Memory, Redis, Vercel KV, and custom session stores |
|
|
63
|
+
| Add Redis for production storage | `setup-redis` | Docker Redis, Vercel KV, pub/sub for distributed subscriptions |
|
|
64
|
+
| Add SQLite for local development | `setup-sqlite` | SQLite with WAL mode, migration helpers |
|
|
65
|
+
| Understand auth mode details (public/transparent/local/remote) | `configure-auth-modes` | Authentication mode details (public, transparent, local, remote) |
|
|
66
|
+
| Fine-tune guard configuration for throttling | `configure-throttle-guard-config` | Advanced guard configuration for throttling |
|
|
67
|
+
| Use transport protocol presets | `configure-transport-protocol-presets` | Transport protocol preset configurations |
|
|
68
|
+
| Configure multi-target deployments and frontmcp.config.ts | `configure-deployment-targets` | Typed config with defineConfig(), 8 deployment targets, JSON schema |
|
|
69
|
+
| Add CSP, HSTS, X-Frame-Options, and other security headers | `configure-security-headers` | CSP directives, report-only mode, HSTS preload, custom headers |
|
|
70
|
+
| Split apps into separate scopes (`splitByApp`) | `decorators-guide` | Per-app scope and basePath isolation on `@FrontMcp` |
|
|
71
|
+
| Enable widget-to-host communication (ext-apps) | `decorators-guide` | `extApps` host capabilities, session validation, widget comms |
|
|
72
|
+
| Enable background jobs and workflows | `decorators-guide` | `jobs: { enabled: true, store? }` on `@FrontMcp` |
|
|
73
|
+
| Configure pagination for list operations | `decorators-guide` | `pagination` defaults for `tools/list` endpoint |
|
|
74
|
+
| Configure npm/ESM package loader for remote apps | `decorators-guide` | `loader` config for `App.esm()` / `App.remote()` resolution |
|
|
73
75
|
|
|
74
76
|
## Configuration Layers
|
|
75
77
|
|
|
@@ -18,8 +18,7 @@ Configure a single FrontMCP server with multiple apps, each using a different au
|
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
20
|
// src/server.ts
|
|
21
|
-
import {
|
|
22
|
-
import { z } from 'zod';
|
|
21
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
23
22
|
|
|
24
23
|
@Tool({
|
|
25
24
|
name: 'public_search',
|
|
@@ -18,8 +18,7 @@ Set up a FrontMCP server with public (unauthenticated) access and anonymous scop
|
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
20
|
// src/server.ts
|
|
21
|
-
import {
|
|
22
|
-
import { z } from 'zod';
|
|
21
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
23
22
|
|
|
24
23
|
@Tool({
|
|
25
24
|
name: 'search',
|
|
@@ -18,8 +18,7 @@ Configure a FrontMCP server with remote OAuth 2.1 authentication and use the cre
|
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
20
|
// src/server.ts
|
|
21
|
-
import {
|
|
22
|
-
import { z } from 'zod';
|
|
21
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
23
22
|
|
|
24
23
|
@Tool({
|
|
25
24
|
name: 'create_github_issue',
|
|
@@ -20,8 +20,7 @@ Configure a server that signs its own JWT tokens with consent and incremental au
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
// src/server.ts
|
|
23
|
-
import {
|
|
24
|
-
import { z } from 'zod';
|
|
23
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
25
24
|
|
|
26
25
|
@Tool({
|
|
27
26
|
name: 'manage_users',
|
|
@@ -19,8 +19,7 @@ Delegate authentication to an external OAuth orchestrator with Redis-backed toke
|
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
21
|
// src/server.ts
|
|
22
|
-
import {
|
|
23
|
-
import { z } from 'zod';
|
|
22
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
24
23
|
|
|
25
24
|
@Tool({
|
|
26
25
|
name: 'query_data',
|
|
@@ -18,8 +18,7 @@ Validate externally-issued JWTs without managing token lifecycle on the server.
|
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
20
|
// src/server.ts
|
|
21
|
-
import {
|
|
22
|
-
import { z } from 'zod';
|
|
21
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
23
22
|
|
|
24
23
|
@Tool({
|
|
25
24
|
name: 'get_profile',
|
package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: distributed-ha-config
|
|
3
|
+
reference: configure-deployment-targets
|
|
4
|
+
level: advanced
|
|
5
|
+
description: Configure a distributed deployment target with HA settings for heartbeat, session takeover, and Redis-backed session persistence
|
|
6
|
+
tags: [config, deployment, distributed, ha, redis, heartbeat, session-takeover]
|
|
7
|
+
features:
|
|
8
|
+
- Configuring the distributed deployment target with HA options
|
|
9
|
+
- Setting custom heartbeat intervals and TTL for pod liveness detection
|
|
10
|
+
- Combining server config (CSP, cookies) with HA config in the same target
|
|
11
|
+
- Using per-target environment variables for Redis connection
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Distributed Deployment with HA Configuration
|
|
15
|
+
|
|
16
|
+
Configure a distributed deployment target with HA settings for heartbeat, session takeover, and Redis-backed session persistence
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// frontmcp.config.ts
|
|
22
|
+
import { defineConfig } from '@frontmcp/cli';
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
name: 'ha-server',
|
|
26
|
+
version: '1.0.0',
|
|
27
|
+
deployments: [
|
|
28
|
+
// Development: standalone Node.js
|
|
29
|
+
{
|
|
30
|
+
target: 'node',
|
|
31
|
+
server: { http: { port: 3000 } },
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// Production: distributed with HA
|
|
35
|
+
{
|
|
36
|
+
target: 'distributed',
|
|
37
|
+
ha: {
|
|
38
|
+
heartbeatIntervalMs: 5000, // Write heartbeat every 5s (fast detection)
|
|
39
|
+
heartbeatTtlMs: 15000, // 3x interval for TTL
|
|
40
|
+
takeoverGracePeriodMs: 3000, // Wait 3s before claiming orphaned sessions
|
|
41
|
+
redisKeyPrefix: 'mcp:ha:', // Default prefix for all HA keys
|
|
42
|
+
},
|
|
43
|
+
server: {
|
|
44
|
+
http: { port: 8080 },
|
|
45
|
+
cookies: {
|
|
46
|
+
affinity: '__myapp_node', // Custom affinity cookie name
|
|
47
|
+
sameSite: 'Lax',
|
|
48
|
+
},
|
|
49
|
+
csp: {
|
|
50
|
+
enabled: true,
|
|
51
|
+
directives: { 'default-src': "'self'" },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
env: {
|
|
55
|
+
REDIS_HOST: 'redis.prod.internal',
|
|
56
|
+
NODE_ENV: 'production',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Build Both Targets
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Development
|
|
67
|
+
frontmcp build --target node
|
|
68
|
+
|
|
69
|
+
# Production
|
|
70
|
+
FRONTMCP_DEPLOYMENT_MODE=distributed frontmcp build --target distributed
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Server Code
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// src/main.ts
|
|
77
|
+
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
78
|
+
|
|
79
|
+
@Tool({ name: 'status', description: 'Server status', inputSchema: {} })
|
|
80
|
+
class StatusTool extends ToolContext {
|
|
81
|
+
async execute() {
|
|
82
|
+
return { status: 'healthy', timestamp: Date.now() };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@App({ name: 'main', tools: [StatusTool] })
|
|
87
|
+
class MainApp {}
|
|
88
|
+
|
|
89
|
+
@FrontMcp({
|
|
90
|
+
info: { name: 'ha-server', version: '1.0.0' },
|
|
91
|
+
apps: [MainApp],
|
|
92
|
+
redis: {
|
|
93
|
+
provider: 'redis',
|
|
94
|
+
host: process.env['REDIS_HOST'] || 'localhost',
|
|
95
|
+
port: 6379,
|
|
96
|
+
},
|
|
97
|
+
transport: {
|
|
98
|
+
persistence: {
|
|
99
|
+
redis: {
|
|
100
|
+
provider: 'redis',
|
|
101
|
+
host: process.env['REDIS_HOST'] || 'localhost',
|
|
102
|
+
port: 6379,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
class Server {}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## What This Demonstrates
|
|
111
|
+
|
|
112
|
+
- Configuring the distributed deployment target with HA options
|
|
113
|
+
- Setting custom heartbeat intervals and TTL for pod liveness detection
|
|
114
|
+
- Combining server config (CSP, cookies) with HA config in the same target
|
|
115
|
+
- Using per-target environment variables for Redis connection
|
|
116
|
+
|
|
117
|
+
## Related
|
|
118
|
+
|
|
119
|
+
- See `configure-deployment-targets` for the full multi-target reference
|
|
120
|
+
- See `distributed-ha` for the HA architecture deep dive
|
|
121
|
+
- See `configure-security-headers` for full security headers setup
|