@frontmcp/skills 1.0.4 → 1.1.0
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,391 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rbac-abac-rebac
|
|
3
|
+
description: Comparison of RBAC, ABAC, and ReBAC authorization models with when to use each, policy syntax, and examples
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# RBAC, ABAC, and ReBAC Models
|
|
7
|
+
|
|
8
|
+
The FrontMCP authorities system supports three authorization models that can be used independently or combined. This reference explains each model, its policy syntax, and when to choose it.
|
|
9
|
+
|
|
10
|
+
## Model Comparison
|
|
11
|
+
|
|
12
|
+
| Model | Based On | Strength | Weakness | Use When |
|
|
13
|
+
| --------- | ----------------------------------------- | ------------------------------------------ | --------------------------------------------- | ------------------------------------------------------- |
|
|
14
|
+
| **RBAC** | User roles and permissions | Simple, well-understood, fast | No context awareness, role explosion at scale | Fixed role hierarchies (admin, editor, viewer) |
|
|
15
|
+
| **ABAC** | Attributes of user, resource, environment | Flexible, context-aware, fine-grained | More complex to configure and debug | Tenant isolation, environment gates, dynamic conditions |
|
|
16
|
+
| **ReBAC** | Relationships between users and resources | Models ownership and hierarchies naturally | Requires external relationship store | Document ownership, team membership, org hierarchies |
|
|
17
|
+
|
|
18
|
+
## RBAC -- Role-Based Access Control
|
|
19
|
+
|
|
20
|
+
RBAC checks whether the user has specific roles or permissions. Roles and permissions are extracted from JWT claims via `claimsMapping`.
|
|
21
|
+
|
|
22
|
+
### Roles Policy
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
interface RbacRolesPolicy {
|
|
26
|
+
/** User must have ALL of these roles (AND) */
|
|
27
|
+
all?: string[];
|
|
28
|
+
/** User must have at least ONE of these roles (OR) */
|
|
29
|
+
any?: string[];
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
When both `all` and `any` are set, both conditions must be satisfied.
|
|
34
|
+
|
|
35
|
+
**Examples:**
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// User must be an admin
|
|
39
|
+
authorities: {
|
|
40
|
+
roles: { any: ['admin', 'superadmin'] },
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// User must have BOTH 'reviewer' AND 'approver' roles
|
|
44
|
+
authorities: {
|
|
45
|
+
roles: { all: ['reviewer', 'approver'] },
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// User must have 'editor' AND at least one of 'us-team' or 'eu-team'
|
|
49
|
+
authorities: {
|
|
50
|
+
roles: {
|
|
51
|
+
all: ['editor'],
|
|
52
|
+
any: ['us-team', 'eu-team'],
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Permissions Policy
|
|
58
|
+
|
|
59
|
+
Same structure as roles, but checked against the user's permissions array.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
interface RbacPermissionsPolicy {
|
|
63
|
+
all?: string[];
|
|
64
|
+
any?: string[];
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Examples:**
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// User must have the 'users:delete' permission
|
|
72
|
+
authorities: {
|
|
73
|
+
permissions: { all: ['users:delete'] },
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// User must have 'content:read' AND ('content:write' OR 'content:publish')
|
|
77
|
+
authorities: {
|
|
78
|
+
permissions: {
|
|
79
|
+
all: ['content:read'],
|
|
80
|
+
any: ['content:write', 'content:publish'],
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Combining Roles and Permissions
|
|
86
|
+
|
|
87
|
+
Within a single policy object, roles and permissions are combined using the `operator` field (default `'AND'`).
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// User must be an admin AND have 'users:delete' permission
|
|
91
|
+
authorities: {
|
|
92
|
+
roles: { any: ['admin'] },
|
|
93
|
+
permissions: { all: ['users:delete'] },
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// User must be an admin OR have 'users:delete' permission
|
|
97
|
+
authorities: {
|
|
98
|
+
roles: { any: ['admin'] },
|
|
99
|
+
permissions: { all: ['users:delete'] },
|
|
100
|
+
operator: 'OR',
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## ABAC -- Attribute-Based Access Control
|
|
105
|
+
|
|
106
|
+
ABAC evaluates conditions against a context envelope containing `user`, `claims`, `input`, and `env`. This enables tenant isolation, environment-specific gates, and dynamic value matching.
|
|
107
|
+
|
|
108
|
+
### Context Envelope
|
|
109
|
+
|
|
110
|
+
The evaluation context has four top-level namespaces:
|
|
111
|
+
|
|
112
|
+
| Prefix | Content | Example Path |
|
|
113
|
+
| ---------- | ------------------------------------------------------------ | ----------------------------------- |
|
|
114
|
+
| `user.*` | Resolved user info (`sub`, `roles`, `permissions`, `claims`) | `user.sub`, `user.roles` |
|
|
115
|
+
| `claims.*` | Raw JWT claims | `claims.org_id`, `claims.email` |
|
|
116
|
+
| `input.*` | Tool/prompt input arguments | `input.tenantId`, `input.projectId` |
|
|
117
|
+
| `env.*` | Runtime environment variables | `env.NODE_ENV`, `env.REGION` |
|
|
118
|
+
|
|
119
|
+
### Simple Match
|
|
120
|
+
|
|
121
|
+
The `match` field provides simple equality checks. All pairs must match (AND semantics).
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
authorities: {
|
|
125
|
+
attributes: {
|
|
126
|
+
match: {
|
|
127
|
+
'claims.org_id': 'tenant-abc',
|
|
128
|
+
'env.NODE_ENV': 'production',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Advanced Conditions
|
|
135
|
+
|
|
136
|
+
The `conditions` array supports operators. All conditions must pass (AND semantics).
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
interface AbacCondition {
|
|
140
|
+
path: string; // Dot-path into context envelope
|
|
141
|
+
op: AbacOperator; // Comparison operator
|
|
142
|
+
value: unknown; // Literal or DynamicValueRef
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Available operators:**
|
|
147
|
+
|
|
148
|
+
| Operator | Description | Example |
|
|
149
|
+
| ------------ | --------------------------------- | --------------------------------------------------------------------------- |
|
|
150
|
+
| `eq` | Strict equality | `{ path: 'claims.tier', op: 'eq', value: 'enterprise' }` |
|
|
151
|
+
| `neq` | Not equal | `{ path: 'claims.status', op: 'neq', value: 'suspended' }` |
|
|
152
|
+
| `in` | Value is in array | `{ path: 'env.REGION', op: 'in', value: ['us-east', 'eu-west'] }` |
|
|
153
|
+
| `notIn` | Value is not in array | `{ path: 'claims.role', op: 'notIn', value: ['blocked'] }` |
|
|
154
|
+
| `gt` | Greater than (number) | `{ path: 'claims.tokenVersion', op: 'gt', value: 2 }` |
|
|
155
|
+
| `gte` | Greater than or equal | `{ path: 'claims.apiQuota', op: 'gte', value: 100 }` |
|
|
156
|
+
| `lt` | Less than (number) | `{ path: 'claims.failCount', op: 'lt', value: 5 }` |
|
|
157
|
+
| `lte` | Less than or equal | `{ path: 'claims.riskScore', op: 'lte', value: 50 }` |
|
|
158
|
+
| `contains` | String contains or array includes | `{ path: 'claims.email', op: 'contains', value: '@corp.com' }` |
|
|
159
|
+
| `startsWith` | String starts with | `{ path: 'user.sub', op: 'startsWith', value: 'service-' }` |
|
|
160
|
+
| `endsWith` | String ends with | `{ path: 'claims.email', op: 'endsWith', value: '@acme.com' }` |
|
|
161
|
+
| `exists` | Value exists (not null/undefined) | `{ path: 'user.sub', op: 'exists', value: true }` |
|
|
162
|
+
| `matches` | Regex match | `{ path: 'claims.email', op: 'matches', value: '^.*@(acme\|corp)\\.com$' }` |
|
|
163
|
+
|
|
164
|
+
### Dynamic Value References
|
|
165
|
+
|
|
166
|
+
Instead of hardcoding values, reference runtime data from tool input or JWT claims.
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// Match tenant from tool input
|
|
170
|
+
{ path: 'claims.org_id', op: 'eq', value: { fromInput: 'tenantId' } }
|
|
171
|
+
|
|
172
|
+
// Match a value from another claim
|
|
173
|
+
{ path: 'claims.department', op: 'eq', value: { fromClaims: 'manager.department' } }
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### ABAC Examples
|
|
177
|
+
|
|
178
|
+
**Tenant isolation:**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
@Tool({
|
|
182
|
+
name: 'get_tenant_data',
|
|
183
|
+
inputSchema: { tenantId: z.string() },
|
|
184
|
+
authorities: {
|
|
185
|
+
attributes: {
|
|
186
|
+
conditions: [
|
|
187
|
+
{ path: 'claims.org_id', op: 'eq', value: { fromInput: 'tenantId' } },
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
})
|
|
192
|
+
export default class GetTenantDataTool extends ToolContext { ... }
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Environment gate:**
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
@Tool({
|
|
199
|
+
name: 'run_migration',
|
|
200
|
+
authorities: {
|
|
201
|
+
attributes: {
|
|
202
|
+
conditions: [
|
|
203
|
+
{ path: 'env.NODE_ENV', op: 'in', value: ['staging', 'production'] },
|
|
204
|
+
{ path: 'claims.role', op: 'eq', value: 'dba' },
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
})
|
|
209
|
+
export default class RunMigrationTool extends ToolContext { ... }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Authenticated user check:**
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
authorities: {
|
|
216
|
+
attributes: {
|
|
217
|
+
conditions: [{ path: 'user.sub', op: 'exists', value: true }],
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## ReBAC -- Relationship-Based Access Control
|
|
223
|
+
|
|
224
|
+
ReBAC checks whether the authenticated user has a specific relationship to a named resource. This requires a `RelationshipResolver` that queries your authorization backend (SpiceDB, OpenFGA, custom database).
|
|
225
|
+
|
|
226
|
+
### Policy Syntax
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
interface RebacPolicy {
|
|
230
|
+
/** Relationship type (e.g., 'owner', 'member', 'viewer') */
|
|
231
|
+
type: string;
|
|
232
|
+
/** Resource type (e.g., 'document', 'site', 'org') */
|
|
233
|
+
resource: string;
|
|
234
|
+
/** Resource identifier -- literal, from input, or from claims */
|
|
235
|
+
resourceId: ResourceIdRef;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
type ResourceIdRef = string | { fromInput: string } | { fromClaims: string };
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Implementing a Relationship Resolver
|
|
242
|
+
|
|
243
|
+
The resolver is passed via the `authorities.relationshipResolver` config in `@FrontMcp()`. It must implement the `RelationshipResolver` interface.
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import type { RelationshipResolver, AuthoritiesEvaluationContext } from '@frontmcp/auth';
|
|
247
|
+
|
|
248
|
+
const myRelationshipResolver: RelationshipResolver = {
|
|
249
|
+
async check(
|
|
250
|
+
type: string,
|
|
251
|
+
resource: string,
|
|
252
|
+
resourceId: string,
|
|
253
|
+
userSub: string,
|
|
254
|
+
ctx: AuthoritiesEvaluationContext,
|
|
255
|
+
): Promise<boolean> {
|
|
256
|
+
// Example: query SpiceDB / OpenFGA / your database
|
|
257
|
+
const result = await spiceDb.checkPermission({
|
|
258
|
+
subject: { object: { objectType: 'user', objectId: userSub } },
|
|
259
|
+
permission: type,
|
|
260
|
+
resource: { objectType: resource, objectId: resourceId },
|
|
261
|
+
});
|
|
262
|
+
return result.permissionship === 'HAS_PERMISSION';
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// In @FrontMcp({ authorities: { ... } })
|
|
267
|
+
authorities: {
|
|
268
|
+
claimsMapping: { roles: 'roles' },
|
|
269
|
+
relationshipResolver: myRelationshipResolver,
|
|
270
|
+
profiles: { ... },
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### ReBAC Examples
|
|
275
|
+
|
|
276
|
+
**Document ownership:**
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
@Tool({
|
|
280
|
+
name: 'edit_document',
|
|
281
|
+
inputSchema: { documentId: z.string() },
|
|
282
|
+
authorities: {
|
|
283
|
+
relationships: {
|
|
284
|
+
type: 'owner',
|
|
285
|
+
resource: 'document',
|
|
286
|
+
resourceId: { fromInput: 'documentId' },
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
})
|
|
290
|
+
export default class EditDocumentTool extends ToolContext { ... }
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Team membership:**
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
@Tool({
|
|
297
|
+
name: 'view_team_dashboard',
|
|
298
|
+
inputSchema: { teamId: z.string() },
|
|
299
|
+
authorities: {
|
|
300
|
+
relationships: {
|
|
301
|
+
type: 'member',
|
|
302
|
+
resource: 'team',
|
|
303
|
+
resourceId: { fromInput: 'teamId' },
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
})
|
|
307
|
+
export default class ViewTeamDashboardTool extends ToolContext { ... }
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Multiple relationships (AND):**
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
@Tool({
|
|
314
|
+
name: 'approve_expense',
|
|
315
|
+
inputSchema: { expenseId: z.string(), departmentId: z.string() },
|
|
316
|
+
authorities: {
|
|
317
|
+
relationships: [
|
|
318
|
+
{ type: 'manager', resource: 'department', resourceId: { fromInput: 'departmentId' } },
|
|
319
|
+
{ type: 'reviewer', resource: 'expense', resourceId: { fromInput: 'expenseId' } },
|
|
320
|
+
],
|
|
321
|
+
},
|
|
322
|
+
})
|
|
323
|
+
export default class ApproveExpenseTool extends ToolContext { ... }
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Combining Models
|
|
327
|
+
|
|
328
|
+
The real power of the authorities system is combining models in a single policy. All fields within a policy are combined using `operator` (default `'AND'`).
|
|
329
|
+
|
|
330
|
+
**RBAC + ABAC (role AND tenant match):**
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
authorities: {
|
|
334
|
+
roles: { any: ['admin'] },
|
|
335
|
+
attributes: {
|
|
336
|
+
conditions: [
|
|
337
|
+
{ path: 'claims.org_id', op: 'eq', value: { fromInput: 'tenantId' } },
|
|
338
|
+
],
|
|
339
|
+
},
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**RBAC + ReBAC (role AND document ownership):**
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
authorities: {
|
|
347
|
+
roles: { any: ['editor'] },
|
|
348
|
+
relationships: {
|
|
349
|
+
type: 'owner',
|
|
350
|
+
resource: 'document',
|
|
351
|
+
resourceId: { fromInput: 'documentId' },
|
|
352
|
+
},
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Complex: admin bypasses ownership, others need ownership:**
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
authorities: {
|
|
360
|
+
anyOf: [
|
|
361
|
+
{ roles: { any: ['admin'] } },
|
|
362
|
+
{
|
|
363
|
+
roles: { any: ['editor'] },
|
|
364
|
+
relationships: {
|
|
365
|
+
type: 'owner',
|
|
366
|
+
resource: 'document',
|
|
367
|
+
resourceId: { fromInput: 'documentId' },
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
],
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Decision Guide
|
|
375
|
+
|
|
376
|
+
Use this guide to pick the right model for your use case:
|
|
377
|
+
|
|
378
|
+
| Question | If Yes | If No |
|
|
379
|
+
| ----------------------------------------- | -------------------------------------- | ---------------------- |
|
|
380
|
+
| Are roles/permissions defined in the IdP? | Start with RBAC | Consider ABAC or ReBAC |
|
|
381
|
+
| Do you need tenant isolation? | Use ABAC with `{ fromInput: ... }` | RBAC may suffice |
|
|
382
|
+
| Do you need per-resource ownership? | Use ReBAC with a relationship resolver | RBAC or ABAC |
|
|
383
|
+
| Do you need environment-specific gates? | Use ABAC with `env.*` paths | Not needed |
|
|
384
|
+
| Is the logic too complex for one model? | Combine with `allOf`/`anyOf` | Keep it simple |
|
|
385
|
+
|
|
386
|
+
## Reference
|
|
387
|
+
|
|
388
|
+
- Types: `libs/auth/src/authorities/authorities.types.ts`
|
|
389
|
+
- Evaluators: `libs/auth/src/authorities/authorities.evaluator.ts`
|
|
390
|
+
- Context: `libs/auth/src/authorities/authorities.context.ts`
|
|
391
|
+
- Related: `references/claims-mapping.md`, `references/authority-profiles.md`, `references/custom-evaluators.md`
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontmcp-channels
|
|
3
|
+
description: 'Use when you want to push real-time notifications into Claude Code sessions. Build webhook channels, chat bridges (WhatsApp, Telegram, Slack), agent completion alerts, job status notifications, or error forwarding. The skill for CHANNELS and NOTIFICATIONS.'
|
|
4
|
+
tags: [channels, notifications, claude-code, webhooks, messaging, real-time, two-way]
|
|
5
|
+
category: development
|
|
6
|
+
targets: [all]
|
|
7
|
+
bundle: [full]
|
|
8
|
+
priority: 8
|
|
9
|
+
visibility: both
|
|
10
|
+
license: Apache-2.0
|
|
11
|
+
metadata:
|
|
12
|
+
docs: https://code.claude.com/docs/en/channels-reference
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# FrontMCP Channels
|
|
16
|
+
|
|
17
|
+
Build push-based notification channels that stream real-time events into Claude Code. Channels let your MCP server forward webhooks, application errors, agent completions, job results, and chat messages directly into Claude's context, with optional two-way reply support.
|
|
18
|
+
|
|
19
|
+
## When to Use This Skill
|
|
20
|
+
|
|
21
|
+
### Must Use
|
|
22
|
+
|
|
23
|
+
- You need Claude Code to react to external events (CI failures, monitoring alerts, deploy status)
|
|
24
|
+
- You are building a chat bridge (WhatsApp, Telegram, Slack, Discord) for Claude Code
|
|
25
|
+
- You want agents or background jobs to notify Claude Code upon completion
|
|
26
|
+
|
|
27
|
+
### Recommended
|
|
28
|
+
|
|
29
|
+
- You want to forward application errors to Claude for debugging assistance
|
|
30
|
+
- You need a messaging interface where remote users can interact with Claude via chat platforms
|
|
31
|
+
|
|
32
|
+
### Skip When
|
|
33
|
+
|
|
34
|
+
- You only need standard MCP resource subscriptions (use `@Resource` with `resources/subscribe`)
|
|
35
|
+
- Your client is not Claude Code and does not support `experimental['claude/channel']`
|
|
36
|
+
- You need request-response patterns (use `@Tool` instead)
|
|
37
|
+
|
|
38
|
+
> **Decision:** Use channels when you need server-initiated push notifications into Claude Code. Use resources when the client pulls data on demand.
|
|
39
|
+
|
|
40
|
+
## Prerequisites
|
|
41
|
+
|
|
42
|
+
- `@frontmcp/sdk` >= 1.0.0
|
|
43
|
+
- Basic understanding of `@FrontMcp`, `@App`, and `@Tool` decorators
|
|
44
|
+
- For webhook sources: HTTP transport (not stdio-only)
|
|
45
|
+
- For chat bridges: external API credentials (WhatsApp Business API, Telegram Bot Token, etc.)
|
|
46
|
+
|
|
47
|
+
## Steps
|
|
48
|
+
|
|
49
|
+
1. Choose your channel source type from the Scenario Routing Table
|
|
50
|
+
2. Create a channel class or function
|
|
51
|
+
3. Register it in your app
|
|
52
|
+
4. Enable channels in `@FrontMcp` config
|
|
53
|
+
5. Test with Claude Code using `--dangerously-load-development-channels`
|
|
54
|
+
|
|
55
|
+
## Scenario Routing Table
|
|
56
|
+
|
|
57
|
+
| Scenario | Reference | Description |
|
|
58
|
+
| ---------------------------------- | ------------------------------- | ---------------------------------------------- |
|
|
59
|
+
| Webhook alerts (CI, monitoring) | `references/channel-sources.md` | Forward HTTP webhooks into Claude |
|
|
60
|
+
| Application error forwarding | `references/channel-sources.md` | Push app errors via event bus |
|
|
61
|
+
| Agent completion notifications | `references/channel-sources.md` | Notify when agents finish |
|
|
62
|
+
| Job/workflow completion | `references/channel-sources.md` | Notify when jobs complete |
|
|
63
|
+
| Service connector (WhatsApp, etc.) | `references/channel-sources.md` | Persistent connection with bidirectional tools |
|
|
64
|
+
| File/log watcher | `references/channel-sources.md` | File system change monitoring |
|
|
65
|
+
| Event replay for offline sessions | `references/channel-sources.md` | Buffer events for later delivery |
|
|
66
|
+
| WhatsApp/Telegram chat bridge | `references/channel-two-way.md` | Two-way messaging with Claude |
|
|
67
|
+
| Slack/Discord integration | `references/channel-two-way.md` | Chat platform bridges |
|
|
68
|
+
| Permission relay | `references/channel-two-way.md` | Remote tool approval via chat |
|
|
69
|
+
|
|
70
|
+
## Common Patterns
|
|
71
|
+
|
|
72
|
+
| Pattern | Correct | Incorrect | Why |
|
|
73
|
+
| -------------- | --------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------ |
|
|
74
|
+
| Meta keys | `meta: { env: 'prod' }` | `meta: { 'my-env': 'prod' }` | Meta keys must be valid identifiers (letters, digits, underscores) |
|
|
75
|
+
| Source naming | `name: 'deploy-alerts'` | `name: 'Deploy Alerts!'` | Channel names should be kebab-case identifiers |
|
|
76
|
+
| Two-way gating | Check sender identity before emitting | Trust room/group membership | Prevent prompt injection from untrusted group members |
|
|
77
|
+
| Error channels | Use `app-event` source with event bus | Poll for errors in a loop | Event bus is push-based and efficient |
|
|
78
|
+
| Manual push | Use `scope.channelNotifications.send()` | Call `pushNotification` on instance directly | Service handles capability filtering |
|
|
79
|
+
|
|
80
|
+
## Verification Checklist
|
|
81
|
+
|
|
82
|
+
### Server Setup
|
|
83
|
+
|
|
84
|
+
- [ ] `@FrontMcp({ channels: { enabled: true } })` is set
|
|
85
|
+
- [ ] Channel classes extend `ChannelContext` with `@Channel()` decorator
|
|
86
|
+
- [ ] Channels are listed in `@App({ channels: [...] })`
|
|
87
|
+
- [ ] `onEvent()` returns `{ content: string, meta?: Record<string, string> }`
|
|
88
|
+
|
|
89
|
+
### Capability
|
|
90
|
+
|
|
91
|
+
- [ ] Server advertises `experimental: { 'claude/channel': {} }` in capabilities
|
|
92
|
+
- [ ] Only sessions with matching capability receive notifications
|
|
93
|
+
- [ ] `instructions` field mentions `<channel>` tags when channels are active
|
|
94
|
+
|
|
95
|
+
### Two-Way
|
|
96
|
+
|
|
97
|
+
- [ ] `twoWay: true` is set on channels that need replies
|
|
98
|
+
- [ ] `channel-reply` tool appears in tool list
|
|
99
|
+
- [ ] `onReply()` is implemented and forwards to external system
|
|
100
|
+
- [ ] Sender authentication is enforced before emitting events
|
|
101
|
+
|
|
102
|
+
### Sources
|
|
103
|
+
|
|
104
|
+
- [ ] Webhook endpoints return 200 on success
|
|
105
|
+
- [ ] Event bus subscriptions are cleaned up on scope teardown
|
|
106
|
+
- [ ] Agent/job completion filters match expected IDs
|
|
107
|
+
|
|
108
|
+
## Troubleshooting
|
|
109
|
+
|
|
110
|
+
| Problem | Cause | Solution |
|
|
111
|
+
| ---------------------------- | ------------------------------- | ------------------------------------------------------------------ |
|
|
112
|
+
| No notifications arrive | Client doesn't support channels | Check client capabilities include `experimental['claude/channel']` |
|
|
113
|
+
| `channel-reply` tool missing | No two-way channels registered | Set `twoWay: true` on at least one channel |
|
|
114
|
+
| Webhook returns 500 | `onEvent()` throws | Check channel handler error logs |
|
|
115
|
+
| Duplicate notifications | Multiple sessions subscribed | This is correct behavior -- each session gets its own copy |
|
|
116
|
+
| Events lost on reconnect | Channels are in-memory | Channel state resets on server restart; use persistent sources |
|
|
117
|
+
|
|
118
|
+
## Reference
|
|
119
|
+
|
|
120
|
+
- [Claude Code Channels Reference](https://code.claude.com/docs/en/channels-reference)
|
|
121
|
+
- [MCP Specification - Notifications](https://modelcontextprotocol.io/specification/2025-03-26)
|
|
122
|
+
- Related skills: `frontmcp-development`, `frontmcp-testing`, `frontmcp-deployment`
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-notify
|
|
3
|
+
reference: channel-sources
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: Notify Claude Code when AI agents complete their tasks
|
|
6
|
+
tags: [agents, completion, notifications, automation]
|
|
7
|
+
features:
|
|
8
|
+
- Agent completion source with ID filtering
|
|
9
|
+
- Duration and output reporting
|
|
10
|
+
- Integration with agent registry emitter
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Agent Completion Channel
|
|
14
|
+
|
|
15
|
+
Notify Claude Code when AI agents complete their tasks
|
|
16
|
+
|
|
17
|
+
## Code
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// src/apps/automation/channels/agent-done.channel.ts
|
|
21
|
+
import { Channel, ChannelContext, ChannelNotification } from '@frontmcp/sdk';
|
|
22
|
+
|
|
23
|
+
@Channel({
|
|
24
|
+
name: 'agent-done',
|
|
25
|
+
description: 'Notifies when code review or test agents complete',
|
|
26
|
+
source: {
|
|
27
|
+
type: 'agent-completion',
|
|
28
|
+
agentIds: ['code-reviewer', 'test-writer', 'security-scanner'],
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
export class AgentDoneChannel extends ChannelContext {
|
|
32
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
33
|
+
const event = payload as {
|
|
34
|
+
agentId: string;
|
|
35
|
+
agentName: string;
|
|
36
|
+
status: 'success' | 'error';
|
|
37
|
+
durationMs?: number;
|
|
38
|
+
output?: string;
|
|
39
|
+
error?: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const duration = event.durationMs ? ` in ${(event.durationMs / 1000).toFixed(1)}s` : '';
|
|
43
|
+
|
|
44
|
+
if (event.status === 'error') {
|
|
45
|
+
return {
|
|
46
|
+
content: `Agent "${event.agentName}" failed${duration}.\nError: ${event.error ?? 'Unknown error'}`,
|
|
47
|
+
meta: { agent: event.agentId, status: 'error' },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const output = event.output ? `\nResult: ${event.output.slice(0, 500)}` : '';
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
content: `Agent "${event.agentName}" completed successfully${duration}.${output}`,
|
|
55
|
+
meta: { agent: event.agentId, status: 'success' },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## What This Demonstrates
|
|
62
|
+
|
|
63
|
+
- Agent completion source with ID filtering
|
|
64
|
+
- Duration and output reporting
|
|
65
|
+
- Integration with agent registry emitter
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- See `channel-sources` for all source type documentation
|
|
70
|
+
- See `frontmcp-development` for agent creation patterns
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: app-errors
|
|
3
|
+
reference: channel-sources
|
|
4
|
+
level: basic
|
|
5
|
+
description: Forward application errors to Claude Code via the in-process event bus
|
|
6
|
+
tags: [errors, app-event, debugging, monitoring]
|
|
7
|
+
features:
|
|
8
|
+
- App event source with ChannelEventBus
|
|
9
|
+
- Error severity classification
|
|
10
|
+
- Stack trace forwarding
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Application Error Channel
|
|
14
|
+
|
|
15
|
+
Forward application errors to Claude Code via the in-process event bus
|
|
16
|
+
|
|
17
|
+
## Code
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// src/apps/monitoring/channels/error-alert.channel.ts
|
|
21
|
+
import { Channel, ChannelContext, ChannelNotification } from '@frontmcp/sdk';
|
|
22
|
+
|
|
23
|
+
@Channel({
|
|
24
|
+
name: 'app-errors',
|
|
25
|
+
description: 'Application error notifications for debugging',
|
|
26
|
+
source: { type: 'app-event', event: 'error' },
|
|
27
|
+
})
|
|
28
|
+
export class ErrorAlertChannel extends ChannelContext {
|
|
29
|
+
async onEvent(payload: unknown): Promise<ChannelNotification> {
|
|
30
|
+
const error = payload as {
|
|
31
|
+
message: string;
|
|
32
|
+
stack?: string;
|
|
33
|
+
code?: string;
|
|
34
|
+
severity: 'warning' | 'error' | 'critical';
|
|
35
|
+
source?: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const lines = [`[${error.severity.toUpperCase()}] ${error.message}`];
|
|
39
|
+
if (error.code) lines.push(`Code: ${error.code}`);
|
|
40
|
+
if (error.stack) lines.push(`Stack:\n${error.stack}`);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
content: lines.join('\n'),
|
|
44
|
+
meta: {
|
|
45
|
+
severity: error.severity,
|
|
46
|
+
...(error.code ? { code: error.code } : {}),
|
|
47
|
+
...(error.source ? { error_source: error.source } : {}),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Emit from anywhere in your application:
|
|
54
|
+
// scope.channelEventBus.emit('error', {
|
|
55
|
+
// message: 'Database connection timeout',
|
|
56
|
+
// severity: 'critical',
|
|
57
|
+
// code: 'DB_TIMEOUT',
|
|
58
|
+
// source: 'user-service',
|
|
59
|
+
// stack: new Error().stack,
|
|
60
|
+
// });
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## What This Demonstrates
|
|
64
|
+
|
|
65
|
+
- App event source with ChannelEventBus
|
|
66
|
+
- Error severity classification
|
|
67
|
+
- Stack trace forwarding
|
|
68
|
+
|
|
69
|
+
## Related
|
|
70
|
+
|
|
71
|
+
- See `channel-sources` for all source type documentation
|