@integrity-labs/agt-cli 0.28.1112 → 0.28.1113
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/dist/bin/agt.js +5 -5
- package/dist/{chunk-5EYINOIW.js → chunk-JX7ZXCNZ.js} +2 -2
- package/dist/{chunk-NO57I56V.js → chunk-OBZB6MUE.js} +74 -1
- package/dist/chunk-OBZB6MUE.js.map +1 -0
- package/dist/{chunk-TJUDOE53.js → chunk-TXNVB3DN.js} +4 -4
- package/dist/{claude-pair-runtime-CKWLQMAC.js → claude-pair-runtime-GL67TYXC.js} +2 -2
- package/dist/lib/manager-worker.js +16 -16
- package/dist/mcp/direct-chat-channel.js +73 -0
- package/dist/mcp/index.js +73 -0
- package/dist/mcp/origami.js +73 -0
- package/dist/mcp/slack-channel.js +73 -0
- package/dist/mcp/telegram-channel.js +73 -0
- package/dist/{persistent-session-SDYY75X7.js → persistent-session-6KIQF4O7.js} +3 -3
- package/dist/{responsiveness-probe-NEBHDSMI.js → responsiveness-probe-GGJNITME.js} +3 -3
- package/dist/{session-auth-dead-CNV4O7RF.js → session-auth-dead-LMCPZJ4K.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-NO57I56V.js.map +0 -1
- /package/dist/{chunk-5EYINOIW.js.map → chunk-JX7ZXCNZ.js.map} +0 -0
- /package/dist/{chunk-TJUDOE53.js.map → chunk-TXNVB3DN.js.map} +0 -0
- /package/dist/{claude-pair-runtime-CKWLQMAC.js.map → claude-pair-runtime-GL67TYXC.js.map} +0 -0
- /package/dist/{persistent-session-SDYY75X7.js.map → persistent-session-6KIQF4O7.js.map} +0 -0
- /package/dist/{responsiveness-probe-NEBHDSMI.js.map → responsiveness-probe-GGJNITME.js.map} +0 -0
- /package/dist/{session-auth-dead-CNV4O7RF.js.map → session-auth-dead-LMCPZJ4K.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parseEnvFileEntries,
|
|
17
17
|
parseEnvIntegrations,
|
|
18
18
|
shellQuote
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-JX7ZXCNZ.js";
|
|
20
20
|
import {
|
|
21
21
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
22
22
|
INTEGRATIONS_SECTION_END,
|
|
@@ -79,7 +79,7 @@ import {
|
|
|
79
79
|
sessionTranscriptDir,
|
|
80
80
|
worseConnectivityOutcome,
|
|
81
81
|
wrapScheduledTaskPrompt
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-OBZB6MUE.js";
|
|
83
83
|
import {
|
|
84
84
|
classifyUnanswerablePane,
|
|
85
85
|
isConsumerTermsDialogVisible,
|
|
@@ -7518,7 +7518,7 @@ function exchangeFailureKind(err) {
|
|
|
7518
7518
|
}
|
|
7519
7519
|
|
|
7520
7520
|
// src/lib/api-client.ts
|
|
7521
|
-
var agtCliVersion = true ? "0.28.
|
|
7521
|
+
var agtCliVersion = true ? "0.28.1113" : "dev";
|
|
7522
7522
|
var lastConfigHash = null;
|
|
7523
7523
|
function setConfigHash(hash) {
|
|
7524
7524
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -12492,4 +12492,4 @@ export {
|
|
|
12492
12492
|
managerInstallSystemUnitCommand,
|
|
12493
12493
|
managerUninstallSystemUnitCommand
|
|
12494
12494
|
};
|
|
12495
|
-
//# sourceMappingURL=chunk-
|
|
12495
|
+
//# sourceMappingURL=chunk-TXNVB3DN.js.map
|
|
@@ -266,7 +266,7 @@ async function spawnPairSession(session) {
|
|
|
266
266
|
return { ok: true };
|
|
267
267
|
} catch {
|
|
268
268
|
}
|
|
269
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
269
|
+
const { resolveClaudeBinary } = await import("./persistent-session-6KIQF4O7.js");
|
|
270
270
|
const claudeBin = resolveClaudeBinary();
|
|
271
271
|
const pairEnv = {
|
|
272
272
|
...process.env,
|
|
@@ -734,4 +734,4 @@ export {
|
|
|
734
734
|
startClaudePair,
|
|
735
735
|
submitClaudePairCode
|
|
736
736
|
};
|
|
737
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
737
|
+
//# sourceMappingURL=claude-pair-runtime-GL67TYXC.js.map
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
safeWriteJsonAtomic,
|
|
69
69
|
setConfigHash,
|
|
70
70
|
tripClass
|
|
71
|
-
} from "../chunk-
|
|
71
|
+
} from "../chunk-TXNVB3DN.js";
|
|
72
72
|
import {
|
|
73
73
|
getProjectDir as getProjectDir2,
|
|
74
74
|
getReadyTasks,
|
|
@@ -155,7 +155,7 @@ import {
|
|
|
155
155
|
webFetchBaselineValue,
|
|
156
156
|
webFetchRestartNeeded,
|
|
157
157
|
writeEgressAllowlist
|
|
158
|
-
} from "../chunk-
|
|
158
|
+
} from "../chunk-JX7ZXCNZ.js";
|
|
159
159
|
import {
|
|
160
160
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
161
161
|
AnchorSessionClient,
|
|
@@ -265,7 +265,7 @@ import {
|
|
|
265
265
|
subagentActivityAgeSeconds,
|
|
266
266
|
sumTranscriptUsageInWindow,
|
|
267
267
|
transcriptActivityAgeSeconds
|
|
268
|
-
} from "../chunk-
|
|
268
|
+
} from "../chunk-OBZB6MUE.js";
|
|
269
269
|
import {
|
|
270
270
|
classifyUnanswerablePane,
|
|
271
271
|
paneRemedy
|
|
@@ -14143,7 +14143,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
14143
14143
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
14144
14144
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
14145
14145
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
14146
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
14146
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-GGJNITME.js");
|
|
14147
14147
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
14148
14148
|
if (newest === null) return null;
|
|
14149
14149
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -14901,7 +14901,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
14901
14901
|
var lastVersionCheckAt = 0;
|
|
14902
14902
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14903
14903
|
var lastResponsivenessProbeAt = 0;
|
|
14904
|
-
var agtCliVersion = true ? "0.28.
|
|
14904
|
+
var agtCliVersion = true ? "0.28.1113" : "dev";
|
|
14905
14905
|
function resolveBrewPath(execFileSync3) {
|
|
14906
14906
|
try {
|
|
14907
14907
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -16518,7 +16518,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
16518
16518
|
if (codeNames.length === 0) return;
|
|
16519
16519
|
void (async () => {
|
|
16520
16520
|
try {
|
|
16521
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16521
|
+
const { collectDiagnostics } = await import("../persistent-session-6KIQF4O7.js");
|
|
16522
16522
|
await api.post("/host/heartbeat", {
|
|
16523
16523
|
host_id: hostId,
|
|
16524
16524
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -16660,7 +16660,7 @@ async function pollCycleInner() {
|
|
|
16660
16660
|
}
|
|
16661
16661
|
try {
|
|
16662
16662
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
16663
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16663
|
+
const { collectDiagnostics } = await import("../persistent-session-6KIQF4O7.js");
|
|
16664
16664
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
16665
16665
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
|
|
16666
16666
|
let tailscaleHostname;
|
|
@@ -16868,7 +16868,7 @@ async function pollCycleInner() {
|
|
|
16868
16868
|
collectPanelessActivityProbes,
|
|
16869
16869
|
getResponsivenessIntervalMs,
|
|
16870
16870
|
occupancyQualificationClassifications
|
|
16871
|
-
} = await import("../responsiveness-probe-
|
|
16871
|
+
} = await import("../responsiveness-probe-GGJNITME.js");
|
|
16872
16872
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
16873
16873
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
16874
16874
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -16985,7 +16985,7 @@ async function pollCycleInner() {
|
|
|
16985
16985
|
collectResponsivenessProbes,
|
|
16986
16986
|
livePendingInboundOldestAgeSeconds,
|
|
16987
16987
|
parkPendingInbound
|
|
16988
|
-
} = await import("../responsiveness-probe-
|
|
16988
|
+
} = await import("../responsiveness-probe-GGJNITME.js");
|
|
16989
16989
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
16990
16990
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
16991
16991
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -17271,7 +17271,7 @@ async function pollCycleInner() {
|
|
|
17271
17271
|
}
|
|
17272
17272
|
}
|
|
17273
17273
|
);
|
|
17274
|
-
const { parkPendingInbound } = await import("../responsiveness-probe-
|
|
17274
|
+
const { parkPendingInbound } = await import("../responsiveness-probe-GGJNITME.js");
|
|
17275
17275
|
const { parked, deadLettered } = parkPendingInbound(codeName, new Date(fatalNowMs));
|
|
17276
17276
|
paneFatalStreak.delete(codeName);
|
|
17277
17277
|
paneFatalRestarts.set(codeName, [...history, fatalNowMs]);
|
|
@@ -17302,7 +17302,7 @@ async function pollCycleInner() {
|
|
|
17302
17302
|
TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS,
|
|
17303
17303
|
bindSourceEscalations
|
|
17304
17304
|
} = await import("../transcript-mount-health-OHE6IVJV.js");
|
|
17305
|
-
const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-
|
|
17305
|
+
const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-6KIQF4O7.js");
|
|
17306
17306
|
const mountConfig = resolveTranscriptMountConfig();
|
|
17307
17307
|
const liveAgents = agentState.persistentSessionAgents;
|
|
17308
17308
|
for (const tracked of [
|
|
@@ -17467,7 +17467,7 @@ async function pollCycleInner() {
|
|
|
17467
17467
|
}
|
|
17468
17468
|
try {
|
|
17469
17469
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
17470
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
17470
|
+
const { probeSessionAuth } = await import("../session-auth-dead-LMCPZJ4K.js");
|
|
17471
17471
|
const observations = [];
|
|
17472
17472
|
const pendingCacheCommits = [];
|
|
17473
17473
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -22054,7 +22054,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
22054
22054
|
try {
|
|
22055
22055
|
const freshId = rotateSessionForWedge(codeName);
|
|
22056
22056
|
consecutiveWedgeCycles.delete(codeName);
|
|
22057
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
22057
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-GGJNITME.js");
|
|
22058
22058
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
22059
22059
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
22060
22060
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -22097,7 +22097,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
22097
22097
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
22098
22098
|
void (async () => {
|
|
22099
22099
|
try {
|
|
22100
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
22100
|
+
const { collectDiagnostics } = await import("../persistent-session-6KIQF4O7.js");
|
|
22101
22101
|
await api.post("/host/heartbeat", {
|
|
22102
22102
|
host_id: hostId,
|
|
22103
22103
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -22148,7 +22148,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
22148
22148
|
}
|
|
22149
22149
|
try {
|
|
22150
22150
|
const hostId = await getHostId();
|
|
22151
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
22151
|
+
const { collectDiagnostics } = await import("../persistent-session-6KIQF4O7.js");
|
|
22152
22152
|
await api.post("/host/heartbeat", {
|
|
22153
22153
|
host_id: hostId,
|
|
22154
22154
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -22821,7 +22821,7 @@ async function processClaudePairSessions(agents) {
|
|
|
22821
22821
|
// cannot take it for itself — by the time it runs, the write it is looking
|
|
22822
22822
|
// for may already have happened.
|
|
22823
22823
|
snapshotPairConfig
|
|
22824
|
-
} = await import("../claude-pair-runtime-
|
|
22824
|
+
} = await import("../claude-pair-runtime-GL67TYXC.js");
|
|
22825
22825
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
22826
22826
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
22827
22827
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -33059,6 +33059,51 @@ var OAUTH_PROVIDERS = {
|
|
|
33059
33059
|
}
|
|
33060
33060
|
]
|
|
33061
33061
|
},
|
|
33062
|
+
"otter": {
|
|
33063
|
+
// CS-2029: Otter.ai's official MCP — remote streamable-HTTP at
|
|
33064
|
+
// https://mcp.otter.ai/mcp. Same Granola/Kajabi shape: OAuth 2.0
|
|
33065
|
+
// authorization-code with PKCE (S256) and a public client
|
|
33066
|
+
// (token_endpoint_auth_method 'none') issued via Dynamic Client
|
|
33067
|
+
// Registration (RFC 7591). Values below are taken verbatim from the
|
|
33068
|
+
// metadata, not inferred:
|
|
33069
|
+
// - https://mcp.otter.ai/.well-known/oauth-protected-resource names the
|
|
33070
|
+
// AS as https://otter.ai/ and advertises scopes profile:read,
|
|
33071
|
+
// conversations:read;
|
|
33072
|
+
// - https://otter.ai/.well-known/oauth-authorization-server gives
|
|
33073
|
+
// authorize /oauth2/authorize, token /oauth/token, revoke
|
|
33074
|
+
// /oauth/revoke_token, register /oauth/register, PKCE S256, `none`,
|
|
33075
|
+
// and the refresh_token grant.
|
|
33076
|
+
// NOTE the authorize path is /oauth2/authorize while token/revoke live
|
|
33077
|
+
// under /oauth/ — that is Otter's own split, do not "normalise" it.
|
|
33078
|
+
// The prod client was registered 2026-10-10 against /oauth/register with
|
|
33079
|
+
// scope 'profile:read conversations:read' and BOTH API callbacks,
|
|
33080
|
+
// https://api.augmented.team/... and https://api.ninjafy.com/integrations/oauth/callback,
|
|
33081
|
+
// because redirect_uri follows API_PUBLIC_URL and the ENG-11060 flip makes
|
|
33082
|
+
// the ninjafy name canonical; Otter returns no RFC 7592 handle, so a redirect
|
|
33083
|
+
// cannot be added later without a new client and a re-consent per connection.
|
|
33084
|
+
// OAUTH_OTTER_CLIENT_ID is set from its output (docs/runbooks/otter-dogfood.md). Otter advertises ONLY
|
|
33085
|
+
// read scopes, so this integration is read-only by construction: there is
|
|
33086
|
+
// no write scope to request even by mistake.
|
|
33087
|
+
definitionId: "otter",
|
|
33088
|
+
authorizeUrl: "https://otter.ai/oauth2/authorize",
|
|
33089
|
+
tokenUrl: "https://otter.ai/oauth/token",
|
|
33090
|
+
revokeUrl: "https://otter.ai/oauth/revoke_token",
|
|
33091
|
+
defaultScopes: ["profile:read", "conversations:read"],
|
|
33092
|
+
supportsRefresh: true,
|
|
33093
|
+
extraAuthorizeParams: {},
|
|
33094
|
+
clientAuthMethod: "body",
|
|
33095
|
+
pkce: "S256",
|
|
33096
|
+
publicClient: true,
|
|
33097
|
+
mcpUrl: "https://mcp.otter.ai/mcp",
|
|
33098
|
+
// Curated surface (matches the catalog seed's defined_scopes[].tools).
|
|
33099
|
+
// These are the server's three tools, all read-only. The names are
|
|
33100
|
+
// Otter's own, quoted from the tools' descriptions ("use `otter_search`
|
|
33101
|
+
// first", "call otter_get_user_info() first"), not Composio's wrapped
|
|
33102
|
+
// OTTER_AI_MCP_* slugs. An allowlisted name the server does not advertise
|
|
33103
|
+
// is logged and SKIPPED by the proxy, so confirm against the first live
|
|
33104
|
+
// tools/list after a real consent (runbook Step 3).
|
|
33105
|
+
toolAllowlist: ["otter_get_user_info", "otter_search", "otter_fetch"]
|
|
33106
|
+
},
|
|
33062
33107
|
"notion-cli": {
|
|
33063
33108
|
// Notion's public OAuth app. Tokens are workspace-scoped and long-lived —
|
|
33064
33109
|
// Notion does not issue refresh_tokens, so `supportsRefresh: false` and
|
|
@@ -33692,6 +33737,34 @@ var INTEGRATION_REGISTRY = [
|
|
|
33692
33737
|
docs_url: "https://help.kajabi.com/articles/api-integrations/connect-kajabi-to-claude-or-chatgpt",
|
|
33693
33738
|
beta: true
|
|
33694
33739
|
},
|
|
33740
|
+
{
|
|
33741
|
+
id: "otter",
|
|
33742
|
+
name: "Otter.ai",
|
|
33743
|
+
category: "knowledge",
|
|
33744
|
+
description: "Read Otter.ai meetings: search recordings by date, attendee or topic, and read summaries, action items and full speaker-attributed transcripts.",
|
|
33745
|
+
// CS-2029: same remote streamable-HTTP MCP + OAuth pattern as Granola/Kajabi.
|
|
33746
|
+
// Otter's server implements the MCP discovery chain (RFC 9728 protected-
|
|
33747
|
+
// resource metadata at mcp.otter.ai → RFC 8414 AS metadata at otter.ai →
|
|
33748
|
+
// RFC 7591 registration); auth is OAuth 2.0 authorization-code with PKCE
|
|
33749
|
+
// (S256) and a public client registered via one-time Dynamic Client
|
|
33750
|
+
// Registration (scripts/dcr-register.ts against https://otter.ai/oauth/register
|
|
33751
|
+
// → OAUTH_OTTER_CLIENT_ID, --scope 'profile:read conversations:read').
|
|
33752
|
+
// Consent is brokered by the webapp through the shared
|
|
33753
|
+
// /integrations/oauth/authorize → /callback path, and the access_token
|
|
33754
|
+
// reaches the host via the generic remote-oauth-proxy
|
|
33755
|
+
// (OAUTH_PROVIDERS.otter.mcpUrl). Read-only by construction: Otter
|
|
33756
|
+
// advertises no write scope.
|
|
33757
|
+
supported_auth_types: ["oauth2"],
|
|
33758
|
+
capabilities: [
|
|
33759
|
+
{ id: "otter:read", name: "Read Meetings & Transcripts", description: "Find recorded meetings by date, attendee, topic or title, and read their summaries, action items, outlines and full transcripts (otter_get_user_info, otter_search, otter_fetch)", access: "read" }
|
|
33760
|
+
],
|
|
33761
|
+
// Otter's own Help Center article for the MCP server (CodeRabbit, #6906). It
|
|
33762
|
+
// exists even though help.otter.ai answers 403 to non-browser clients; the
|
|
33763
|
+
// help-centre API confirmed it (title "Otter MCP Server"). The MCP endpoint
|
|
33764
|
+
// itself is a JSON-RPC URL, not a page (Obi Wan 8305072d5414).
|
|
33765
|
+
docs_url: "https://help.otter.ai/hc/en-us/articles/35287607569687-Otter-MCP-Server",
|
|
33766
|
+
beta: true
|
|
33767
|
+
},
|
|
33695
33768
|
{
|
|
33696
33769
|
id: "anchor-browser",
|
|
33697
33770
|
name: "Anchor Browser",
|
package/dist/mcp/index.js
CHANGED
|
@@ -25562,6 +25562,51 @@ var OAUTH_PROVIDERS = {
|
|
|
25562
25562
|
}
|
|
25563
25563
|
]
|
|
25564
25564
|
},
|
|
25565
|
+
"otter": {
|
|
25566
|
+
// CS-2029: Otter.ai's official MCP — remote streamable-HTTP at
|
|
25567
|
+
// https://mcp.otter.ai/mcp. Same Granola/Kajabi shape: OAuth 2.0
|
|
25568
|
+
// authorization-code with PKCE (S256) and a public client
|
|
25569
|
+
// (token_endpoint_auth_method 'none') issued via Dynamic Client
|
|
25570
|
+
// Registration (RFC 7591). Values below are taken verbatim from the
|
|
25571
|
+
// metadata, not inferred:
|
|
25572
|
+
// - https://mcp.otter.ai/.well-known/oauth-protected-resource names the
|
|
25573
|
+
// AS as https://otter.ai/ and advertises scopes profile:read,
|
|
25574
|
+
// conversations:read;
|
|
25575
|
+
// - https://otter.ai/.well-known/oauth-authorization-server gives
|
|
25576
|
+
// authorize /oauth2/authorize, token /oauth/token, revoke
|
|
25577
|
+
// /oauth/revoke_token, register /oauth/register, PKCE S256, `none`,
|
|
25578
|
+
// and the refresh_token grant.
|
|
25579
|
+
// NOTE the authorize path is /oauth2/authorize while token/revoke live
|
|
25580
|
+
// under /oauth/ — that is Otter's own split, do not "normalise" it.
|
|
25581
|
+
// The prod client was registered 2026-10-10 against /oauth/register with
|
|
25582
|
+
// scope 'profile:read conversations:read' and BOTH API callbacks,
|
|
25583
|
+
// https://api.augmented.team/... and https://api.ninjafy.com/integrations/oauth/callback,
|
|
25584
|
+
// because redirect_uri follows API_PUBLIC_URL and the ENG-11060 flip makes
|
|
25585
|
+
// the ninjafy name canonical; Otter returns no RFC 7592 handle, so a redirect
|
|
25586
|
+
// cannot be added later without a new client and a re-consent per connection.
|
|
25587
|
+
// OAUTH_OTTER_CLIENT_ID is set from its output (docs/runbooks/otter-dogfood.md). Otter advertises ONLY
|
|
25588
|
+
// read scopes, so this integration is read-only by construction: there is
|
|
25589
|
+
// no write scope to request even by mistake.
|
|
25590
|
+
definitionId: "otter",
|
|
25591
|
+
authorizeUrl: "https://otter.ai/oauth2/authorize",
|
|
25592
|
+
tokenUrl: "https://otter.ai/oauth/token",
|
|
25593
|
+
revokeUrl: "https://otter.ai/oauth/revoke_token",
|
|
25594
|
+
defaultScopes: ["profile:read", "conversations:read"],
|
|
25595
|
+
supportsRefresh: true,
|
|
25596
|
+
extraAuthorizeParams: {},
|
|
25597
|
+
clientAuthMethod: "body",
|
|
25598
|
+
pkce: "S256",
|
|
25599
|
+
publicClient: true,
|
|
25600
|
+
mcpUrl: "https://mcp.otter.ai/mcp",
|
|
25601
|
+
// Curated surface (matches the catalog seed's defined_scopes[].tools).
|
|
25602
|
+
// These are the server's three tools, all read-only. The names are
|
|
25603
|
+
// Otter's own, quoted from the tools' descriptions ("use `otter_search`
|
|
25604
|
+
// first", "call otter_get_user_info() first"), not Composio's wrapped
|
|
25605
|
+
// OTTER_AI_MCP_* slugs. An allowlisted name the server does not advertise
|
|
25606
|
+
// is logged and SKIPPED by the proxy, so confirm against the first live
|
|
25607
|
+
// tools/list after a real consent (runbook Step 3).
|
|
25608
|
+
toolAllowlist: ["otter_get_user_info", "otter_search", "otter_fetch"]
|
|
25609
|
+
},
|
|
25565
25610
|
"notion-cli": {
|
|
25566
25611
|
// Notion's public OAuth app. Tokens are workspace-scoped and long-lived —
|
|
25567
25612
|
// Notion does not issue refresh_tokens, so `supportsRefresh: false` and
|
|
@@ -26195,6 +26240,34 @@ var INTEGRATION_REGISTRY = [
|
|
|
26195
26240
|
docs_url: "https://help.kajabi.com/articles/api-integrations/connect-kajabi-to-claude-or-chatgpt",
|
|
26196
26241
|
beta: true
|
|
26197
26242
|
},
|
|
26243
|
+
{
|
|
26244
|
+
id: "otter",
|
|
26245
|
+
name: "Otter.ai",
|
|
26246
|
+
category: "knowledge",
|
|
26247
|
+
description: "Read Otter.ai meetings: search recordings by date, attendee or topic, and read summaries, action items and full speaker-attributed transcripts.",
|
|
26248
|
+
// CS-2029: same remote streamable-HTTP MCP + OAuth pattern as Granola/Kajabi.
|
|
26249
|
+
// Otter's server implements the MCP discovery chain (RFC 9728 protected-
|
|
26250
|
+
// resource metadata at mcp.otter.ai → RFC 8414 AS metadata at otter.ai →
|
|
26251
|
+
// RFC 7591 registration); auth is OAuth 2.0 authorization-code with PKCE
|
|
26252
|
+
// (S256) and a public client registered via one-time Dynamic Client
|
|
26253
|
+
// Registration (scripts/dcr-register.ts against https://otter.ai/oauth/register
|
|
26254
|
+
// → OAUTH_OTTER_CLIENT_ID, --scope 'profile:read conversations:read').
|
|
26255
|
+
// Consent is brokered by the webapp through the shared
|
|
26256
|
+
// /integrations/oauth/authorize → /callback path, and the access_token
|
|
26257
|
+
// reaches the host via the generic remote-oauth-proxy
|
|
26258
|
+
// (OAUTH_PROVIDERS.otter.mcpUrl). Read-only by construction: Otter
|
|
26259
|
+
// advertises no write scope.
|
|
26260
|
+
supported_auth_types: ["oauth2"],
|
|
26261
|
+
capabilities: [
|
|
26262
|
+
{ id: "otter:read", name: "Read Meetings & Transcripts", description: "Find recorded meetings by date, attendee, topic or title, and read their summaries, action items, outlines and full transcripts (otter_get_user_info, otter_search, otter_fetch)", access: "read" }
|
|
26263
|
+
],
|
|
26264
|
+
// Otter's own Help Center article for the MCP server (CodeRabbit, #6906). It
|
|
26265
|
+
// exists even though help.otter.ai answers 403 to non-browser clients; the
|
|
26266
|
+
// help-centre API confirmed it (title "Otter MCP Server"). The MCP endpoint
|
|
26267
|
+
// itself is a JSON-RPC URL, not a page (Obi Wan 8305072d5414).
|
|
26268
|
+
docs_url: "https://help.otter.ai/hc/en-us/articles/35287607569687-Otter-MCP-Server",
|
|
26269
|
+
beta: true
|
|
26270
|
+
},
|
|
26198
26271
|
{
|
|
26199
26272
|
id: "anchor-browser",
|
|
26200
26273
|
name: "Anchor Browser",
|
package/dist/mcp/origami.js
CHANGED
|
@@ -39711,6 +39711,51 @@ var OAUTH_PROVIDERS = {
|
|
|
39711
39711
|
}
|
|
39712
39712
|
]
|
|
39713
39713
|
},
|
|
39714
|
+
"otter": {
|
|
39715
|
+
// CS-2029: Otter.ai's official MCP — remote streamable-HTTP at
|
|
39716
|
+
// https://mcp.otter.ai/mcp. Same Granola/Kajabi shape: OAuth 2.0
|
|
39717
|
+
// authorization-code with PKCE (S256) and a public client
|
|
39718
|
+
// (token_endpoint_auth_method 'none') issued via Dynamic Client
|
|
39719
|
+
// Registration (RFC 7591). Values below are taken verbatim from the
|
|
39720
|
+
// metadata, not inferred:
|
|
39721
|
+
// - https://mcp.otter.ai/.well-known/oauth-protected-resource names the
|
|
39722
|
+
// AS as https://otter.ai/ and advertises scopes profile:read,
|
|
39723
|
+
// conversations:read;
|
|
39724
|
+
// - https://otter.ai/.well-known/oauth-authorization-server gives
|
|
39725
|
+
// authorize /oauth2/authorize, token /oauth/token, revoke
|
|
39726
|
+
// /oauth/revoke_token, register /oauth/register, PKCE S256, `none`,
|
|
39727
|
+
// and the refresh_token grant.
|
|
39728
|
+
// NOTE the authorize path is /oauth2/authorize while token/revoke live
|
|
39729
|
+
// under /oauth/ — that is Otter's own split, do not "normalise" it.
|
|
39730
|
+
// The prod client was registered 2026-10-10 against /oauth/register with
|
|
39731
|
+
// scope 'profile:read conversations:read' and BOTH API callbacks,
|
|
39732
|
+
// https://api.augmented.team/... and https://api.ninjafy.com/integrations/oauth/callback,
|
|
39733
|
+
// because redirect_uri follows API_PUBLIC_URL and the ENG-11060 flip makes
|
|
39734
|
+
// the ninjafy name canonical; Otter returns no RFC 7592 handle, so a redirect
|
|
39735
|
+
// cannot be added later without a new client and a re-consent per connection.
|
|
39736
|
+
// OAUTH_OTTER_CLIENT_ID is set from its output (docs/runbooks/otter-dogfood.md). Otter advertises ONLY
|
|
39737
|
+
// read scopes, so this integration is read-only by construction: there is
|
|
39738
|
+
// no write scope to request even by mistake.
|
|
39739
|
+
definitionId: "otter",
|
|
39740
|
+
authorizeUrl: "https://otter.ai/oauth2/authorize",
|
|
39741
|
+
tokenUrl: "https://otter.ai/oauth/token",
|
|
39742
|
+
revokeUrl: "https://otter.ai/oauth/revoke_token",
|
|
39743
|
+
defaultScopes: ["profile:read", "conversations:read"],
|
|
39744
|
+
supportsRefresh: true,
|
|
39745
|
+
extraAuthorizeParams: {},
|
|
39746
|
+
clientAuthMethod: "body",
|
|
39747
|
+
pkce: "S256",
|
|
39748
|
+
publicClient: true,
|
|
39749
|
+
mcpUrl: "https://mcp.otter.ai/mcp",
|
|
39750
|
+
// Curated surface (matches the catalog seed's defined_scopes[].tools).
|
|
39751
|
+
// These are the server's three tools, all read-only. The names are
|
|
39752
|
+
// Otter's own, quoted from the tools' descriptions ("use `otter_search`
|
|
39753
|
+
// first", "call otter_get_user_info() first"), not Composio's wrapped
|
|
39754
|
+
// OTTER_AI_MCP_* slugs. An allowlisted name the server does not advertise
|
|
39755
|
+
// is logged and SKIPPED by the proxy, so confirm against the first live
|
|
39756
|
+
// tools/list after a real consent (runbook Step 3).
|
|
39757
|
+
toolAllowlist: ["otter_get_user_info", "otter_search", "otter_fetch"]
|
|
39758
|
+
},
|
|
39714
39759
|
"notion-cli": {
|
|
39715
39760
|
// Notion's public OAuth app. Tokens are workspace-scoped and long-lived —
|
|
39716
39761
|
// Notion does not issue refresh_tokens, so `supportsRefresh: false` and
|
|
@@ -40344,6 +40389,34 @@ var INTEGRATION_REGISTRY = [
|
|
|
40344
40389
|
docs_url: "https://help.kajabi.com/articles/api-integrations/connect-kajabi-to-claude-or-chatgpt",
|
|
40345
40390
|
beta: true
|
|
40346
40391
|
},
|
|
40392
|
+
{
|
|
40393
|
+
id: "otter",
|
|
40394
|
+
name: "Otter.ai",
|
|
40395
|
+
category: "knowledge",
|
|
40396
|
+
description: "Read Otter.ai meetings: search recordings by date, attendee or topic, and read summaries, action items and full speaker-attributed transcripts.",
|
|
40397
|
+
// CS-2029: same remote streamable-HTTP MCP + OAuth pattern as Granola/Kajabi.
|
|
40398
|
+
// Otter's server implements the MCP discovery chain (RFC 9728 protected-
|
|
40399
|
+
// resource metadata at mcp.otter.ai → RFC 8414 AS metadata at otter.ai →
|
|
40400
|
+
// RFC 7591 registration); auth is OAuth 2.0 authorization-code with PKCE
|
|
40401
|
+
// (S256) and a public client registered via one-time Dynamic Client
|
|
40402
|
+
// Registration (scripts/dcr-register.ts against https://otter.ai/oauth/register
|
|
40403
|
+
// → OAUTH_OTTER_CLIENT_ID, --scope 'profile:read conversations:read').
|
|
40404
|
+
// Consent is brokered by the webapp through the shared
|
|
40405
|
+
// /integrations/oauth/authorize → /callback path, and the access_token
|
|
40406
|
+
// reaches the host via the generic remote-oauth-proxy
|
|
40407
|
+
// (OAUTH_PROVIDERS.otter.mcpUrl). Read-only by construction: Otter
|
|
40408
|
+
// advertises no write scope.
|
|
40409
|
+
supported_auth_types: ["oauth2"],
|
|
40410
|
+
capabilities: [
|
|
40411
|
+
{ id: "otter:read", name: "Read Meetings & Transcripts", description: "Find recorded meetings by date, attendee, topic or title, and read their summaries, action items, outlines and full transcripts (otter_get_user_info, otter_search, otter_fetch)", access: "read" }
|
|
40412
|
+
],
|
|
40413
|
+
// Otter's own Help Center article for the MCP server (CodeRabbit, #6906). It
|
|
40414
|
+
// exists even though help.otter.ai answers 403 to non-browser clients; the
|
|
40415
|
+
// help-centre API confirmed it (title "Otter MCP Server"). The MCP endpoint
|
|
40416
|
+
// itself is a JSON-RPC URL, not a page (Obi Wan 8305072d5414).
|
|
40417
|
+
docs_url: "https://help.otter.ai/hc/en-us/articles/35287607569687-Otter-MCP-Server",
|
|
40418
|
+
beta: true
|
|
40419
|
+
},
|
|
40347
40420
|
{
|
|
40348
40421
|
id: "anchor-browser",
|
|
40349
40422
|
name: "Anchor Browser",
|
|
@@ -34068,6 +34068,51 @@ var OAUTH_PROVIDERS = {
|
|
|
34068
34068
|
}
|
|
34069
34069
|
]
|
|
34070
34070
|
},
|
|
34071
|
+
"otter": {
|
|
34072
|
+
// CS-2029: Otter.ai's official MCP — remote streamable-HTTP at
|
|
34073
|
+
// https://mcp.otter.ai/mcp. Same Granola/Kajabi shape: OAuth 2.0
|
|
34074
|
+
// authorization-code with PKCE (S256) and a public client
|
|
34075
|
+
// (token_endpoint_auth_method 'none') issued via Dynamic Client
|
|
34076
|
+
// Registration (RFC 7591). Values below are taken verbatim from the
|
|
34077
|
+
// metadata, not inferred:
|
|
34078
|
+
// - https://mcp.otter.ai/.well-known/oauth-protected-resource names the
|
|
34079
|
+
// AS as https://otter.ai/ and advertises scopes profile:read,
|
|
34080
|
+
// conversations:read;
|
|
34081
|
+
// - https://otter.ai/.well-known/oauth-authorization-server gives
|
|
34082
|
+
// authorize /oauth2/authorize, token /oauth/token, revoke
|
|
34083
|
+
// /oauth/revoke_token, register /oauth/register, PKCE S256, `none`,
|
|
34084
|
+
// and the refresh_token grant.
|
|
34085
|
+
// NOTE the authorize path is /oauth2/authorize while token/revoke live
|
|
34086
|
+
// under /oauth/ — that is Otter's own split, do not "normalise" it.
|
|
34087
|
+
// The prod client was registered 2026-10-10 against /oauth/register with
|
|
34088
|
+
// scope 'profile:read conversations:read' and BOTH API callbacks,
|
|
34089
|
+
// https://api.augmented.team/... and https://api.ninjafy.com/integrations/oauth/callback,
|
|
34090
|
+
// because redirect_uri follows API_PUBLIC_URL and the ENG-11060 flip makes
|
|
34091
|
+
// the ninjafy name canonical; Otter returns no RFC 7592 handle, so a redirect
|
|
34092
|
+
// cannot be added later without a new client and a re-consent per connection.
|
|
34093
|
+
// OAUTH_OTTER_CLIENT_ID is set from its output (docs/runbooks/otter-dogfood.md). Otter advertises ONLY
|
|
34094
|
+
// read scopes, so this integration is read-only by construction: there is
|
|
34095
|
+
// no write scope to request even by mistake.
|
|
34096
|
+
definitionId: "otter",
|
|
34097
|
+
authorizeUrl: "https://otter.ai/oauth2/authorize",
|
|
34098
|
+
tokenUrl: "https://otter.ai/oauth/token",
|
|
34099
|
+
revokeUrl: "https://otter.ai/oauth/revoke_token",
|
|
34100
|
+
defaultScopes: ["profile:read", "conversations:read"],
|
|
34101
|
+
supportsRefresh: true,
|
|
34102
|
+
extraAuthorizeParams: {},
|
|
34103
|
+
clientAuthMethod: "body",
|
|
34104
|
+
pkce: "S256",
|
|
34105
|
+
publicClient: true,
|
|
34106
|
+
mcpUrl: "https://mcp.otter.ai/mcp",
|
|
34107
|
+
// Curated surface (matches the catalog seed's defined_scopes[].tools).
|
|
34108
|
+
// These are the server's three tools, all read-only. The names are
|
|
34109
|
+
// Otter's own, quoted from the tools' descriptions ("use `otter_search`
|
|
34110
|
+
// first", "call otter_get_user_info() first"), not Composio's wrapped
|
|
34111
|
+
// OTTER_AI_MCP_* slugs. An allowlisted name the server does not advertise
|
|
34112
|
+
// is logged and SKIPPED by the proxy, so confirm against the first live
|
|
34113
|
+
// tools/list after a real consent (runbook Step 3).
|
|
34114
|
+
toolAllowlist: ["otter_get_user_info", "otter_search", "otter_fetch"]
|
|
34115
|
+
},
|
|
34071
34116
|
"notion-cli": {
|
|
34072
34117
|
// Notion's public OAuth app. Tokens are workspace-scoped and long-lived —
|
|
34073
34118
|
// Notion does not issue refresh_tokens, so `supportsRefresh: false` and
|
|
@@ -34707,6 +34752,34 @@ var INTEGRATION_REGISTRY = [
|
|
|
34707
34752
|
docs_url: "https://help.kajabi.com/articles/api-integrations/connect-kajabi-to-claude-or-chatgpt",
|
|
34708
34753
|
beta: true
|
|
34709
34754
|
},
|
|
34755
|
+
{
|
|
34756
|
+
id: "otter",
|
|
34757
|
+
name: "Otter.ai",
|
|
34758
|
+
category: "knowledge",
|
|
34759
|
+
description: "Read Otter.ai meetings: search recordings by date, attendee or topic, and read summaries, action items and full speaker-attributed transcripts.",
|
|
34760
|
+
// CS-2029: same remote streamable-HTTP MCP + OAuth pattern as Granola/Kajabi.
|
|
34761
|
+
// Otter's server implements the MCP discovery chain (RFC 9728 protected-
|
|
34762
|
+
// resource metadata at mcp.otter.ai → RFC 8414 AS metadata at otter.ai →
|
|
34763
|
+
// RFC 7591 registration); auth is OAuth 2.0 authorization-code with PKCE
|
|
34764
|
+
// (S256) and a public client registered via one-time Dynamic Client
|
|
34765
|
+
// Registration (scripts/dcr-register.ts against https://otter.ai/oauth/register
|
|
34766
|
+
// → OAUTH_OTTER_CLIENT_ID, --scope 'profile:read conversations:read').
|
|
34767
|
+
// Consent is brokered by the webapp through the shared
|
|
34768
|
+
// /integrations/oauth/authorize → /callback path, and the access_token
|
|
34769
|
+
// reaches the host via the generic remote-oauth-proxy
|
|
34770
|
+
// (OAUTH_PROVIDERS.otter.mcpUrl). Read-only by construction: Otter
|
|
34771
|
+
// advertises no write scope.
|
|
34772
|
+
supported_auth_types: ["oauth2"],
|
|
34773
|
+
capabilities: [
|
|
34774
|
+
{ id: "otter:read", name: "Read Meetings & Transcripts", description: "Find recorded meetings by date, attendee, topic or title, and read their summaries, action items, outlines and full transcripts (otter_get_user_info, otter_search, otter_fetch)", access: "read" }
|
|
34775
|
+
],
|
|
34776
|
+
// Otter's own Help Center article for the MCP server (CodeRabbit, #6906). It
|
|
34777
|
+
// exists even though help.otter.ai answers 403 to non-browser clients; the
|
|
34778
|
+
// help-centre API confirmed it (title "Otter MCP Server"). The MCP endpoint
|
|
34779
|
+
// itself is a JSON-RPC URL, not a page (Obi Wan 8305072d5414).
|
|
34780
|
+
docs_url: "https://help.otter.ai/hc/en-us/articles/35287607569687-Otter-MCP-Server",
|
|
34781
|
+
beta: true
|
|
34782
|
+
},
|
|
34710
34783
|
{
|
|
34711
34784
|
id: "anchor-browser",
|
|
34712
34785
|
name: "Anchor Browser",
|
|
@@ -34260,6 +34260,51 @@ var OAUTH_PROVIDERS = {
|
|
|
34260
34260
|
}
|
|
34261
34261
|
]
|
|
34262
34262
|
},
|
|
34263
|
+
"otter": {
|
|
34264
|
+
// CS-2029: Otter.ai's official MCP — remote streamable-HTTP at
|
|
34265
|
+
// https://mcp.otter.ai/mcp. Same Granola/Kajabi shape: OAuth 2.0
|
|
34266
|
+
// authorization-code with PKCE (S256) and a public client
|
|
34267
|
+
// (token_endpoint_auth_method 'none') issued via Dynamic Client
|
|
34268
|
+
// Registration (RFC 7591). Values below are taken verbatim from the
|
|
34269
|
+
// metadata, not inferred:
|
|
34270
|
+
// - https://mcp.otter.ai/.well-known/oauth-protected-resource names the
|
|
34271
|
+
// AS as https://otter.ai/ and advertises scopes profile:read,
|
|
34272
|
+
// conversations:read;
|
|
34273
|
+
// - https://otter.ai/.well-known/oauth-authorization-server gives
|
|
34274
|
+
// authorize /oauth2/authorize, token /oauth/token, revoke
|
|
34275
|
+
// /oauth/revoke_token, register /oauth/register, PKCE S256, `none`,
|
|
34276
|
+
// and the refresh_token grant.
|
|
34277
|
+
// NOTE the authorize path is /oauth2/authorize while token/revoke live
|
|
34278
|
+
// under /oauth/ — that is Otter's own split, do not "normalise" it.
|
|
34279
|
+
// The prod client was registered 2026-10-10 against /oauth/register with
|
|
34280
|
+
// scope 'profile:read conversations:read' and BOTH API callbacks,
|
|
34281
|
+
// https://api.augmented.team/... and https://api.ninjafy.com/integrations/oauth/callback,
|
|
34282
|
+
// because redirect_uri follows API_PUBLIC_URL and the ENG-11060 flip makes
|
|
34283
|
+
// the ninjafy name canonical; Otter returns no RFC 7592 handle, so a redirect
|
|
34284
|
+
// cannot be added later without a new client and a re-consent per connection.
|
|
34285
|
+
// OAUTH_OTTER_CLIENT_ID is set from its output (docs/runbooks/otter-dogfood.md). Otter advertises ONLY
|
|
34286
|
+
// read scopes, so this integration is read-only by construction: there is
|
|
34287
|
+
// no write scope to request even by mistake.
|
|
34288
|
+
definitionId: "otter",
|
|
34289
|
+
authorizeUrl: "https://otter.ai/oauth2/authorize",
|
|
34290
|
+
tokenUrl: "https://otter.ai/oauth/token",
|
|
34291
|
+
revokeUrl: "https://otter.ai/oauth/revoke_token",
|
|
34292
|
+
defaultScopes: ["profile:read", "conversations:read"],
|
|
34293
|
+
supportsRefresh: true,
|
|
34294
|
+
extraAuthorizeParams: {},
|
|
34295
|
+
clientAuthMethod: "body",
|
|
34296
|
+
pkce: "S256",
|
|
34297
|
+
publicClient: true,
|
|
34298
|
+
mcpUrl: "https://mcp.otter.ai/mcp",
|
|
34299
|
+
// Curated surface (matches the catalog seed's defined_scopes[].tools).
|
|
34300
|
+
// These are the server's three tools, all read-only. The names are
|
|
34301
|
+
// Otter's own, quoted from the tools' descriptions ("use `otter_search`
|
|
34302
|
+
// first", "call otter_get_user_info() first"), not Composio's wrapped
|
|
34303
|
+
// OTTER_AI_MCP_* slugs. An allowlisted name the server does not advertise
|
|
34304
|
+
// is logged and SKIPPED by the proxy, so confirm against the first live
|
|
34305
|
+
// tools/list after a real consent (runbook Step 3).
|
|
34306
|
+
toolAllowlist: ["otter_get_user_info", "otter_search", "otter_fetch"]
|
|
34307
|
+
},
|
|
34263
34308
|
"notion-cli": {
|
|
34264
34309
|
// Notion's public OAuth app. Tokens are workspace-scoped and long-lived —
|
|
34265
34310
|
// Notion does not issue refresh_tokens, so `supportsRefresh: false` and
|
|
@@ -34893,6 +34938,34 @@ var INTEGRATION_REGISTRY = [
|
|
|
34893
34938
|
docs_url: "https://help.kajabi.com/articles/api-integrations/connect-kajabi-to-claude-or-chatgpt",
|
|
34894
34939
|
beta: true
|
|
34895
34940
|
},
|
|
34941
|
+
{
|
|
34942
|
+
id: "otter",
|
|
34943
|
+
name: "Otter.ai",
|
|
34944
|
+
category: "knowledge",
|
|
34945
|
+
description: "Read Otter.ai meetings: search recordings by date, attendee or topic, and read summaries, action items and full speaker-attributed transcripts.",
|
|
34946
|
+
// CS-2029: same remote streamable-HTTP MCP + OAuth pattern as Granola/Kajabi.
|
|
34947
|
+
// Otter's server implements the MCP discovery chain (RFC 9728 protected-
|
|
34948
|
+
// resource metadata at mcp.otter.ai → RFC 8414 AS metadata at otter.ai →
|
|
34949
|
+
// RFC 7591 registration); auth is OAuth 2.0 authorization-code with PKCE
|
|
34950
|
+
// (S256) and a public client registered via one-time Dynamic Client
|
|
34951
|
+
// Registration (scripts/dcr-register.ts against https://otter.ai/oauth/register
|
|
34952
|
+
// → OAUTH_OTTER_CLIENT_ID, --scope 'profile:read conversations:read').
|
|
34953
|
+
// Consent is brokered by the webapp through the shared
|
|
34954
|
+
// /integrations/oauth/authorize → /callback path, and the access_token
|
|
34955
|
+
// reaches the host via the generic remote-oauth-proxy
|
|
34956
|
+
// (OAUTH_PROVIDERS.otter.mcpUrl). Read-only by construction: Otter
|
|
34957
|
+
// advertises no write scope.
|
|
34958
|
+
supported_auth_types: ["oauth2"],
|
|
34959
|
+
capabilities: [
|
|
34960
|
+
{ id: "otter:read", name: "Read Meetings & Transcripts", description: "Find recorded meetings by date, attendee, topic or title, and read their summaries, action items, outlines and full transcripts (otter_get_user_info, otter_search, otter_fetch)", access: "read" }
|
|
34961
|
+
],
|
|
34962
|
+
// Otter's own Help Center article for the MCP server (CodeRabbit, #6906). It
|
|
34963
|
+
// exists even though help.otter.ai answers 403 to non-browser clients; the
|
|
34964
|
+
// help-centre API confirmed it (title "Otter MCP Server"). The MCP endpoint
|
|
34965
|
+
// itself is a JSON-RPC URL, not a page (Obi Wan 8305072d5414).
|
|
34966
|
+
docs_url: "https://help.otter.ai/hc/en-us/articles/35287607569687-Otter-MCP-Server",
|
|
34967
|
+
beta: true
|
|
34968
|
+
},
|
|
34896
34969
|
{
|
|
34897
34970
|
id: "anchor-browser",
|
|
34898
34971
|
name: "Anchor Browser",
|
|
@@ -68,8 +68,8 @@ import {
|
|
|
68
68
|
writeDirectChatSessionState,
|
|
69
69
|
writeEgressAllowlist,
|
|
70
70
|
writePersistentClaudeWrapper
|
|
71
|
-
} from "./chunk-
|
|
72
|
-
import "./chunk-
|
|
71
|
+
} from "./chunk-JX7ZXCNZ.js";
|
|
72
|
+
import "./chunk-OBZB6MUE.js";
|
|
73
73
|
import "./chunk-OCMJ5E6J.js";
|
|
74
74
|
import "./chunk-XWVM4KPK.js";
|
|
75
75
|
import "./chunk-EL5MWGGH.js";
|
|
@@ -145,4 +145,4 @@ export {
|
|
|
145
145
|
writeEgressAllowlist,
|
|
146
146
|
writePersistentClaudeWrapper
|
|
147
147
|
};
|
|
148
|
-
//# sourceMappingURL=persistent-session-
|
|
148
|
+
//# sourceMappingURL=persistent-session-6KIQF4O7.js.map
|