@agent-native/core 0.105.0 → 0.106.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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +33 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AssistantChat.tsx +4 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +5 -1
- package/corpus/core/src/client/composer/PromptComposer.tsx +8 -0
- package/corpus/core/src/client/composer/TiptapComposer.tsx +38 -1
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +107 -32
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +33 -0
- package/corpus/core/src/client/resources/use-mcp-servers.ts +1 -0
- package/corpus/core/src/client/use-chat-models.ts +10 -2
- package/corpus/core/src/connections/catalog.ts +107 -6
- package/corpus/core/src/localization/default-messages.ts +2 -0
- package/corpus/core/src/mcp/actions/call-mcp-tool.ts +18 -0
- package/corpus/core/src/mcp/actions/list-mcp-tools.ts +18 -0
- package/corpus/core/src/mcp-client/app-api.ts +136 -0
- package/corpus/core/src/mcp-client/index.ts +21 -0
- package/corpus/core/src/mcp-client/oauth-client.ts +462 -0
- package/corpus/core/src/mcp-client/oauth-routes.ts +307 -0
- package/corpus/core/src/mcp-client/remote-store.ts +93 -118
- package/corpus/core/src/mcp-client/remote-url.ts +97 -0
- package/corpus/core/src/mcp-client/routes.ts +11 -0
- package/corpus/core/src/oauth-tokens/store.ts +10 -4
- package/corpus/core/src/provider-api/index.ts +690 -55
- package/corpus/core/src/secrets/register-framework-secrets.ts +30 -0
- package/corpus/core/src/server/action-discovery.ts +2 -0
- package/corpus/core/src/server/core-routes-plugin.ts +9 -1
- package/corpus/core/src/server/workspace-provider-oauth.ts +448 -61
- package/corpus/core/src/templates/default/AGENTS.md +9 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +46 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +2 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +61 -0
- package/corpus/templates/analytics/server/handlers/jira.ts +7 -0
- package/corpus/templates/analytics/server/lib/jira.ts +14 -42
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +11 -0
- package/corpus/templates/dispatch/app/routes/integrations.tsx +57 -4
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +2 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +5 -2
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts +2 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +5 -2
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +4 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +13 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +58 -14
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +9 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +13 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +1 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/use-chat-models.d.ts +1 -0
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +8 -2
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/connections/catalog.d.ts +78 -7
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +97 -6
- package/dist/connections/catalog.js.map +1 -1
- package/dist/localization/default-messages.d.ts +2 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +2 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/actions/call-mcp-tool.d.ts +7 -0
- package/dist/mcp/actions/call-mcp-tool.d.ts.map +1 -0
- package/dist/mcp/actions/call-mcp-tool.js +15 -0
- package/dist/mcp/actions/call-mcp-tool.js.map +1 -0
- package/dist/mcp/actions/list-mcp-tools.d.ts +5 -0
- package/dist/mcp/actions/list-mcp-tools.d.ts.map +1 -0
- package/dist/mcp/actions/list-mcp-tools.js +16 -0
- package/dist/mcp/actions/list-mcp-tools.js.map +1 -0
- package/dist/mcp-client/app-api.d.ts +34 -0
- package/dist/mcp-client/app-api.d.ts.map +1 -0
- package/dist/mcp-client/app-api.js +94 -0
- package/dist/mcp-client/app-api.js.map +1 -0
- package/dist/mcp-client/index.d.ts +3 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +3 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/oauth-client.d.ts +113 -0
- package/dist/mcp-client/oauth-client.d.ts.map +1 -0
- package/dist/mcp-client/oauth-client.js +316 -0
- package/dist/mcp-client/oauth-client.js.map +1 -0
- package/dist/mcp-client/oauth-routes.d.ts +25 -0
- package/dist/mcp-client/oauth-routes.d.ts.map +1 -0
- package/dist/mcp-client/oauth-routes.js +218 -0
- package/dist/mcp-client/oauth-routes.js.map +1 -0
- package/dist/mcp-client/remote-store.d.ts +21 -6
- package/dist/mcp-client/remote-store.d.ts.map +1 -1
- package/dist/mcp-client/remote-store.js +72 -124
- package/dist/mcp-client/remote-store.js.map +1 -1
- package/dist/mcp-client/remote-url.d.ts +8 -0
- package/dist/mcp-client/remote-url.d.ts.map +1 -0
- package/dist/mcp-client/remote-url.js +103 -0
- package/dist/mcp-client/remote-url.js.map +1 -0
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +9 -0
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +2 -2
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +10 -6
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/provider-api/index.d.ts +14 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +499 -61
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +28 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +2 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +9 -1
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +10 -3
- package/dist/server/workspace-provider-oauth.d.ts.map +1 -1
- package/dist/server/workspace-provider-oauth.js +325 -43
- package/dist/server/workspace-provider-oauth.js.map +1 -1
- package/dist/templates/default/AGENTS.md +9 -7
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +46 -0
- package/package.json +2 -2
- package/src/templates/default/AGENTS.md +9 -7
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +46 -0
|
@@ -27,6 +27,8 @@ export type WorkspaceConnectionProviderId =
|
|
|
27
27
|
| "gmail"
|
|
28
28
|
| "google_drive"
|
|
29
29
|
| "hubspot"
|
|
30
|
+
| "jira"
|
|
31
|
+
| "sentry"
|
|
30
32
|
| "granola"
|
|
31
33
|
| "clips"
|
|
32
34
|
| "generic";
|
|
@@ -91,12 +93,18 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
91
93
|
credentialKeys: [
|
|
92
94
|
{
|
|
93
95
|
key: "GITHUB_TOKEN",
|
|
94
|
-
label: "GitHub token",
|
|
96
|
+
label: "GitHub token (fallback)",
|
|
95
97
|
description:
|
|
96
|
-
"
|
|
97
|
-
required:
|
|
98
|
+
"Optional fine-grained token fallback. OAuth is preferred for new connections.",
|
|
99
|
+
required: false,
|
|
98
100
|
},
|
|
99
101
|
],
|
|
102
|
+
oauth: {
|
|
103
|
+
provider: "github",
|
|
104
|
+
authorizationUrl: "https://github.com/login/oauth/authorize",
|
|
105
|
+
tokenUrl: "https://github.com/login/oauth/access_token",
|
|
106
|
+
scopes: ["repo", "read:org", "read:user", "user:email"],
|
|
107
|
+
},
|
|
100
108
|
capabilities: ["search", "import", "code", "docs"],
|
|
101
109
|
recommendedTemplateUses: ["brain", "analytics", "dispatch"],
|
|
102
110
|
}),
|
|
@@ -199,15 +207,108 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
199
207
|
credentialKeys: [
|
|
200
208
|
{
|
|
201
209
|
key: "HUBSPOT_PRIVATE_APP_TOKEN",
|
|
202
|
-
label: "HubSpot private app token",
|
|
210
|
+
label: "HubSpot private app token (fallback)",
|
|
203
211
|
description:
|
|
204
|
-
"
|
|
205
|
-
required:
|
|
212
|
+
"Optional private app token fallback. OAuth is preferred for new connections.",
|
|
213
|
+
required: false,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
key: "HUBSPOT_ACCESS_TOKEN",
|
|
217
|
+
label: "HubSpot access token (fallback)",
|
|
218
|
+
description:
|
|
219
|
+
"Optional legacy access token fallback for existing HubSpot setups.",
|
|
220
|
+
required: false,
|
|
206
221
|
},
|
|
207
222
|
],
|
|
223
|
+
oauth: {
|
|
224
|
+
provider: "hubspot",
|
|
225
|
+
authorizationUrl: "https://app.hubspot.com/oauth/authorize",
|
|
226
|
+
tokenUrl: "https://api.hubapi.com/oauth/v3/token",
|
|
227
|
+
refreshUrl: "https://api.hubapi.com/oauth/v3/token",
|
|
228
|
+
scopes: [
|
|
229
|
+
"oauth",
|
|
230
|
+
"crm.objects.contacts.read",
|
|
231
|
+
"crm.objects.companies.read",
|
|
232
|
+
"crm.objects.deals.read",
|
|
233
|
+
"crm.objects.tickets.read",
|
|
234
|
+
"crm.schemas.contacts.read",
|
|
235
|
+
"crm.schemas.companies.read",
|
|
236
|
+
"crm.schemas.deals.read",
|
|
237
|
+
"crm.schemas.tickets.read",
|
|
238
|
+
],
|
|
239
|
+
},
|
|
208
240
|
capabilities: ["search", "import", "crm"],
|
|
209
241
|
recommendedTemplateUses: ["analytics", "brain", "mail", "dispatch"],
|
|
210
242
|
}),
|
|
243
|
+
defineWorkspaceConnectionProvider({
|
|
244
|
+
id: "jira",
|
|
245
|
+
label: "Jira Cloud",
|
|
246
|
+
description:
|
|
247
|
+
"Projects, issues, sprints, and delivery context for engineering analytics and product workflows.",
|
|
248
|
+
credentialKeys: [
|
|
249
|
+
{
|
|
250
|
+
key: "JIRA_BASE_URL",
|
|
251
|
+
label: "Jira base URL (fallback)",
|
|
252
|
+
description:
|
|
253
|
+
"Optional site URL for API-token fallback connections. OAuth connections discover their site automatically.",
|
|
254
|
+
required: false,
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
key: "JIRA_USER_EMAIL",
|
|
258
|
+
label: "Jira email (fallback)",
|
|
259
|
+
description:
|
|
260
|
+
"Optional Atlassian account email for API-token fallback connections.",
|
|
261
|
+
required: false,
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
key: "JIRA_API_TOKEN",
|
|
265
|
+
label: "Jira API token (fallback)",
|
|
266
|
+
description:
|
|
267
|
+
"Optional API token fallback for existing Jira Cloud setups. OAuth is preferred for new connections.",
|
|
268
|
+
required: false,
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
oauth: {
|
|
272
|
+
provider: "jira",
|
|
273
|
+
authorizationUrl: "https://auth.atlassian.com/authorize",
|
|
274
|
+
tokenUrl: "https://auth.atlassian.com/oauth/token",
|
|
275
|
+
refreshUrl: "https://auth.atlassian.com/oauth/token",
|
|
276
|
+
scopes: ["read:jira-work", "read:jira-user", "offline_access"],
|
|
277
|
+
},
|
|
278
|
+
capabilities: ["search", "import", "code", "docs"],
|
|
279
|
+
recommendedTemplateUses: ["analytics", "brain", "dispatch"],
|
|
280
|
+
}),
|
|
281
|
+
defineWorkspaceConnectionProvider({
|
|
282
|
+
id: "sentry",
|
|
283
|
+
label: "Sentry",
|
|
284
|
+
description:
|
|
285
|
+
"Error tracking, performance issues, projects, and release context for engineering analytics.",
|
|
286
|
+
credentialKeys: [
|
|
287
|
+
{
|
|
288
|
+
key: "SENTRY_AUTH_TOKEN",
|
|
289
|
+
label: "Sentry auth token (fallback)",
|
|
290
|
+
description:
|
|
291
|
+
"Optional auth token fallback for self-hosted or local Sentry setups. OAuth is preferred for sentry.io.",
|
|
292
|
+
required: false,
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
key: "SENTRY_SERVER_TOKEN",
|
|
296
|
+
label: "Sentry server token (fallback)",
|
|
297
|
+
description:
|
|
298
|
+
"Optional server token fallback for existing Sentry deployments.",
|
|
299
|
+
required: false,
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
oauth: {
|
|
303
|
+
provider: "sentry",
|
|
304
|
+
authorizationUrl: "https://sentry.io/oauth/authorize/",
|
|
305
|
+
tokenUrl: "https://sentry.io/oauth/token/",
|
|
306
|
+
refreshUrl: "https://sentry.io/oauth/token/",
|
|
307
|
+
scopes: ["org:read", "project:read", "event:read", "team:read"],
|
|
308
|
+
},
|
|
309
|
+
capabilities: ["search", "import", "docs"],
|
|
310
|
+
recommendedTemplateUses: ["analytics", "brain", "dispatch"],
|
|
311
|
+
}),
|
|
211
312
|
defineWorkspaceConnectionProvider({
|
|
212
313
|
id: "granola",
|
|
213
314
|
label: "Granola",
|
|
@@ -690,6 +690,7 @@ const messages = {
|
|
|
690
690
|
connected: "Connected",
|
|
691
691
|
configure: "Configure",
|
|
692
692
|
connect: "Connect",
|
|
693
|
+
connectWithOAuth: "Connect with OAuth",
|
|
693
694
|
backToIntegrations: "Back to integrations",
|
|
694
695
|
customTitle: "Add custom MCP server",
|
|
695
696
|
configureTitle: "Configure {{name}}",
|
|
@@ -705,6 +706,7 @@ const messages = {
|
|
|
705
706
|
organization: "Organization",
|
|
706
707
|
orgNoOrg: "Join an organization to share MCP servers",
|
|
707
708
|
orgAdminOnly: "Only owners and admins can add org-scope servers",
|
|
709
|
+
serverNameRequired: "Enter a server name before connecting with OAuth.",
|
|
708
710
|
serverName: "Server name",
|
|
709
711
|
url: "URL",
|
|
710
712
|
fieldDescription: "Description",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { defineAction } from "../../action.js";
|
|
4
|
+
import { callMcpTool } from "../../mcp-client/app-api.js";
|
|
5
|
+
|
|
6
|
+
export default defineAction({
|
|
7
|
+
description:
|
|
8
|
+
"Call an MCP tool visible to the authenticated app request by server id and original tool name. Server credentials and tokens are never exposed.",
|
|
9
|
+
agentTool: false,
|
|
10
|
+
requiresAuth: true,
|
|
11
|
+
schema: z.object({
|
|
12
|
+
serverId: z.string().trim().min(1),
|
|
13
|
+
toolName: z.string().trim().min(1),
|
|
14
|
+
arguments: z.record(z.string(), z.unknown()).default({}),
|
|
15
|
+
}),
|
|
16
|
+
run: ({ serverId, toolName, arguments: args }) =>
|
|
17
|
+
callMcpTool(serverId, toolName, args),
|
|
18
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { defineAction } from "../../action.js";
|
|
4
|
+
import { listVisibleMcpTools } from "../../mcp-client/app-api.js";
|
|
5
|
+
|
|
6
|
+
export default defineAction({
|
|
7
|
+
description:
|
|
8
|
+
"List MCP tools visible to the authenticated app request. Returns tool contracts only; server credentials and tokens are never exposed.",
|
|
9
|
+
agentTool: false,
|
|
10
|
+
requiresAuth: true,
|
|
11
|
+
schema: z.object({
|
|
12
|
+
serverId: z.string().trim().min(1).optional(),
|
|
13
|
+
}),
|
|
14
|
+
http: { method: "GET" },
|
|
15
|
+
readOnly: true,
|
|
16
|
+
parallelSafe: true,
|
|
17
|
+
run: ({ serverId }) => listVisibleMcpTools({ serverId }),
|
|
18
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { isToolVisibilityModelOnly } from "@modelcontextprotocol/ext-apps/app-bridge";
|
|
2
|
+
|
|
3
|
+
import { getGlobalMcpManager } from "../server/agent-chat/mcp-glue.js";
|
|
4
|
+
import { getRequestContext } from "../server/request-context.js";
|
|
5
|
+
import {
|
|
6
|
+
buildMcpToolName,
|
|
7
|
+
type McpClientManager,
|
|
8
|
+
type McpTool,
|
|
9
|
+
} from "./manager.js";
|
|
10
|
+
import { parseMergedKey } from "./remote-store.js";
|
|
11
|
+
import { isMcpToolAllowedForRequest } from "./visibility.js";
|
|
12
|
+
|
|
13
|
+
export interface AppMcpTool {
|
|
14
|
+
/** Configured MCP server id. */
|
|
15
|
+
serverId: string;
|
|
16
|
+
/** Original, unprefixed name reported by the MCP server. */
|
|
17
|
+
name: string;
|
|
18
|
+
title?: string;
|
|
19
|
+
description: string;
|
|
20
|
+
inputSchema: Record<string, unknown>;
|
|
21
|
+
outputSchema?: Record<string, unknown>;
|
|
22
|
+
annotations?: Record<string, unknown>;
|
|
23
|
+
_meta?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ListVisibleMcpToolsOptions {
|
|
27
|
+
/** Restrict the result to one configured server. */
|
|
28
|
+
serverId?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class McpAppApiError extends Error {
|
|
32
|
+
readonly statusCode: 401 | 403 | 503;
|
|
33
|
+
|
|
34
|
+
constructor(message: string, statusCode: 401 | 403 | 503) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = "McpAppApiError";
|
|
37
|
+
this.statusCode = statusCode;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* List MCP tools that the authenticated request may expose to an app.
|
|
43
|
+
*
|
|
44
|
+
* The manager owns connection state and credentials; this API deliberately
|
|
45
|
+
* projects only the tool contract and never returns server configuration.
|
|
46
|
+
*/
|
|
47
|
+
export async function listVisibleMcpTools(
|
|
48
|
+
options: ListVisibleMcpToolsOptions = {},
|
|
49
|
+
): Promise<AppMcpTool[]> {
|
|
50
|
+
const context = requireAuthenticatedRequest();
|
|
51
|
+
const manager = requireMcpManager();
|
|
52
|
+
const tools = options.serverId
|
|
53
|
+
? manager.getToolsForServer(options.serverId)
|
|
54
|
+
: manager.getTools();
|
|
55
|
+
|
|
56
|
+
return tools
|
|
57
|
+
.filter((tool) => isToolVisibleToApp(tool, context))
|
|
58
|
+
.map(toAppMcpTool);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Call an app-visible MCP tool by server id and its original server-reported
|
|
63
|
+
* name. The prefixed manager name is built only after the tool is found in
|
|
64
|
+
* that server's current, request-visible tool list.
|
|
65
|
+
*/
|
|
66
|
+
export async function callMcpTool(
|
|
67
|
+
serverId: string,
|
|
68
|
+
originalToolName: string,
|
|
69
|
+
args: Record<string, unknown> = {},
|
|
70
|
+
): Promise<unknown> {
|
|
71
|
+
const context = requireAuthenticatedRequest();
|
|
72
|
+
const manager = requireMcpManager();
|
|
73
|
+
const tool = manager
|
|
74
|
+
.getToolsForServer(serverId)
|
|
75
|
+
.find((candidate) => candidate.originalName === originalToolName);
|
|
76
|
+
|
|
77
|
+
if (!tool || !isToolVisibleToApp(tool, context)) {
|
|
78
|
+
throw new McpAppApiError(
|
|
79
|
+
"MCP tool is not available in this request scope.",
|
|
80
|
+
403,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return manager.callTool(buildMcpToolName(serverId, originalToolName), args);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function requireAuthenticatedRequest() {
|
|
88
|
+
const context = getRequestContext();
|
|
89
|
+
if (!context?.userEmail?.trim()) {
|
|
90
|
+
throw new McpAppApiError("Authentication required.", 401);
|
|
91
|
+
}
|
|
92
|
+
return context;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function requireMcpManager(): McpClientManager {
|
|
96
|
+
const manager = getGlobalMcpManager();
|
|
97
|
+
if (!manager) {
|
|
98
|
+
throw new McpAppApiError("MCP client is not configured.", 503);
|
|
99
|
+
}
|
|
100
|
+
return manager;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isToolVisibleToApp(
|
|
104
|
+
tool: McpTool,
|
|
105
|
+
context: ReturnType<typeof getRequestContext>,
|
|
106
|
+
): boolean {
|
|
107
|
+
if (!context) return false;
|
|
108
|
+
|
|
109
|
+
// `isMcpToolAllowedForRequest` intentionally permits missing identity in
|
|
110
|
+
// development for CLI/startup enumeration. App calls are stricter: an
|
|
111
|
+
// active org-scoped tool requires an active org even in development.
|
|
112
|
+
if (!isMcpToolAllowedForRequest(tool.name)) return false;
|
|
113
|
+
const merged = parseMergedKey(tool.name);
|
|
114
|
+
if (merged?.scope === "user" && !context.userEmail?.trim()) return false;
|
|
115
|
+
if (merged?.scope === "org" && !context.orgId?.trim()) return false;
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
// A malformed visibility declaration is not safe to expose to an app.
|
|
119
|
+
return !isToolVisibilityModelOnly(tool.raw as any);
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function toAppMcpTool(tool: McpTool): AppMcpTool {
|
|
126
|
+
return {
|
|
127
|
+
serverId: tool.source,
|
|
128
|
+
name: tool.originalName,
|
|
129
|
+
...(tool.title ? { title: tool.title } : {}),
|
|
130
|
+
description: tool.description,
|
|
131
|
+
inputSchema: tool.inputSchema,
|
|
132
|
+
...(tool.outputSchema ? { outputSchema: tool.outputSchema } : {}),
|
|
133
|
+
...(tool.annotations ? { annotations: tool.annotations } : {}),
|
|
134
|
+
...(tool._meta ? { _meta: tool._meta } : {}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -24,6 +24,7 @@ export {
|
|
|
24
24
|
export {
|
|
25
25
|
listRemoteServers,
|
|
26
26
|
addRemoteServer,
|
|
27
|
+
addOAuthRemoteServer,
|
|
27
28
|
addFirstPartyRemoteServer,
|
|
28
29
|
isFirstPartyRemoteEndpointTrusted,
|
|
29
30
|
removeRemoteServer,
|
|
@@ -39,6 +40,19 @@ export {
|
|
|
39
40
|
type StoredRemoteMcpServer,
|
|
40
41
|
} from "./remote-store.js";
|
|
41
42
|
|
|
43
|
+
export {
|
|
44
|
+
finishMcpOAuthAuthorization,
|
|
45
|
+
getMcpOAuthAccessToken,
|
|
46
|
+
readMcpOAuthCredentials,
|
|
47
|
+
saveMcpOAuthCredentials,
|
|
48
|
+
startMcpOAuthAuthorization,
|
|
49
|
+
type McpOAuthCallbackResult,
|
|
50
|
+
type McpOAuthCredentialBundle,
|
|
51
|
+
type McpOAuthDiscoveryState,
|
|
52
|
+
type McpOAuthProviderOptions,
|
|
53
|
+
type McpOAuthStartResult,
|
|
54
|
+
} from "./oauth-client.js";
|
|
55
|
+
|
|
42
56
|
export {
|
|
43
57
|
areBuiltinMcpCapabilitiesSupported,
|
|
44
58
|
BUILTIN_MCP_CAPABILITIES,
|
|
@@ -80,6 +94,13 @@ export {
|
|
|
80
94
|
export { fetchHubServers } from "./hub-client.js";
|
|
81
95
|
|
|
82
96
|
export { isMcpToolAllowedForRequest } from "./visibility.js";
|
|
97
|
+
export {
|
|
98
|
+
callMcpTool,
|
|
99
|
+
listVisibleMcpTools,
|
|
100
|
+
McpAppApiError,
|
|
101
|
+
type AppMcpTool,
|
|
102
|
+
type ListVisibleMcpToolsOptions,
|
|
103
|
+
} from "./app-api.js";
|
|
83
104
|
import { isMcpToolAllowedForRequest } from "./visibility.js";
|
|
84
105
|
export {
|
|
85
106
|
classifyMcpToolCall,
|