@zackbart/connecta 0.28.1 → 0.29.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/CHANGELOG.md +788 -5
- package/README.md +62 -42
- package/bin/connecta.mjs +110 -139
- package/bin/meta-tool-names.d.mts +2 -0
- package/bin/meta-tool-names.mjs +9 -0
- package/bin/version.mjs +3 -0
- package/dist/access-tokens.js +53 -63
- package/dist/activity-request.js +8 -0
- package/dist/activity.d.ts +76 -42
- package/dist/activity.js +110 -42
- package/dist/auth/clerk-sdk/client.d.ts +65 -0
- package/dist/auth/clerk-sdk/client.js +5 -0
- package/dist/auth/clerk-sdk/generated.js +1845 -0
- package/dist/auth/clerk-transport.js +19 -0
- package/dist/auth/clerk.d.ts +17 -7
- package/dist/auth/clerk.js +189 -107
- package/dist/auth/cloudflare-access.js +25 -26
- package/dist/auth/downstream-client-metadata.d.ts +29 -0
- package/dist/auth/downstream-client-metadata.js +133 -0
- package/dist/auth/downstream-oauth.js +1584 -1580
- package/dist/auth/downstream-revocation.js +106 -0
- package/dist/auth/oauth-token-response.js +231 -0
- package/dist/auth/oauth-v2-migration.js +116 -0
- package/dist/auth/static-oauth.js +93 -71
- package/dist/auth-elicitation.js +283 -0
- package/dist/branding.d.ts +8 -16
- package/dist/branding.js +26 -59
- package/dist/byte-read-response.js +39 -0
- package/dist/call-admission.js +12 -16
- package/dist/catalog-cache.js +739 -0
- package/dist/catalog-drift.d.ts +50 -15
- package/dist/catalog-drift.js +365 -128
- package/dist/catalog-fingerprint.js +2 -4
- package/dist/catalog-freshness.js +13 -0
- package/dist/catalog-limits.js +2 -2
- package/dist/catalog-service.js +368 -224
- package/dist/catalog.js +43 -84
- package/dist/concurrency.js +3 -4
- package/dist/config-defaults.d.ts +39 -0
- package/dist/config-defaults.js +46 -0
- package/dist/config-schema.d.ts +181 -0
- package/dist/config-schema.js +435 -0
- package/dist/config-value-sources.js +102 -0
- package/dist/config.d.ts +631 -0
- package/dist/config.js +503 -0
- package/dist/connector-access.d.ts +1 -0
- package/dist/connector-access.js +13 -15
- package/dist/connector-caller.d.ts +8 -0
- package/dist/connector-caller.js +15 -6
- package/dist/connector-scope.js +1 -1
- package/dist/connectors/api-connector.d.ts +59 -7
- package/dist/connectors/api-connector.js +106 -19
- package/dist/connectors/api.js +4 -1
- package/dist/connectors/guarded-fetch.d.ts +144 -0
- package/dist/connectors/guarded-fetch.js +84 -35
- package/dist/connectors/negotiation-cache.js +46 -0
- package/dist/connectors/option-shapes.js +27 -0
- package/dist/connectors/remote-mcp.d.ts +30 -4
- package/dist/connectors/remote-mcp.js +1774 -320
- package/dist/connectors/resource-uri.js +335 -0
- package/dist/credential-contract.d.ts +10 -0
- package/dist/credential-rules.js +1 -3
- package/dist/credential-url.js +108 -0
- package/dist/credentials.d.ts +6 -1
- package/dist/credentials.js +27 -18
- package/dist/d1.d.ts +130 -0
- package/dist/d1.js +290 -0
- package/dist/describe-config.d.ts +165 -0
- package/dist/describe-config.js +315 -0
- package/dist/described.js +106 -0
- package/dist/downstream-input-context.js +119 -0
- package/dist/downstream-input.js +323 -0
- package/dist/errors.d.ts +97 -20
- package/dist/errors.js +158 -80
- package/dist/execute.js +453 -305
- package/dist/executor-admission.d.ts +1 -0
- package/dist/executor-admission.js +11 -15
- package/dist/executor-contract.d.ts +20 -0
- package/dist/executor-contract.js +48 -0
- package/dist/executor-result.js +24 -9
- package/dist/executors/quickjs-child.js +3 -4
- package/dist/executors/quickjs-runtime.js +147 -59
- package/dist/executors/quickjs.js +29 -35
- package/dist/favicon.js +1 -2
- package/dist/fix-prompt.js +1 -3
- package/dist/guest-runtime.js +188 -0
- package/dist/guest-types.d.ts +176 -0
- package/dist/guest-types.js +1 -0
- package/dist/html-security.js +24 -0
- package/dist/identity.js +1 -3
- package/dist/inbound-credential.js +52 -0
- package/dist/index.d.ts +24 -256
- package/dist/index.js +65 -478
- package/dist/invocation-auth.js +69 -0
- package/dist/invocation.js +230 -73
- package/dist/json-schema.d.ts +1 -1
- package/dist/mcp-client-context.js +35 -0
- package/dist/mcp-result.js +11 -7
- package/dist/meta-output.js +76 -0
- package/dist/meta-tool-names.d.ts +2 -0
- package/dist/meta-tool-names.js +3 -0
- package/dist/meta-tools.js +285 -209
- package/dist/module-contracts.d.ts +8 -23
- package/dist/node.d.ts +0 -2
- package/dist/node.js +2 -2
- package/dist/oauth-callback-outcome.js +1 -3
- package/dist/oauth-handoff.js +117 -0
- package/dist/oauth-sealing.js +20 -0
- package/dist/operator-record.d.ts +137 -0
- package/dist/operator-record.js +420 -0
- package/dist/operator-ui/assets.js +31 -0
- package/dist/operator-ui/contract.d.ts +72 -0
- package/dist/operator-ui/contract.js +1 -0
- package/dist/operator-ui/fix-prompts.d.ts +18 -0
- package/dist/operator-ui/generated.js +5 -4
- package/dist/operator-ui/model.d.ts +12 -87
- package/dist/operator-ui/model.js +2 -9
- package/dist/operator-ui/setup-commands.js +1 -3
- package/dist/operator-ui/view.d.ts +323 -0
- package/dist/operator-ui/view.js +62 -189
- package/dist/page-styles.js +2 -3
- package/dist/program-source.js +14 -2
- package/dist/{exempt-writes.js → program-writes.js} +55 -18
- package/dist/provider.d.ts +142 -0
- package/dist/provider.js +187 -0
- package/dist/providers/_shared/google/result-size.js +57 -0
- package/dist/providers/_shared/google/service-account.d.ts +58 -0
- package/dist/providers/_shared/google/service-account.js +500 -0
- package/dist/providers/_shared/google/workspace.d.ts +276 -0
- package/dist/providers/_shared/google/workspace.js +518 -0
- package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
- package/dist/providers/basecamp/index.js +997 -0
- package/dist/providers/basecamp/skill.generated.js +9 -0
- package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
- package/dist/providers/{breeze.js → breeze/index.js} +184 -140
- package/dist/providers/breeze/skill.generated.js +9 -0
- package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
- package/dist/providers/{ccb.js → ccb/index.js} +271 -116
- package/dist/providers/ccb/skill.generated.js +9 -0
- package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
- package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
- package/dist/providers/cloudflare/skill.generated.js +10 -0
- package/dist/providers/docs/index.d.ts +54 -0
- package/dist/providers/docs/index.js +1237 -0
- package/dist/providers/docs/skill.generated.js +9 -0
- package/dist/providers/drive/index.d.ts +53 -0
- package/dist/providers/drive/index.js +1523 -0
- package/dist/providers/drive/skill.generated.js +9 -0
- package/dist/providers/forms/index.d.ts +54 -0
- package/dist/providers/forms/index.js +1217 -0
- package/dist/providers/forms/skill.generated.js +11 -0
- package/dist/providers/github/auth.d.ts +32 -0
- package/dist/providers/github/auth.js +361 -0
- package/dist/providers/github/hosted.js +218 -0
- package/dist/providers/github/index.d.ts +13 -0
- package/dist/providers/github/index.js +140 -0
- package/dist/providers/github/key.js +100 -0
- package/dist/providers/github/rest.js +321 -0
- package/dist/providers/github/scope.d.ts +29 -0
- package/dist/providers/github/scope.js +124 -0
- package/dist/providers/github/skill.generated.js +8 -0
- package/dist/providers/gmail/index.d.ts +51 -0
- package/dist/providers/gmail/index.js +1436 -0
- package/dist/providers/gmail/skill.generated.js +9 -0
- package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
- package/dist/providers/linear/index.js +352 -0
- package/dist/providers/linear/skill.generated.js +8 -0
- package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
- package/dist/providers/mixpanel/index.js +416 -0
- package/dist/providers/mixpanel/skill.generated.js +9 -0
- package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
- package/dist/providers/{notion.js → notion/index.js} +226 -239
- package/dist/providers/notion/skill.generated.js +10 -0
- package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
- package/dist/providers/{overflow.js → overflow/index.js} +74 -111
- package/dist/providers/overflow/skill.generated.js +8 -0
- package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
- package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
- package/dist/providers/planning-center/skill.generated.js +10 -0
- package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
- package/dist/providers/revenuecat/index.js +557 -0
- package/dist/providers/revenuecat/skill.generated.js +11 -0
- package/dist/providers/sheets/index.d.ts +54 -0
- package/dist/providers/sheets/index.js +1237 -0
- package/dist/providers/sheets/skill.generated.js +10 -0
- package/dist/providers/slides/index.d.ts +53 -0
- package/dist/providers/slides/index.js +2645 -0
- package/dist/providers/slides/skill.generated.js +9 -0
- package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
- package/dist/providers/stripe/index.js +266 -0
- package/dist/providers/stripe/skill.generated.js +11 -0
- package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
- package/dist/providers/{tithely.js → tithely/index.js} +60 -91
- package/dist/providers/tithely/skill.generated.js +8 -0
- package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
- package/dist/providers/vercel/index.js +1038 -0
- package/dist/providers/vercel/mcp-ownership.js +212 -0
- package/dist/providers/vercel/skill.generated.js +11 -0
- package/dist/registry.d.ts +108 -171
- package/dist/registry.js +513 -925
- package/dist/request-state.js +21 -0
- package/dist/resource-read.js +100 -0
- package/dist/result-shapes.js +17 -49
- package/dist/retired-toolkits.js +1 -1
- package/dist/routes/access-tokens.js +3 -6
- package/dist/routes/activity-context.js +21 -0
- package/dist/routes/activity-disclosure.js +40 -0
- package/dist/routes/activity.js +59 -21
- package/dist/routes/actor-labels.js +3 -50
- package/dist/routes/connect.js +221 -0
- package/dist/routes/credentials.js +15 -27
- package/dist/routes/mcp.js +356 -130
- package/dist/routes/oauth-client-metadata.js +15 -0
- package/dist/routes/oauth-management.js +45 -107
- package/dist/routes/oauth.js +110 -57
- package/dist/routes/operator.js +3 -3
- package/dist/routes/shared.d.ts +25 -64
- package/dist/routes/shared.js +160 -80
- package/dist/routes/skills.js +30 -0
- package/dist/routes/ui-config.js +225 -0
- package/dist/routes/ui-data.js +40 -35
- package/dist/routes/ui.js +66 -56
- package/dist/runtime/admission.js +4 -2
- package/dist/runtime/call-admission.js +3 -1
- package/dist/runtime/connector-scope.js +1 -4
- package/dist/runtime/run.js +10 -39
- package/dist/runtime/services.js +12 -117
- package/dist/runtime/shared-read.js +1 -3
- package/dist/runtime/storage.js +8 -1
- package/dist/sent-secrets.d.ts +52 -0
- package/dist/sent-secrets.js +474 -0
- package/dist/server.js +28 -71
- package/dist/skills.js +406 -174
- package/dist/sqlite.d.ts +48 -0
- package/dist/sqlite.js +166 -0
- package/dist/storage/keys.js +428 -0
- package/dist/storage/memory.js +7 -0
- package/dist/storage/sql.d.ts +66 -0
- package/dist/storage/sql.js +534 -0
- package/dist/timeout.js +4 -2
- package/dist/tool-name.js +17 -0
- package/dist/tool-safety.d.ts +9 -35
- package/dist/tool-safety.js +20 -40
- package/dist/types.d.ts +320 -54
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +7 -19
- package/dist/ui.js +76 -90
- package/dist/url-safety.js +3 -6
- package/dist/usage-guide.js +137 -0
- package/dist/validate.d.ts +7 -0
- package/dist/validate.js +309 -47
- package/dist/version.d.ts +1 -7
- package/dist/version.js +3 -7
- package/dist/worker.d.ts +11 -0
- package/dist/worker.js +434 -0
- package/documentation/architecture.md +664 -231
- package/documentation/auth.md +936 -546
- package/documentation/code-mode.md +501 -312
- package/documentation/meta-tools.md +449 -200
- package/documentation/operator-tests.md +93 -0
- package/documentation/provider-migration-0.29.md +60 -0
- package/examples/worker/AGENTS.md +34 -12
- package/examples/worker/README.md +286 -255
- package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
- package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
- package/examples/worker/src/connecta.config.ts +151 -0
- package/examples/worker/src/index.ts +14 -197
- package/examples/worker/wrangler.jsonc +15 -35
- package/package.json +120 -54
- package/templates/node/.dockerignore +1 -2
- package/templates/node/.env.example +20 -21
- package/templates/node/AGENTS.md +21 -17
- package/templates/node/Dockerfile +3 -5
- package/templates/node/README.md +133 -58
- package/templates/node/docker-compose.yml +11 -12
- package/templates/node/package.json +4 -2
- package/templates/node/src/connecta.config.ts +119 -0
- package/templates/node/src/index.ts +9 -154
- package/templates/node/src/provision-token.ts +17 -0
- package/AGENTS.md +0 -170
- package/dist/artifacts/connector.d.ts +0 -58
- package/dist/artifacts/connector.js +0 -730
- package/dist/artifacts/document.js +0 -86
- package/dist/artifacts/guide.js +0 -140
- package/dist/artifacts/html-scan.js +0 -329
- package/dist/artifacts/json.js +0 -78
- package/dist/artifacts/kv-store.d.ts +0 -20
- package/dist/artifacts/kv-store.js +0 -140
- package/dist/artifacts/markdown.js +0 -478
- package/dist/artifacts/module.d.ts +0 -37
- package/dist/artifacts/module.js +0 -66
- package/dist/artifacts/operations.d.ts +0 -197
- package/dist/artifacts/operations.js +0 -1002
- package/dist/artifacts/refresh.d.ts +0 -55
- package/dist/artifacts/refresh.js +0 -236
- package/dist/artifacts/routes.js +0 -206
- package/dist/artifacts/types.d.ts +0 -214
- package/dist/artifacts/types.js +0 -22
- package/dist/artifacts/validate.d.ts +0 -62
- package/dist/artifacts/validate.js +0 -651
- package/dist/artifacts.d.ts +0 -6
- package/dist/artifacts.js +0 -9
- package/dist/auth/bearer.d.ts +0 -11
- package/dist/auth/bearer.js +0 -50
- package/dist/providers/basecamp.js +0 -445
- package/dist/providers/linear.js +0 -217
- package/dist/providers/mixpanel.js +0 -247
- package/dist/providers/revenuecat.js +0 -317
- package/dist/providers/stripe.js +0 -253
- package/dist/providers/vercel.js +0 -1253
- package/dist/storage/file.d.ts +0 -15
- package/dist/storage/file.js +0 -455
- package/ethos.md +0 -93
- package/examples/worker/src/cloudflare-kv.ts +0 -43
- package/examples/worker/src/d1-activity-row.ts +0 -155
- package/examples/worker/src/d1-activity.ts +0 -147
- package/examples/worker/src/d1-storage.ts +0 -138
- package/examples/worker/src/r2-artifact-blobs.ts +0 -29
- package/templates/node/src/file-activity.ts +0 -182
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { skill } from "./skill.generated.js";
|
|
1
2
|
/**
|
|
2
3
|
* Planning Center Online as a hand-written `api()` provider: named tools for
|
|
3
4
|
* the jobs a church staff agent actually does, plus two hatches split by safety
|
|
@@ -19,16 +20,19 @@
|
|
|
19
20
|
* Drift. Planning Center publishes an OpenAPI 3.1 document per product and
|
|
20
21
|
* dated version (`/<app>/v2/open_api/<version>`) and a credential-free
|
|
21
22
|
* documentation graph listing every version (`/<app>/v2/documentation`).
|
|
22
|
-
* `
|
|
23
|
+
* `src/providers/planning-center/drift.json` records each endpoint a named
|
|
23
24
|
* tool calls, digested at the version pinned below, and
|
|
24
25
|
* `npm run providers:check -- --provider planning-center` reports a touched
|
|
25
26
|
* contract that moved and a newly published version of any pinned product.
|
|
26
27
|
* Both are evidence only: no tool here is generated from either document.
|
|
27
28
|
*/
|
|
28
|
-
import { apiConnector as api } from "
|
|
29
|
-
import { guardedFetch, retryAfterMs, } from "
|
|
30
|
-
import { ConnectorCallError } from "
|
|
31
|
-
import { CONNECTA_VERSION } from "
|
|
29
|
+
import { apiConnector as api } from "../../connectors/api-connector.js";
|
|
30
|
+
import { guardedFetch, retryAfterMs, } from "../../connectors/guarded-fetch.js";
|
|
31
|
+
import { ConnectorCallError } from "../../errors.js";
|
|
32
|
+
import { CONNECTA_VERSION } from "../../version.js";
|
|
33
|
+
import { keys, optionsOf } from "../../config-schema.js";
|
|
34
|
+
import { PROVIDER_COMMON } from "../../connectors/option-shapes.js";
|
|
35
|
+
import { asProviderFactory } from "../../provider.js";
|
|
32
36
|
/** Planning Center's REST origin. Override only for a proxy or test double. */
|
|
33
37
|
export const PLANNING_CENTER_API_BASE_URL = "https://api.planningcenteronline.com";
|
|
34
38
|
/** The products behind `/<app>/v2`, in the order their guides list them. */
|
|
@@ -148,9 +152,7 @@ const PERSONAL_ACCESS_TOKEN = {
|
|
|
148
152
|
},
|
|
149
153
|
};
|
|
150
154
|
function asRecord(value) {
|
|
151
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
152
|
-
? value
|
|
153
|
-
: {};
|
|
155
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
154
156
|
}
|
|
155
157
|
function asArray(value) {
|
|
156
158
|
return Array.isArray(value) ? value : [];
|
|
@@ -267,9 +269,7 @@ function errorDetail(payload, status) {
|
|
|
267
269
|
if (text)
|
|
268
270
|
parts.push(`${text}${at}`);
|
|
269
271
|
}
|
|
270
|
-
return parts.length > 0
|
|
271
|
-
? `Planning Center: ${parts.join("; ")}`
|
|
272
|
-
: `Planning Center returned HTTP ${status}.`;
|
|
272
|
+
return parts.length > 0 ? `Planning Center: ${parts.join("; ")}` : `Planning Center returned HTTP ${status}.`;
|
|
273
273
|
}
|
|
274
274
|
/**
|
|
275
275
|
* Map by the caller's next move.
|
|
@@ -293,7 +293,7 @@ function planningCenterFailure(status, headers, payload) {
|
|
|
293
293
|
return new ConnectorCallError("auth_required", `${detail} The personal access token was rejected: revoked, mistyped, or an Application ID and Secret from different tokens. An operator must replace it.`);
|
|
294
294
|
}
|
|
295
295
|
if (status === 403) {
|
|
296
|
-
return new ConnectorCallError("
|
|
296
|
+
return new ConnectorCallError("provider_permission_denied", `${detail} The token's Planning Center user lacks permission for this product or record. Permissions belong to that user; an operator must raise them or use another user's token. Retrying will not help.`, { retryable: false });
|
|
297
297
|
}
|
|
298
298
|
if (status === 404) {
|
|
299
299
|
return new ConnectorCallError("not_found", `${detail} Confirm the id with its list tool. A person id that used to resolve was probably merged: look it up in /people/v2/person_mergers with where[person_to_remove_id].`);
|
|
@@ -471,8 +471,20 @@ const PERSON_SCHEMA = record({
|
|
|
471
471
|
addresses: ARRAY,
|
|
472
472
|
households: ARRAY,
|
|
473
473
|
});
|
|
474
|
-
const EMAIL_SCHEMA = record({
|
|
475
|
-
|
|
474
|
+
const EMAIL_SCHEMA = record({
|
|
475
|
+
id: STRING,
|
|
476
|
+
address: STRING,
|
|
477
|
+
location: NULLABLE_STRING,
|
|
478
|
+
primary: BOOLEAN,
|
|
479
|
+
person_id: STRING,
|
|
480
|
+
});
|
|
481
|
+
const PHONE_SCHEMA = record({
|
|
482
|
+
id: STRING,
|
|
483
|
+
number: STRING,
|
|
484
|
+
location: NULLABLE_STRING,
|
|
485
|
+
primary: BOOLEAN,
|
|
486
|
+
person_id: STRING,
|
|
487
|
+
});
|
|
476
488
|
const CARD_SCHEMA = record({
|
|
477
489
|
id: STRING,
|
|
478
490
|
stage: STRING,
|
|
@@ -560,7 +572,10 @@ function personSummary(person, index) {
|
|
|
560
572
|
};
|
|
561
573
|
}
|
|
562
574
|
function emailRecord(email) {
|
|
563
|
-
return compact({
|
|
575
|
+
return compact({
|
|
576
|
+
...pick(email, ["address", "location", "primary"]),
|
|
577
|
+
person_id: relId(email, "person") ?? undefined,
|
|
578
|
+
});
|
|
564
579
|
}
|
|
565
580
|
function phoneRecord(phone) {
|
|
566
581
|
return compact({ ...pick(phone, ["number", "location", "primary"]), person_id: relId(phone, "person") ?? undefined });
|
|
@@ -738,10 +753,21 @@ const PERSON_WRITE_PROPERTIES = {
|
|
|
738
753
|
lastName: { type: "string", minLength: 1, description: "Last name." },
|
|
739
754
|
nickname: { type: ["string", "null"], description: "Nickname; null clears it." },
|
|
740
755
|
middleName: { type: ["string", "null"], description: "Middle name; null clears it." },
|
|
741
|
-
birthdate: {
|
|
742
|
-
|
|
756
|
+
birthdate: {
|
|
757
|
+
type: ["string", "null"],
|
|
758
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$",
|
|
759
|
+
description: "Birthdate, YYYY-MM-DD; null clears it.",
|
|
760
|
+
},
|
|
761
|
+
anniversary: {
|
|
762
|
+
type: ["string", "null"],
|
|
763
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$",
|
|
764
|
+
description: "Anniversary, YYYY-MM-DD; null clears it.",
|
|
765
|
+
},
|
|
743
766
|
gender: { type: ["string", "null"], description: "Gender as the organization records it, e.g. Male or Female." },
|
|
744
|
-
membership: {
|
|
767
|
+
membership: {
|
|
768
|
+
type: ["string", "null"],
|
|
769
|
+
description: "Membership type, one of the organization's own values such as Member or Visitor.",
|
|
770
|
+
},
|
|
745
771
|
child: { type: "boolean", description: "Whether the person is a child." },
|
|
746
772
|
primaryCampusId: { type: "string", pattern: "^[0-9]+$", description: "Campus id from /people/v2/campuses." },
|
|
747
773
|
};
|
|
@@ -760,15 +786,7 @@ function personAttributes(args) {
|
|
|
760
786
|
status: args["status"],
|
|
761
787
|
};
|
|
762
788
|
}
|
|
763
|
-
const WORKFLOW_CARD_ACTIONS = [
|
|
764
|
-
"promote",
|
|
765
|
-
"go_back",
|
|
766
|
-
"skip_step",
|
|
767
|
-
"snooze",
|
|
768
|
-
"unsnooze",
|
|
769
|
-
"remove",
|
|
770
|
-
"restore",
|
|
771
|
-
];
|
|
789
|
+
const WORKFLOW_CARD_ACTIONS = ["promote", "go_back", "skip_step", "snooze", "unsnooze", "remove", "restore"];
|
|
772
790
|
function tools(call, defaultPageSize) {
|
|
773
791
|
const perPage = (args) => args["perPage"] ?? defaultPageSize;
|
|
774
792
|
const list = (spec) => listTool(call, defaultPageSize, spec);
|
|
@@ -909,7 +927,11 @@ function tools(call, defaultPageSize) {
|
|
|
909
927
|
inputSchema: input({
|
|
910
928
|
personId: PERSON_ID,
|
|
911
929
|
...PERSON_WRITE_PROPERTIES,
|
|
912
|
-
status: {
|
|
930
|
+
status: {
|
|
931
|
+
type: "string",
|
|
932
|
+
enum: ["active", "inactive"],
|
|
933
|
+
description: "inactive archives the profile; active restores it.",
|
|
934
|
+
},
|
|
913
935
|
}, ["personId"]),
|
|
914
936
|
outputSchema: PERSON_SUMMARY_SCHEMA,
|
|
915
937
|
handler: async (args, ctx) => {
|
|
@@ -953,7 +975,11 @@ function tools(call, defaultPageSize) {
|
|
|
953
975
|
inputSchema: input({
|
|
954
976
|
personId: PERSON_ID,
|
|
955
977
|
number: { type: "string", minLength: 3, description: "Phone number as dialed; Planning Center formats it." },
|
|
956
|
-
location: {
|
|
978
|
+
location: {
|
|
979
|
+
type: "string",
|
|
980
|
+
minLength: 1,
|
|
981
|
+
description: "Label such as Mobile, Home, or Work. Defaults to Mobile.",
|
|
982
|
+
},
|
|
957
983
|
primary: { type: "boolean", description: "Make this the primary number." },
|
|
958
984
|
}, ["personId", "number"]),
|
|
959
985
|
outputSchema: PHONE_SCHEMA,
|
|
@@ -987,7 +1013,15 @@ function tools(call, defaultPageSize) {
|
|
|
987
1013
|
},
|
|
988
1014
|
path: () => "/people/v2/lists",
|
|
989
1015
|
query: (args) => ({ "where[name]": args["name"], order: args["order"] }),
|
|
990
|
-
project: (row) => pick(row, [
|
|
1016
|
+
project: (row) => pick(row, [
|
|
1017
|
+
"name",
|
|
1018
|
+
"description",
|
|
1019
|
+
"total_people",
|
|
1020
|
+
"status",
|
|
1021
|
+
"refreshed_at",
|
|
1022
|
+
"auto_refresh",
|
|
1023
|
+
"automations_active",
|
|
1024
|
+
]),
|
|
991
1025
|
}),
|
|
992
1026
|
list({
|
|
993
1027
|
name: "list_list_people",
|
|
@@ -1058,7 +1092,11 @@ function tools(call, defaultPageSize) {
|
|
|
1058
1092
|
item: CARD_SCHEMA,
|
|
1059
1093
|
properties: {
|
|
1060
1094
|
workflowId: idProperty("Workflow id from list_workflows."),
|
|
1061
|
-
stage: {
|
|
1095
|
+
stage: {
|
|
1096
|
+
type: "string",
|
|
1097
|
+
minLength: 1,
|
|
1098
|
+
description: "Card stage as Planning Center reports it, e.g. ready, snoozed, completed, removed.",
|
|
1099
|
+
},
|
|
1062
1100
|
stepId: idProperty("Only cards on this step (list_workflows steps[].id)."),
|
|
1063
1101
|
assigneeId: idProperty("Only cards assigned to this person id."),
|
|
1064
1102
|
overdue: { type: "boolean", description: "Only overdue (true) or on-time (false) cards." },
|
|
@@ -1104,7 +1142,12 @@ function tools(call, defaultPageSize) {
|
|
|
1104
1142
|
enum: [...WORKFLOW_CARD_ACTIONS],
|
|
1105
1143
|
description: "promote completes the step; skip_step moves on without completing it; go_back returns to the previous step.",
|
|
1106
1144
|
},
|
|
1107
|
-
snoozeDays: {
|
|
1145
|
+
snoozeDays: {
|
|
1146
|
+
type: "integer",
|
|
1147
|
+
minimum: 1,
|
|
1148
|
+
maximum: 365,
|
|
1149
|
+
description: "Days to snooze; required with action snooze and refused otherwise.",
|
|
1150
|
+
},
|
|
1108
1151
|
}, ["personId", "cardId", "action"]),
|
|
1109
1152
|
outputSchema: record({ cardId: STRING, action: STRING, applied: BOOLEAN }, ["cardId", "action", "applied"]),
|
|
1110
1153
|
handler: async (args, ctx) => {
|
|
@@ -1254,7 +1297,13 @@ function tools(call, defaultPageSize) {
|
|
|
1254
1297
|
name: "list_service_types",
|
|
1255
1298
|
description: "List Services service types — the recurring services such as Sunday Morning. Supplies serviceTypeId for plans and teams.",
|
|
1256
1299
|
key: "serviceTypes",
|
|
1257
|
-
item: record({
|
|
1300
|
+
item: record({
|
|
1301
|
+
id: STRING,
|
|
1302
|
+
name: STRING,
|
|
1303
|
+
frequency: NULLABLE_STRING,
|
|
1304
|
+
sequence: NULLABLE_INTEGER,
|
|
1305
|
+
parent_id: NULLABLE_STRING,
|
|
1306
|
+
}),
|
|
1258
1307
|
path: () => "/services/v2/service_types",
|
|
1259
1308
|
query: () => ({ order: "sequence" }),
|
|
1260
1309
|
project: (row) => ({ ...pick(row, ["name", "frequency", "sequence"]), parent_id: relId(row, "parent") ?? null }),
|
|
@@ -1276,7 +1325,11 @@ function tools(call, defaultPageSize) {
|
|
|
1276
1325
|
}),
|
|
1277
1326
|
properties: {
|
|
1278
1327
|
serviceTypeId: SERVICE_TYPE_ID,
|
|
1279
|
-
when: {
|
|
1328
|
+
when: {
|
|
1329
|
+
type: "string",
|
|
1330
|
+
enum: ["future", "past", "all"],
|
|
1331
|
+
description: "future (default) sorts soonest first; past sorts most recent first.",
|
|
1332
|
+
},
|
|
1280
1333
|
},
|
|
1281
1334
|
required: ["serviceTypeId"],
|
|
1282
1335
|
path: (args) => `/services/v2/service_types/${segment(args["serviceTypeId"])}/plans`,
|
|
@@ -1302,7 +1355,10 @@ function tools(call, defaultPageSize) {
|
|
|
1302
1355
|
name: "get_plan",
|
|
1303
1356
|
description: "Get one plan with its times, order of service, and scheduled team in a single call. Flags a section past 100 rows rather than dropping it silently.",
|
|
1304
1357
|
annotations: READ,
|
|
1305
|
-
inputSchema: input({ serviceTypeId: SERVICE_TYPE_ID, planId: PLAN_ID, raw: RAW_PROPERTY }, [
|
|
1358
|
+
inputSchema: input({ serviceTypeId: SERVICE_TYPE_ID, planId: PLAN_ID, raw: RAW_PROPERTY }, [
|
|
1359
|
+
"serviceTypeId",
|
|
1360
|
+
"planId",
|
|
1361
|
+
]),
|
|
1306
1362
|
outputSchema: {
|
|
1307
1363
|
type: "object",
|
|
1308
1364
|
properties: {
|
|
@@ -1340,12 +1396,18 @@ function tools(call, defaultPageSize) {
|
|
|
1340
1396
|
const teamIndex = indexIncluded(teamDocument);
|
|
1341
1397
|
return {
|
|
1342
1398
|
plan: {
|
|
1343
|
-
...pick(plan, [
|
|
1399
|
+
...pick(plan, [
|
|
1400
|
+
"title",
|
|
1401
|
+
"series_title",
|
|
1402
|
+
"dates",
|
|
1403
|
+
"sort_date",
|
|
1404
|
+
"total_length",
|
|
1405
|
+
"needed_positions_count",
|
|
1406
|
+
"planning_center_url",
|
|
1407
|
+
]),
|
|
1344
1408
|
times: relatedMany(plan, "plan_times", planIndex).map((time) => pick(time, ["name", "time_type", "starts_at", "ends_at"])),
|
|
1345
1409
|
},
|
|
1346
|
-
items: items
|
|
1347
|
-
.map(itemRecord)
|
|
1348
|
-
.sort((a, b) => Number(a["sequence"] ?? 0) - Number(b["sequence"] ?? 0)),
|
|
1410
|
+
items: items.map(itemRecord).sort((a, b) => Number(a["sequence"] ?? 0) - Number(b["sequence"] ?? 0)),
|
|
1349
1411
|
teamMembers: members.map((member) => planPersonRecord(member, teamIndex)),
|
|
1350
1412
|
...truncation,
|
|
1351
1413
|
};
|
|
@@ -1386,9 +1448,20 @@ function tools(call, defaultPageSize) {
|
|
|
1386
1448
|
},
|
|
1387
1449
|
required: ["personId"],
|
|
1388
1450
|
path: (args) => `/services/v2/people/${segment(args["personId"])}/schedules`,
|
|
1389
|
-
query: (args) => ({
|
|
1451
|
+
query: (args) => ({
|
|
1452
|
+
filter: args["when"] ?? "future",
|
|
1453
|
+
order: args["when"] === "past" ? "-starts_at" : "starts_at",
|
|
1454
|
+
}),
|
|
1390
1455
|
project: (row) => ({
|
|
1391
|
-
...pick(row, [
|
|
1456
|
+
...pick(row, [
|
|
1457
|
+
"dates",
|
|
1458
|
+
"sort_date",
|
|
1459
|
+
"service_type_name",
|
|
1460
|
+
"team_name",
|
|
1461
|
+
"team_position_name",
|
|
1462
|
+
"status",
|
|
1463
|
+
"decline_reason",
|
|
1464
|
+
]),
|
|
1392
1465
|
plan_id: relId(row, "plan") ?? null,
|
|
1393
1466
|
}),
|
|
1394
1467
|
}),
|
|
@@ -1401,9 +1474,16 @@ function tools(call, defaultPageSize) {
|
|
|
1401
1474
|
planId: PLAN_ID,
|
|
1402
1475
|
personId: PERSON_ID,
|
|
1403
1476
|
teamId: idProperty("Team id from list_teams."),
|
|
1404
|
-
teamPositionName: {
|
|
1477
|
+
teamPositionName: {
|
|
1478
|
+
type: "string",
|
|
1479
|
+
minLength: 1,
|
|
1480
|
+
description: "Position name from list_teams positions[].name.",
|
|
1481
|
+
},
|
|
1405
1482
|
status: { type: "string", enum: ["U", "C"], description: "U unconfirmed (default) or C confirmed." },
|
|
1406
|
-
prepareNotification: {
|
|
1483
|
+
prepareNotification: {
|
|
1484
|
+
type: "boolean",
|
|
1485
|
+
description: "Queue Planning Center's scheduling notification for this person.",
|
|
1486
|
+
},
|
|
1407
1487
|
notes: { type: "string", description: "Note shown to the person." },
|
|
1408
1488
|
}, ["serviceTypeId", "planId", "personId", "teamId"]),
|
|
1409
1489
|
outputSchema: PLAN_PERSON_SCHEMA,
|
|
@@ -1438,7 +1518,11 @@ function tools(call, defaultPageSize) {
|
|
|
1438
1518
|
keyId: idProperty("Key id from list_song_arrangements keys[].id."),
|
|
1439
1519
|
length: { type: "integer", minimum: 0, maximum: 86_400, description: "Length in seconds." },
|
|
1440
1520
|
sequence: { type: "integer", minimum: 0, description: "Position in the order; omit to append." },
|
|
1441
|
-
servicePosition: {
|
|
1521
|
+
servicePosition: {
|
|
1522
|
+
type: "string",
|
|
1523
|
+
enum: ["pre", "during", "post"],
|
|
1524
|
+
description: "Before, during, or after the service. Defaults to during.",
|
|
1525
|
+
},
|
|
1442
1526
|
description: { type: "string", description: "Item description." },
|
|
1443
1527
|
}, ["serviceTypeId", "planId", "title"]),
|
|
1444
1528
|
outputSchema: ITEM_SCHEMA,
|
|
@@ -1530,7 +1614,11 @@ function tools(call, defaultPageSize) {
|
|
|
1530
1614
|
properties: {
|
|
1531
1615
|
name: { type: "string", minLength: 1, description: "Exact group name; end it with % for a prefix match." },
|
|
1532
1616
|
groupTypeId: idProperty("Only groups of this type (/groups/v2/group_types)."),
|
|
1533
|
-
archived: {
|
|
1617
|
+
archived: {
|
|
1618
|
+
type: "string",
|
|
1619
|
+
enum: ["exclude", "include", "only"],
|
|
1620
|
+
description: "Archived groups: exclude (default), include, or only.",
|
|
1621
|
+
},
|
|
1534
1622
|
order: orderProperty(["name", "created_at", "memberships_count"]),
|
|
1535
1623
|
},
|
|
1536
1624
|
path: () => "/groups/v2/groups",
|
|
@@ -1541,7 +1629,14 @@ function tools(call, defaultPageSize) {
|
|
|
1541
1629
|
order: args["order"],
|
|
1542
1630
|
}),
|
|
1543
1631
|
project: (row) => ({
|
|
1544
|
-
...pick(row, [
|
|
1632
|
+
...pick(row, [
|
|
1633
|
+
"name",
|
|
1634
|
+
"memberships_count",
|
|
1635
|
+
"schedule",
|
|
1636
|
+
"contact_email",
|
|
1637
|
+
"archived_at",
|
|
1638
|
+
"public_church_center_web_url",
|
|
1639
|
+
]),
|
|
1545
1640
|
group_type_id: relId(row, "group_type") ?? null,
|
|
1546
1641
|
}),
|
|
1547
1642
|
}),
|
|
@@ -1606,7 +1701,7 @@ function tools(call, defaultPageSize) {
|
|
|
1606
1701
|
startsBefore: dateProperty("Only events starting before this time."),
|
|
1607
1702
|
includeCanceled: { type: "boolean", description: "Include canceled events." },
|
|
1608
1703
|
},
|
|
1609
|
-
path: (args) => args["groupId"] ? `/groups/v2/groups/${segment(args["groupId"])}/events` : "/groups/v2/events",
|
|
1704
|
+
path: (args) => (args["groupId"] ? `/groups/v2/groups/${segment(args["groupId"])}/events` : "/groups/v2/events"),
|
|
1610
1705
|
query: (args) => ({
|
|
1611
1706
|
...range(["starts_at"], args["startsAfter"], args["startsBefore"]),
|
|
1612
1707
|
filter: args["includeCanceled"] === true ? undefined : "not_canceled",
|
|
@@ -1628,7 +1723,10 @@ function tools(call, defaultPageSize) {
|
|
|
1628
1723
|
includeArchived: { type: "boolean", description: "Include archived events." },
|
|
1629
1724
|
},
|
|
1630
1725
|
path: () => "/check-ins/v2/events",
|
|
1631
|
-
query: (args) => ({
|
|
1726
|
+
query: (args) => ({
|
|
1727
|
+
"where[name]": args["name"],
|
|
1728
|
+
filter: args["includeArchived"] === true ? undefined : "not_archived",
|
|
1729
|
+
}),
|
|
1632
1730
|
project: (row) => pick(row, ["name", "frequency", "archived_at"]),
|
|
1633
1731
|
}),
|
|
1634
1732
|
list({
|
|
@@ -1653,7 +1751,15 @@ function tools(call, defaultPageSize) {
|
|
|
1653
1751
|
required: ["eventId"],
|
|
1654
1752
|
path: (args) => `/check-ins/v2/events/${segment(args["eventId"])}/event_periods`,
|
|
1655
1753
|
query: (args) => ({ ...range(["starts_at"], args["startsAfter"], args["startsBefore"]), order: "-starts_at" }),
|
|
1656
|
-
project: (row) => pick(row, [
|
|
1754
|
+
project: (row) => pick(row, [
|
|
1755
|
+
"starts_at",
|
|
1756
|
+
"ends_at",
|
|
1757
|
+
"regular_count",
|
|
1758
|
+
"guest_count",
|
|
1759
|
+
"volunteer_count",
|
|
1760
|
+
"unique_total_count",
|
|
1761
|
+
"note",
|
|
1762
|
+
]),
|
|
1657
1763
|
}),
|
|
1658
1764
|
list({
|
|
1659
1765
|
name: "list_check_ins",
|
|
@@ -1686,7 +1792,16 @@ function tools(call, defaultPageSize) {
|
|
|
1686
1792
|
order: args["order"],
|
|
1687
1793
|
}),
|
|
1688
1794
|
project: (row) => ({
|
|
1689
|
-
...pick(row, [
|
|
1795
|
+
...pick(row, [
|
|
1796
|
+
"first_name",
|
|
1797
|
+
"last_name",
|
|
1798
|
+
"kind",
|
|
1799
|
+
"number",
|
|
1800
|
+
"security_code",
|
|
1801
|
+
"created_at",
|
|
1802
|
+
"checked_out_at",
|
|
1803
|
+
"one_time_guest",
|
|
1804
|
+
]),
|
|
1690
1805
|
person_id: relId(row, "person") ?? null,
|
|
1691
1806
|
event_period_id: relId(row, "event_period") ?? null,
|
|
1692
1807
|
}),
|
|
@@ -1720,7 +1835,16 @@ function tools(call, defaultPageSize) {
|
|
|
1720
1835
|
order: "starts_at",
|
|
1721
1836
|
}),
|
|
1722
1837
|
project: (row) => ({
|
|
1723
|
-
...pick(row, [
|
|
1838
|
+
...pick(row, [
|
|
1839
|
+
"name",
|
|
1840
|
+
"starts_at",
|
|
1841
|
+
"ends_at",
|
|
1842
|
+
"all_day_event",
|
|
1843
|
+
"location",
|
|
1844
|
+
"kind",
|
|
1845
|
+
"recurrence_description",
|
|
1846
|
+
"church_center_url",
|
|
1847
|
+
]),
|
|
1724
1848
|
event_id: relId(row, "event") ?? null,
|
|
1725
1849
|
}),
|
|
1726
1850
|
}),
|
|
@@ -1742,11 +1866,25 @@ function tools(call, defaultPageSize) {
|
|
|
1742
1866
|
new_registration_url: NULLABLE_STRING,
|
|
1743
1867
|
}),
|
|
1744
1868
|
properties: {
|
|
1745
|
-
archived: {
|
|
1869
|
+
archived: {
|
|
1870
|
+
type: "string",
|
|
1871
|
+
enum: ["unarchived", "archived", "all"],
|
|
1872
|
+
description: "unarchived (default), archived, or all.",
|
|
1873
|
+
},
|
|
1746
1874
|
},
|
|
1747
1875
|
path: () => "/registrations/v2/signups",
|
|
1748
1876
|
query: (args) => ({ filter: args["archived"] === "all" ? undefined : (args["archived"] ?? "unarchived") }),
|
|
1749
|
-
project: (row) => pick(row, [
|
|
1877
|
+
project: (row) => pick(row, [
|
|
1878
|
+
"name",
|
|
1879
|
+
"open",
|
|
1880
|
+
"closed",
|
|
1881
|
+
"open_at",
|
|
1882
|
+
"close_at",
|
|
1883
|
+
"maximum_capacity",
|
|
1884
|
+
"at_maximum_capacity",
|
|
1885
|
+
"archived",
|
|
1886
|
+
"new_registration_url",
|
|
1887
|
+
]),
|
|
1750
1888
|
}),
|
|
1751
1889
|
list({
|
|
1752
1890
|
name: "list_signup_attendees",
|
|
@@ -1764,7 +1902,11 @@ function tools(call, defaultPageSize) {
|
|
|
1764
1902
|
}),
|
|
1765
1903
|
properties: {
|
|
1766
1904
|
signupId: idProperty("Signup id from list_signups."),
|
|
1767
|
-
status: {
|
|
1905
|
+
status: {
|
|
1906
|
+
type: "string",
|
|
1907
|
+
enum: ["active", "waitlist", "canceled"],
|
|
1908
|
+
description: "Only attendees in this state.",
|
|
1909
|
+
},
|
|
1768
1910
|
},
|
|
1769
1911
|
required: ["signupId"],
|
|
1770
1912
|
path: (args) => `/registrations/v2/signups/${segment(args["signupId"])}/attendees`,
|
|
@@ -1803,7 +1945,14 @@ function tools(call, defaultPageSize) {
|
|
|
1803
1945
|
name: "list_funds",
|
|
1804
1946
|
description: "List Giving funds with ledger codes and visibility. Supplies fundId for donation filters.",
|
|
1805
1947
|
key: "funds",
|
|
1806
|
-
item: record({
|
|
1948
|
+
item: record({
|
|
1949
|
+
id: STRING,
|
|
1950
|
+
name: STRING,
|
|
1951
|
+
ledger_code: NULLABLE_STRING,
|
|
1952
|
+
visibility: STRING,
|
|
1953
|
+
default: BOOLEAN,
|
|
1954
|
+
description: NULLABLE_STRING,
|
|
1955
|
+
}),
|
|
1807
1956
|
path: () => "/giving/v2/funds",
|
|
1808
1957
|
project: (row) => pick(row, ["name", "ledger_code", "visibility", "default", "description"]),
|
|
1809
1958
|
}),
|
|
@@ -1823,12 +1972,24 @@ function tools(call, defaultPageSize) {
|
|
|
1823
1972
|
batch_group_id: NULLABLE_STRING,
|
|
1824
1973
|
}),
|
|
1825
1974
|
properties: {
|
|
1826
|
-
status: {
|
|
1975
|
+
status: {
|
|
1976
|
+
type: "string",
|
|
1977
|
+
enum: ["committed", "in_progress"],
|
|
1978
|
+
description: "Only committed or in-progress batches.",
|
|
1979
|
+
},
|
|
1827
1980
|
},
|
|
1828
1981
|
path: () => "/giving/v2/batches",
|
|
1829
1982
|
query: (args) => ({ filter: args["status"], order: "-updated_at" }),
|
|
1830
1983
|
project: (row) => ({
|
|
1831
|
-
...pick(row, [
|
|
1984
|
+
...pick(row, [
|
|
1985
|
+
"description",
|
|
1986
|
+
"status",
|
|
1987
|
+
"donations_count",
|
|
1988
|
+
"total_cents",
|
|
1989
|
+
"total_currency",
|
|
1990
|
+
"committed_at",
|
|
1991
|
+
"created_at",
|
|
1992
|
+
]),
|
|
1832
1993
|
batch_group_id: relId(row, "batch_group") ?? null,
|
|
1833
1994
|
}),
|
|
1834
1995
|
}),
|
|
@@ -1895,12 +2056,21 @@ function tools(call, defaultPageSize) {
|
|
|
1895
2056
|
person_id: NULLABLE_STRING,
|
|
1896
2057
|
designations: DESIGNATIONS,
|
|
1897
2058
|
}),
|
|
1898
|
-
properties: {
|
|
2059
|
+
properties: {
|
|
2060
|
+
status: { type: "string", minLength: 1, description: "Status as Planning Center reports it, e.g. active." },
|
|
2061
|
+
},
|
|
1899
2062
|
path: () => "/giving/v2/recurring_donations",
|
|
1900
2063
|
query: (args) => ({ "where[status]": args["status"] }),
|
|
1901
2064
|
include: "designations,designations.fund",
|
|
1902
2065
|
project: (row, index) => ({
|
|
1903
|
-
...pick(row, [
|
|
2066
|
+
...pick(row, [
|
|
2067
|
+
"amount_cents",
|
|
2068
|
+
"amount_currency",
|
|
2069
|
+
"schedule",
|
|
2070
|
+
"status",
|
|
2071
|
+
"next_occurrence",
|
|
2072
|
+
"last_donation_received_at",
|
|
2073
|
+
]),
|
|
1904
2074
|
person_id: relId(row, "person") ?? null,
|
|
1905
2075
|
designations: designations(row, index),
|
|
1906
2076
|
}),
|
|
@@ -1911,9 +2081,20 @@ function tools(call, defaultPageSize) {
|
|
|
1911
2081
|
description: "List the organization's webhook subscriptions: event name, URL, and active state. Never returns the signing secret; that needs pco_api_get.",
|
|
1912
2082
|
annotations: READ,
|
|
1913
2083
|
inputSchema: input({ perPage: perPageProperty(defaultPageSize), offset: OFFSET_PROPERTY }),
|
|
1914
|
-
outputSchema: listOutput("subscriptions", record({
|
|
2084
|
+
outputSchema: listOutput("subscriptions", record({
|
|
2085
|
+
id: STRING,
|
|
2086
|
+
name: STRING,
|
|
2087
|
+
url: STRING,
|
|
2088
|
+
active: BOOLEAN,
|
|
2089
|
+
application_id: NULLABLE_STRING,
|
|
2090
|
+
created_at: STRING,
|
|
2091
|
+
})),
|
|
1915
2092
|
handler: async (args, ctx) => {
|
|
1916
|
-
const document = asRecord(await call({
|
|
2093
|
+
const document = asRecord(await call({
|
|
2094
|
+
method: "GET",
|
|
2095
|
+
path: "/webhooks/v2/webhook_subscriptions",
|
|
2096
|
+
query: { per_page: perPage(args), offset: args["offset"] },
|
|
2097
|
+
}, ctx));
|
|
1917
2098
|
// `authenticity_secret` verifies deliveries. A projection is the
|
|
1918
2099
|
// place it never appears, so this read has no `raw` mode.
|
|
1919
2100
|
return {
|
|
@@ -1929,50 +2110,29 @@ function tools(call, defaultPageSize) {
|
|
|
1929
2110
|
// ---------------------------------------------------------------------------
|
|
1930
2111
|
function usageGuide(purpose, instructions) {
|
|
1931
2112
|
const organizationInstructions = instructions?.trim();
|
|
1932
|
-
return
|
|
1933
|
-
|
|
1934
|
-
Planning Center Online church management — People, Services, Groups, Check-Ins, Calendar, Registrations, Giving, Publishing, Webhooks — for: ${purpose}
|
|
1935
|
-
|
|
1936
|
-
## Identity first
|
|
1937
|
-
|
|
1938
|
-
- A person id is the join key across every product: the id \`search_people\` returns is the \`personId\` for Services schedules, Groups memberships, Giving donations, and Check-Ins. Resolve ids with list tools; never guess one.
|
|
1939
|
-
- A person id that used to resolve and now answers \`not_found\` was most likely merged. Read \`/people/v2/person_mergers\` with \`where[person_to_remove_id]\` and follow \`person_to_keep_id\`.
|
|
1940
|
-
- \`get_me\` names the user this token acts as. Every read and write runs with that user's permissions, product by product; a \`connector_call_failed\` naming permission means the user cannot, not that the call was wrong.
|
|
1941
|
-
|
|
1942
|
-
## Results and paging
|
|
1943
|
-
|
|
1944
|
-
- Records keep Planning Center's own snake_case attribute names; a relationship appears as \`<relationship>_id\`. Pass \`raw: true\` for the untouched JSON:API resources and \`included\`.
|
|
1945
|
-
- Lists page by offset: \`perPage\` up to 100, then pass \`page.nextOffset\` back as \`offset\` while \`page.hasMore\` is true. \`page.totalCount\` answers "how many" without paging — request \`perPage: 1\`.
|
|
1946
|
-
- A bare date in a date filter is the organization's local day; pass a full timestamp for exact bounds. Name filters are exact; end one with \`%\` for a prefix match.
|
|
1947
|
-
- \`get_plan\` fetches the plan, its items, and its team in one call and sets \`itemsTruncated\`/\`teamMembersTruncated\` past 100 rows; page the rest with \`pco_api_get\`.
|
|
1948
|
-
|
|
1949
|
-
## What each product lets the API write
|
|
1950
|
-
|
|
1951
|
-
- People: full read/write. \`update_person\` with \`status: inactive\` archives reversibly; a DELETE is permanent and only reachable through \`pco_api_mutate\`. \`run_list\` can fire list automations.
|
|
1952
|
-
- Services: full read/write. A plan's dates come from its plan times. Scheduling needs a team.
|
|
1953
|
-
- Groups: memberships and group settings are writable; groups cannot be created, and events and attendance are read-only.
|
|
1954
|
-
- Check-Ins and Registrations: read-only. Nobody can be checked in or registered through the API.
|
|
1955
|
-
- Calendar: events, instances, and times are read-only; tags, resources, rooms, and folders are writable through \`pco_api_mutate\`.
|
|
1956
|
-
- Giving: the named tools only read, amounts in integer cents. Creating or editing donations, refunds, and committing a batch move money and go through \`pco_api_mutate\`.
|
|
1957
|
-
- Publishing and the \`api\` product (organization, OAuth applications, personal access tokens) have no named tools; use the hatches.
|
|
1958
|
-
|
|
1959
|
-
## The hatches
|
|
1960
|
-
|
|
1961
|
-
- \`pco_api_get\` reaches any GET; \`pco_api_mutate\` any POST, PATCH, or DELETE, always approval-gated. Paths start \`/<app>/v2\`, exactly as Planning Center documents them; the connector owns host, auth, content type, and the \`X-PCO-API-Version\` header.
|
|
1962
|
-
- Bodies are JSON:API documents: \`{"data":{"type":"Email","attributes":{...}}}\`. \`null\` clears an attribute; an omitted key is left alone.
|
|
1963
|
-
- Each product is pinned to a reviewed API version: ${PLANNING_CENTER_APPS.map((app) => `${app} ${PLANNING_CENTER_API_VERSIONS[app]}`).join(", ")}. Pass \`version\` only for an endpoint those versions lack.
|
|
1964
|
-
- Query parameters are name/value pairs with literal brackets: \`where[status]\`, \`include\`, \`order\`, \`filter\`, \`fields[Person]\`. Every list response's \`meta\` names the \`can_query_by\`, \`can_order_by\`, and \`can_include\` values for that endpoint; an unknown \`where\` key is ignored rather than refused.
|
|
1965
|
-
- File uploads go to a separate host (upload.planningcenteronline.com), which this connection does not reach.
|
|
1966
|
-
|
|
1967
|
-
## Rate limits
|
|
1968
|
-
|
|
1969
|
-
Planning Center allows 100 requests per 20 seconds per user, shared by every integration running as that user. This connection admits 100 calls per 20 seconds, five at a time, per runtime — an approximation, not a guarantee. A \`rate_limited\` failure carries Planning Center's wait. Filter server-side and use \`totalCount\` rather than paging to count.
|
|
1970
|
-
${organizationInstructions
|
|
1971
|
-
? `\n## Organization instructions\n\n${organizationInstructions}\n`
|
|
1972
|
-
: ""}`;
|
|
2113
|
+
return `${skill.fragments.guide_0}${purpose}${skill.fragments.guide_1}${PLANNING_CENTER_APPS.map((app) => `${app} ${PLANNING_CENTER_API_VERSIONS[app]}`).join(", ")}${skill.fragments.guide_2}${organizationInstructions ? `\n## ${skill.instructionsHeading}\n\n${organizationInstructions}\n` : ""}`;
|
|
1973
2114
|
}
|
|
2115
|
+
/** The closed options planningCenter() accepts; see `assertKnownOptions`. */
|
|
2116
|
+
const PLANNING_CENTER_OPTIONS = optionsOf()({
|
|
2117
|
+
...PROVIDER_COMMON,
|
|
2118
|
+
...keys("userAgent", "defaultPageSize", "baseUrl"),
|
|
2119
|
+
});
|
|
1974
2120
|
/** A maintained Planning Center Online connection over the REST API. */
|
|
1975
|
-
export
|
|
2121
|
+
export const planningCenter = asProviderFactory({
|
|
2122
|
+
name: "planning-center",
|
|
2123
|
+
title: "Planning Center",
|
|
2124
|
+
kind: "api",
|
|
2125
|
+
readme: "Planning Center",
|
|
2126
|
+
bundle: {
|
|
2127
|
+
"baselineGzip": 26970,
|
|
2128
|
+
"maxGzip": 86970,
|
|
2129
|
+
"note": "./providers/planning-center starts at 26,970 B gzip. It is api() over the guarded transport with no hosted-MCP surface, so neither the MCP client nor the Effect core is in its graph; the cap uses the existing baseline + 60,000 B policy.",
|
|
2130
|
+
},
|
|
2131
|
+
skill,
|
|
2132
|
+
options: PLANNING_CENTER_OPTIONS,
|
|
2133
|
+
create: planningCenterConnector,
|
|
2134
|
+
});
|
|
2135
|
+
function planningCenterConnector(id, options) {
|
|
1976
2136
|
const purpose = options.purpose.trim();
|
|
1977
2137
|
if (!purpose) {
|
|
1978
2138
|
throw new Error("planningCenter() requires a non-empty organization purpose.");
|
|
@@ -2004,7 +2164,7 @@ export function planningCenter(id, options) {
|
|
|
2004
2164
|
const document = asRecord(await call({ method: "GET", path: "/people/v2/me", query: { include: "organization" } }, {
|
|
2005
2165
|
...ctx,
|
|
2006
2166
|
credential: {
|
|
2007
|
-
get: async (field) => (field ? values[field] ?? null : null),
|
|
2167
|
+
get: async (field) => (field ? (values[field] ?? null) : null),
|
|
2008
2168
|
getAll: async () => values,
|
|
2009
2169
|
},
|
|
2010
2170
|
}));
|