@inkeep/agents-manage-api 0.22.11 → 0.23.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/dist/index.cjs +90 -233
- package/dist/index.js +91 -234
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -4534,8 +4534,16 @@ app19.route("/projects/:projectId/agent", agentFull_default);
|
|
|
4534
4534
|
var routes_default = app19;
|
|
4535
4535
|
var logger6 = agentsCore.getLogger("oauth-service");
|
|
4536
4536
|
var pkceStore = /* @__PURE__ */ new Map();
|
|
4537
|
-
function storePKCEVerifier(state, codeVerifier, toolId, tenantId, projectId,
|
|
4538
|
-
pkceStore.set(state, {
|
|
4537
|
+
function storePKCEVerifier(state, codeVerifier, toolId, tenantId, projectId, clientInformation, metadata, resourceUrl) {
|
|
4538
|
+
pkceStore.set(state, {
|
|
4539
|
+
codeVerifier,
|
|
4540
|
+
toolId,
|
|
4541
|
+
tenantId,
|
|
4542
|
+
projectId,
|
|
4543
|
+
clientInformation,
|
|
4544
|
+
metadata,
|
|
4545
|
+
resourceUrl
|
|
4546
|
+
});
|
|
4539
4547
|
setTimeout(
|
|
4540
4548
|
() => {
|
|
4541
4549
|
pkceStore.delete(state);
|
|
@@ -4563,216 +4571,74 @@ var OAuthService = class {
|
|
|
4563
4571
|
};
|
|
4564
4572
|
}
|
|
4565
4573
|
/**
|
|
4566
|
-
* Initiate OAuth flow for an MCP tool
|
|
4574
|
+
* Initiate OAuth flow for an MCP tool using MCP SDK
|
|
4567
4575
|
*/
|
|
4568
4576
|
async initiateOAuthFlow(params) {
|
|
4569
|
-
const {
|
|
4570
|
-
if (tool.config.type !== "mcp") {
|
|
4571
|
-
throw new Error("OAuth is only supported for MCP tools");
|
|
4572
|
-
}
|
|
4573
|
-
const oAuthConfig = await agentsCore.discoverOAuthEndpoints(tool.config.mcp.server.url, logger6);
|
|
4574
|
-
if (!oAuthConfig) {
|
|
4575
|
-
throw new Error("OAuth not supported by this server");
|
|
4576
|
-
}
|
|
4577
|
-
const { codeVerifier, codeChallenge } = await this.generatePKCEInternal();
|
|
4577
|
+
const { tenantId, projectId, toolId, mcpServerUrl, baseUrl } = params;
|
|
4578
4578
|
const redirectBaseUrl = baseUrl || this.defaultConfig.redirectBaseUrl;
|
|
4579
4579
|
const redirectUri = `${redirectBaseUrl}/oauth/callback`;
|
|
4580
|
-
let clientId = this.defaultConfig.defaultClientId;
|
|
4581
|
-
if (oAuthConfig.supportsDynamicRegistration && oAuthConfig.registrationUrl) {
|
|
4582
|
-
clientId = await this.performDynamicClientRegistration(
|
|
4583
|
-
oAuthConfig.registrationUrl,
|
|
4584
|
-
redirectUri
|
|
4585
|
-
);
|
|
4586
|
-
}
|
|
4587
4580
|
const state = `tool_${toolId}`;
|
|
4588
|
-
const
|
|
4589
|
-
|
|
4590
|
-
clientId,
|
|
4581
|
+
const authResult = await agentsCore.initiateMcpOAuthFlow({
|
|
4582
|
+
mcpServerUrl,
|
|
4591
4583
|
redirectUri,
|
|
4592
4584
|
state,
|
|
4593
|
-
|
|
4594
|
-
|
|
4585
|
+
clientName: this.defaultConfig.clientName,
|
|
4586
|
+
clientUri: this.defaultConfig.clientUri,
|
|
4587
|
+
logoUri: this.defaultConfig.logoUri,
|
|
4588
|
+
defaultClientId: this.defaultConfig.defaultClientId,
|
|
4589
|
+
logger: logger6
|
|
4595
4590
|
});
|
|
4596
|
-
storePKCEVerifier(
|
|
4597
|
-
|
|
4591
|
+
storePKCEVerifier(
|
|
4592
|
+
state,
|
|
4593
|
+
authResult.codeVerifier,
|
|
4594
|
+
toolId,
|
|
4595
|
+
tenantId,
|
|
4596
|
+
projectId,
|
|
4597
|
+
authResult.clientInformation,
|
|
4598
|
+
authResult.metadata,
|
|
4599
|
+
authResult.resourceUrl
|
|
4600
|
+
);
|
|
4601
|
+
logger6.info(
|
|
4602
|
+
{
|
|
4603
|
+
toolId,
|
|
4604
|
+
authorizationUrl: authResult.authorizationUrl,
|
|
4605
|
+
tenantId,
|
|
4606
|
+
projectId,
|
|
4607
|
+
scopes: authResult.scopes
|
|
4608
|
+
},
|
|
4609
|
+
"MCP OAuth flow initiated successfully"
|
|
4610
|
+
);
|
|
4598
4611
|
return {
|
|
4599
|
-
redirectUrl:
|
|
4612
|
+
redirectUrl: authResult.authorizationUrl,
|
|
4600
4613
|
state
|
|
4601
4614
|
};
|
|
4602
4615
|
}
|
|
4603
4616
|
/**
|
|
4604
|
-
* Exchange authorization code for access tokens
|
|
4617
|
+
* Exchange authorization code for access tokens using MCP SDK with stored metadata
|
|
4605
4618
|
*/
|
|
4606
4619
|
async exchangeCodeForTokens(params) {
|
|
4607
|
-
const { code, codeVerifier,
|
|
4608
|
-
if (tool.config.type !== "mcp") {
|
|
4609
|
-
throw new Error("OAuth is only supported for MCP tools");
|
|
4610
|
-
}
|
|
4611
|
-
const oAuthConfig = await agentsCore.discoverOAuthEndpoints(tool.config.mcp.server.url, logger6);
|
|
4612
|
-
if (!oAuthConfig?.tokenUrl) {
|
|
4613
|
-
throw new Error("Could not discover OAuth token endpoint");
|
|
4614
|
-
}
|
|
4620
|
+
const { code, codeVerifier, clientInformation, metadata, resourceUrl, mcpServerUrl, baseUrl } = params;
|
|
4615
4621
|
const redirectBaseUrl = baseUrl || this.defaultConfig.redirectBaseUrl;
|
|
4616
4622
|
const redirectUri = `${redirectBaseUrl}/oauth/callback`;
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
logger6.info({ tokenType: tokens.token_type }, "Token exchange successful with openid-client");
|
|
4627
|
-
} catch (error) {
|
|
4628
|
-
logger6.warn(
|
|
4629
|
-
{ error: error instanceof Error ? error.message : error },
|
|
4630
|
-
"openid-client failed, falling back to manual token exchange"
|
|
4631
|
-
);
|
|
4632
|
-
tokens = await this.exchangeManually({
|
|
4633
|
-
oAuthConfig,
|
|
4634
|
-
clientId,
|
|
4635
|
-
code,
|
|
4636
|
-
codeVerifier,
|
|
4637
|
-
redirectUri
|
|
4638
|
-
});
|
|
4639
|
-
logger6.info({ tokenType: tokens.token_type }, "Manual token exchange successful");
|
|
4640
|
-
}
|
|
4641
|
-
return { tokens, oAuthConfig };
|
|
4642
|
-
}
|
|
4643
|
-
/**
|
|
4644
|
-
* Perform dynamic client registration
|
|
4645
|
-
*/
|
|
4646
|
-
async performDynamicClientRegistration(registrationUrl, redirectUri) {
|
|
4647
|
-
logger6.info({ registrationUrl }, "Attempting dynamic client registration");
|
|
4648
|
-
try {
|
|
4649
|
-
const registrationResponse = await fetch(registrationUrl, {
|
|
4650
|
-
method: "POST",
|
|
4651
|
-
headers: {
|
|
4652
|
-
"Content-Type": "application/json",
|
|
4653
|
-
Accept: "application/json"
|
|
4654
|
-
},
|
|
4655
|
-
body: JSON.stringify({
|
|
4656
|
-
client_name: this.defaultConfig.clientName,
|
|
4657
|
-
client_uri: this.defaultConfig.clientUri,
|
|
4658
|
-
logo_uri: this.defaultConfig.logoUri,
|
|
4659
|
-
redirect_uris: [redirectUri],
|
|
4660
|
-
grant_types: ["authorization_code"],
|
|
4661
|
-
response_types: ["code"],
|
|
4662
|
-
token_endpoint_auth_method: "none",
|
|
4663
|
-
// PKCE only, no client secret
|
|
4664
|
-
application_type: "native"
|
|
4665
|
-
// For PKCE flows
|
|
4666
|
-
})
|
|
4667
|
-
});
|
|
4668
|
-
if (registrationResponse.ok) {
|
|
4669
|
-
const registration = await registrationResponse.json();
|
|
4670
|
-
logger6.info({ clientId: registration.client_id }, "Dynamic client registration successful");
|
|
4671
|
-
return registration.client_id;
|
|
4672
|
-
} else {
|
|
4673
|
-
const errorText = await registrationResponse.text();
|
|
4674
|
-
logger6.warn(
|
|
4675
|
-
{
|
|
4676
|
-
status: registrationResponse.status,
|
|
4677
|
-
errorText
|
|
4678
|
-
},
|
|
4679
|
-
"Dynamic client registration failed, using default client_id"
|
|
4680
|
-
);
|
|
4681
|
-
}
|
|
4682
|
-
} catch (regError) {
|
|
4683
|
-
logger6.warn(
|
|
4684
|
-
{ error: regError },
|
|
4685
|
-
"Dynamic client registration error, using default client_id"
|
|
4686
|
-
);
|
|
4687
|
-
}
|
|
4688
|
-
return this.defaultConfig.defaultClientId;
|
|
4689
|
-
}
|
|
4690
|
-
/**
|
|
4691
|
-
* Build authorization URL
|
|
4692
|
-
*/
|
|
4693
|
-
buildAuthorizationUrl(params) {
|
|
4694
|
-
const { oAuthConfig, clientId, redirectUri, state, codeChallenge, resource } = params;
|
|
4695
|
-
const authUrl = new URL(oAuthConfig.authorizationUrl);
|
|
4696
|
-
authUrl.searchParams.set("response_type", "code");
|
|
4697
|
-
authUrl.searchParams.set("client_id", clientId);
|
|
4698
|
-
authUrl.searchParams.set("redirect_uri", redirectUri);
|
|
4699
|
-
authUrl.searchParams.set("state", state);
|
|
4700
|
-
authUrl.searchParams.set("code_challenge", codeChallenge);
|
|
4701
|
-
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
4702
|
-
authUrl.searchParams.set("resource", resource);
|
|
4703
|
-
return authUrl.toString();
|
|
4704
|
-
}
|
|
4705
|
-
/**
|
|
4706
|
-
* Exchange code using openid-client library
|
|
4707
|
-
*/
|
|
4708
|
-
async exchangeWithOpenIdClient(params) {
|
|
4709
|
-
const { oAuthConfig, clientId, code, codeVerifier, redirectUri } = params;
|
|
4710
|
-
const oauth = await import('openid-client');
|
|
4711
|
-
const tokenUrl = new URL(oAuthConfig.tokenUrl);
|
|
4712
|
-
const oauthServerUrl = `${tokenUrl.protocol}//${tokenUrl.host}`;
|
|
4713
|
-
logger6.info({ oauthServerUrl, clientId }, "Attempting openid-client discovery");
|
|
4714
|
-
const config = await oauth.discovery(
|
|
4715
|
-
new URL(oauthServerUrl),
|
|
4716
|
-
clientId,
|
|
4717
|
-
void 0
|
|
4718
|
-
// No client secret for PKCE
|
|
4719
|
-
);
|
|
4720
|
-
const callbackUrl = new URL(
|
|
4721
|
-
`${redirectUri}?${new URLSearchParams({ code, state: "unused" }).toString()}`
|
|
4722
|
-
);
|
|
4723
|
-
return await oauth.authorizationCodeGrant(config, callbackUrl, {
|
|
4724
|
-
pkceCodeVerifier: codeVerifier
|
|
4623
|
+
const tokens = await agentsCore.exchangeMcpAuthorizationCode({
|
|
4624
|
+
mcpServerUrl,
|
|
4625
|
+
metadata,
|
|
4626
|
+
clientInformation,
|
|
4627
|
+
authorizationCode: code,
|
|
4628
|
+
codeVerifier,
|
|
4629
|
+
redirectUri,
|
|
4630
|
+
resourceUrl,
|
|
4631
|
+
logger: logger6
|
|
4725
4632
|
});
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
const codeVerifier = Buffer.from(
|
|
4732
|
-
Array.from(crypto.getRandomValues(new Uint8Array(32)))
|
|
4733
|
-
).toString("base64url");
|
|
4734
|
-
const encoder = new TextEncoder();
|
|
4735
|
-
const data = encoder.encode(codeVerifier);
|
|
4736
|
-
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
4737
|
-
const codeChallenge = Buffer.from(hash).toString("base64url");
|
|
4738
|
-
return { codeVerifier, codeChallenge };
|
|
4739
|
-
}
|
|
4740
|
-
/**
|
|
4741
|
-
* Manual token exchange fallback
|
|
4742
|
-
*/
|
|
4743
|
-
async exchangeManually(params) {
|
|
4744
|
-
const { oAuthConfig, clientId, code, codeVerifier, redirectUri } = params;
|
|
4745
|
-
logger6.info({ tokenUrl: oAuthConfig.tokenUrl }, "Attempting manual token exchange");
|
|
4746
|
-
const tokenResponse = await fetch(oAuthConfig.tokenUrl, {
|
|
4747
|
-
method: "POST",
|
|
4748
|
-
headers: {
|
|
4749
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
4750
|
-
Accept: "application/json"
|
|
4633
|
+
logger6.info(
|
|
4634
|
+
{
|
|
4635
|
+
tokenType: tokens.token_type,
|
|
4636
|
+
hasRefreshToken: !!tokens.refresh_token,
|
|
4637
|
+
clientId: clientInformation.client_id
|
|
4751
4638
|
},
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
redirect_uri: redirectUri,
|
|
4756
|
-
client_id: clientId,
|
|
4757
|
-
code_verifier: codeVerifier
|
|
4758
|
-
// PKCE verification
|
|
4759
|
-
})
|
|
4760
|
-
});
|
|
4761
|
-
if (!tokenResponse.ok) {
|
|
4762
|
-
const errorText = await tokenResponse.text();
|
|
4763
|
-
logger6.error(
|
|
4764
|
-
{
|
|
4765
|
-
status: tokenResponse.status,
|
|
4766
|
-
statusText: tokenResponse.statusText,
|
|
4767
|
-
...process.env.NODE_ENV === "development" && { errorText },
|
|
4768
|
-
clientId,
|
|
4769
|
-
tokenUrl: oAuthConfig.tokenUrl
|
|
4770
|
-
},
|
|
4771
|
-
"Token exchange failed"
|
|
4772
|
-
);
|
|
4773
|
-
throw new Error("Authentication failed. Please try again or contact support.");
|
|
4774
|
-
}
|
|
4775
|
-
return await tokenResponse.json();
|
|
4639
|
+
"MCP token exchange successful"
|
|
4640
|
+
);
|
|
4641
|
+
return { tokens };
|
|
4776
4642
|
}
|
|
4777
4643
|
};
|
|
4778
4644
|
var oauthService = new OAuthService();
|
|
@@ -4939,14 +4805,12 @@ app20.openapi(
|
|
|
4939
4805
|
logger7.error({ toolId, tenantId, projectId }, "Tool not found for OAuth login");
|
|
4940
4806
|
return c.text("Tool not found", 404);
|
|
4941
4807
|
}
|
|
4942
|
-
const credentialStores = c.get("credentialStores");
|
|
4943
|
-
const mcpTool = await agentsCore.dbResultToMcpTool(tool, dbClient_default, credentialStores);
|
|
4944
4808
|
const baseUrl = getBaseUrlFromRequest(c);
|
|
4945
4809
|
const { redirectUrl } = await oauthService.initiateOAuthFlow({
|
|
4946
|
-
tool: mcpTool,
|
|
4947
4810
|
tenantId,
|
|
4948
4811
|
projectId,
|
|
4949
4812
|
toolId,
|
|
4813
|
+
mcpServerUrl: tool.config.mcp.server.url,
|
|
4950
4814
|
baseUrl
|
|
4951
4815
|
});
|
|
4952
4816
|
return c.redirect(redirectUrl, 302);
|
|
@@ -5015,7 +4879,15 @@ app20.openapi(
|
|
|
5015
4879
|
});
|
|
5016
4880
|
return c.html(expiredPage);
|
|
5017
4881
|
}
|
|
5018
|
-
const {
|
|
4882
|
+
const {
|
|
4883
|
+
codeVerifier,
|
|
4884
|
+
toolId,
|
|
4885
|
+
tenantId,
|
|
4886
|
+
projectId,
|
|
4887
|
+
clientInformation,
|
|
4888
|
+
metadata,
|
|
4889
|
+
resourceUrl
|
|
4890
|
+
} = pkceData;
|
|
5019
4891
|
const tool = await agentsCore.getToolById(dbClient_default)({
|
|
5020
4892
|
scopes: { tenantId, projectId },
|
|
5021
4893
|
toolId
|
|
@@ -5026,13 +4898,14 @@ app20.openapi(
|
|
|
5026
4898
|
logger7.info({ toolId, tenantId, projectId }, "Processing OAuth callback");
|
|
5027
4899
|
logger7.info({ toolId }, "Exchanging authorization code for access token");
|
|
5028
4900
|
const credentialStores = c.get("credentialStores");
|
|
5029
|
-
const mcpTool = await agentsCore.dbResultToMcpTool(tool, dbClient_default, credentialStores);
|
|
5030
4901
|
const baseUrl = getBaseUrlFromRequest(c);
|
|
5031
4902
|
const { tokens } = await oauthService.exchangeCodeForTokens({
|
|
5032
4903
|
code,
|
|
5033
4904
|
codeVerifier,
|
|
5034
|
-
|
|
5035
|
-
|
|
4905
|
+
clientInformation,
|
|
4906
|
+
metadata,
|
|
4907
|
+
resourceUrl,
|
|
4908
|
+
mcpServerUrl: tool.config.mcp.server.url,
|
|
5036
4909
|
baseUrl
|
|
5037
4910
|
});
|
|
5038
4911
|
logger7.info(
|
|
@@ -5041,39 +4914,23 @@ app20.openapi(
|
|
|
5041
4914
|
);
|
|
5042
4915
|
const credentialTokenKey = `oauth_token_${toolId}`;
|
|
5043
4916
|
let newCredentialData;
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
try {
|
|
5062
|
-
await keychainStore.set(credentialTokenKey, JSON.stringify(tokens));
|
|
5063
|
-
newCredentialData = {
|
|
5064
|
-
id: agentsCore.generateIdFromName(mcpTool.name),
|
|
5065
|
-
type: agentsCore.CredentialStoreType.keychain,
|
|
5066
|
-
credentialStoreId: "keychain-default",
|
|
5067
|
-
retrievalParams: {
|
|
5068
|
-
key: credentialTokenKey
|
|
5069
|
-
}
|
|
5070
|
-
};
|
|
5071
|
-
} catch (error2) {
|
|
5072
|
-
logger7.info(
|
|
5073
|
-
{ error: error2 instanceof Error ? error2.message : error2 },
|
|
5074
|
-
"Keychain store not available."
|
|
5075
|
-
);
|
|
5076
|
-
}
|
|
4917
|
+
const keychainStore = credentialStores.get("keychain-default");
|
|
4918
|
+
if (keychainStore) {
|
|
4919
|
+
try {
|
|
4920
|
+
await keychainStore.set(credentialTokenKey, JSON.stringify(tokens));
|
|
4921
|
+
newCredentialData = {
|
|
4922
|
+
id: agentsCore.generateIdFromName(tool.name),
|
|
4923
|
+
type: agentsCore.CredentialStoreType.keychain,
|
|
4924
|
+
credentialStoreId: "keychain-default",
|
|
4925
|
+
retrievalParams: {
|
|
4926
|
+
key: credentialTokenKey
|
|
4927
|
+
}
|
|
4928
|
+
};
|
|
4929
|
+
} catch (error2) {
|
|
4930
|
+
logger7.info(
|
|
4931
|
+
{ error: error2 instanceof Error ? error2.message : error2 },
|
|
4932
|
+
"Keychain store not available."
|
|
4933
|
+
);
|
|
5077
4934
|
}
|
|
5078
4935
|
}
|
|
5079
4936
|
if (!newCredentialData) {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadEnvironmentFiles, getLogger, createDatabaseClient, commonGetErrorResponses, AgentListResponse, PaginationQueryParamsSchema, TenantProjectParamsSchema, listAgents, AgentResponse, TenantProjectIdParamsSchema, getAgentById, createApiError, ListResponseSchema, getAgentSubAgentInfos, SingleResponseSchema, TenantProjectAgentParamsSchema, AgentWithinContextOfProjectSchema, getFullAgentDefinition, AgentApiInsertSchema, createAgent, AgentApiUpdateSchema, updateAgent, ErrorResponseSchema, deleteAgent, createFullAgentServerSide, getFullAgent, updateFullAgentServerSide, deleteFullAgent, ApiKeyListResponse, listApiKeysPaginated, ApiKeyResponse, getApiKeyById, ApiKeyApiCreationResponseSchema, ApiKeyApiInsertSchema, generateApiKey, createApiKey, ApiKeyApiUpdateSchema, updateApiKey, deleteApiKey, ArtifactComponentListResponse, listArtifactComponentsPaginated, ArtifactComponentResponse, getArtifactComponentById, ArtifactComponentApiInsertSchema, validatePropsAsJsonSchema, createArtifactComponent, ArtifactComponentApiUpdateSchema, updateArtifactComponent, deleteArtifactComponent, ContextConfigListResponse, listContextConfigsPaginated, ContextConfigResponse, TenantProjectAgentIdParamsSchema, getContextConfigById, ContextConfigApiInsertSchema, createContextConfig, commonUpdateErrorResponses, ContextConfigApiUpdateSchema, updateContextConfig, commonDeleteErrorResponses, deleteContextConfig, CredentialStoreType, CredentialReferenceListResponse, listCredentialReferencesPaginated, CredentialReferenceApiSelectSchema, CredentialReferenceResponse, getCredentialReferenceWithTools, CredentialReferenceApiInsertSchema, createCredentialReference, CredentialReferenceApiUpdateSchema, updateCredentialReference, getCredentialReferenceById, getCredentialStoreLookupKeyFromRetrievalParams, deleteCredentialReference, DataComponentListResponse, listDataComponentsPaginated, DataComponentResponse, getDataComponent, DataComponentApiInsertSchema, createDataComponent, DataComponentApiUpdateSchema, updateDataComponent, deleteDataComponent, ExternalAgentListResponse, listExternalAgentsPaginated, ExternalAgentResponse, getExternalAgent, ExternalAgentApiInsertSchema, createExternalAgent, ExternalAgentApiUpdateSchema, updateExternalAgent, deleteExternalAgent, FunctionListResponse, listFunctions, FunctionResponse, getFunction, FunctionApiInsertSchema, upsertFunction, FunctionApiUpdateSchema, deleteFunction, FunctionToolApiSelectSchema, listFunctionTools, getFunctionToolById, FunctionToolApiInsertSchema, createFunctionTool, FunctionToolApiUpdateSchema, updateFunctionTool, deleteFunctionTool, ProjectListResponse, TenantParamsSchema, listProjectsPaginated, ProjectResponse, TenantIdParamsSchema, getProject, ProjectApiInsertSchema, createProject, ProjectApiUpdateSchema, updateProject, deleteProject, ArtifactComponentApiSelectSchema, getArtifactComponentsForAgent, getAgentsUsingArtifactComponent, SubAgentArtifactComponentApiInsertSchema, SubAgentArtifactComponentApiSelectSchema, getSubAgentById, isArtifactComponentAssociatedWithAgent, associateArtifactComponentWithAgent, RemovedResponseSchema, removeArtifactComponentFromAgent, ExistsResponseSchema, DataComponentApiSelectSchema, getDataComponentsForAgent, getAgentsUsingDataComponent, SubAgentDataComponentApiInsertSchema, SubAgentDataComponentApiSelectSchema, isDataComponentAssociatedWithAgent, associateDataComponentWithAgent, removeDataComponentFromAgent, SubAgentRelationApiSelectSchema, SubAgentRelationQuerySchema, getAgentRelationsBySource, getSubAgentRelationsByTarget, getExternalAgentRelations, listAgentRelations, getAgentRelationById, SubAgentRelationApiInsertSchema, validateExternalAgent, validateInternalSubAgent, createSubAgentRelation, SubAgentRelationApiUpdateSchema, updateAgentRelation, deleteSubAgentRelation, SubAgentListResponse, listSubAgentsPaginated, SubAgentResponse, SubAgentApiInsertSchema, createSubAgent, SubAgentApiUpdateSchema, updateSubAgent, deleteSubAgent, SubAgentToolRelationApiSelectSchema, getAgentToolRelationByAgent, getAgentToolRelationByTool, listAgentToolRelations, getAgentToolRelationById, getAgentsForTool, SubAgentToolRelationApiInsertSchema, createAgentToolRelation, SubAgentToolRelationApiUpdateSchema, updateAgentToolRelation, deleteAgentToolRelation, McpToolSchema, ToolStatusSchema, listTools, dbResultToMcpTool, getToolById, ToolApiInsertSchema, createTool, ToolApiUpdateSchema, updateTool, deleteTool, generateIdFromName, FullProjectDefinitionSchema, createFullProjectServerSide, getFullProject, updateFullProjectServerSide, deleteFullProject, createDefaultCredentialStores, CredentialStoreRegistry,
|
|
1
|
+
import { loadEnvironmentFiles, getLogger, createDatabaseClient, commonGetErrorResponses, AgentListResponse, PaginationQueryParamsSchema, TenantProjectParamsSchema, listAgents, AgentResponse, TenantProjectIdParamsSchema, getAgentById, createApiError, ListResponseSchema, getAgentSubAgentInfos, SingleResponseSchema, TenantProjectAgentParamsSchema, AgentWithinContextOfProjectSchema, getFullAgentDefinition, AgentApiInsertSchema, createAgent, AgentApiUpdateSchema, updateAgent, ErrorResponseSchema, deleteAgent, createFullAgentServerSide, getFullAgent, updateFullAgentServerSide, deleteFullAgent, ApiKeyListResponse, listApiKeysPaginated, ApiKeyResponse, getApiKeyById, ApiKeyApiCreationResponseSchema, ApiKeyApiInsertSchema, generateApiKey, createApiKey, ApiKeyApiUpdateSchema, updateApiKey, deleteApiKey, ArtifactComponentListResponse, listArtifactComponentsPaginated, ArtifactComponentResponse, getArtifactComponentById, ArtifactComponentApiInsertSchema, validatePropsAsJsonSchema, createArtifactComponent, ArtifactComponentApiUpdateSchema, updateArtifactComponent, deleteArtifactComponent, ContextConfigListResponse, listContextConfigsPaginated, ContextConfigResponse, TenantProjectAgentIdParamsSchema, getContextConfigById, ContextConfigApiInsertSchema, createContextConfig, commonUpdateErrorResponses, ContextConfigApiUpdateSchema, updateContextConfig, commonDeleteErrorResponses, deleteContextConfig, CredentialStoreType, CredentialReferenceListResponse, listCredentialReferencesPaginated, CredentialReferenceApiSelectSchema, CredentialReferenceResponse, getCredentialReferenceWithTools, CredentialReferenceApiInsertSchema, createCredentialReference, CredentialReferenceApiUpdateSchema, updateCredentialReference, getCredentialReferenceById, getCredentialStoreLookupKeyFromRetrievalParams, deleteCredentialReference, DataComponentListResponse, listDataComponentsPaginated, DataComponentResponse, getDataComponent, DataComponentApiInsertSchema, createDataComponent, DataComponentApiUpdateSchema, updateDataComponent, deleteDataComponent, ExternalAgentListResponse, listExternalAgentsPaginated, ExternalAgentResponse, getExternalAgent, ExternalAgentApiInsertSchema, createExternalAgent, ExternalAgentApiUpdateSchema, updateExternalAgent, deleteExternalAgent, FunctionListResponse, listFunctions, FunctionResponse, getFunction, FunctionApiInsertSchema, upsertFunction, FunctionApiUpdateSchema, deleteFunction, FunctionToolApiSelectSchema, listFunctionTools, getFunctionToolById, FunctionToolApiInsertSchema, createFunctionTool, FunctionToolApiUpdateSchema, updateFunctionTool, deleteFunctionTool, ProjectListResponse, TenantParamsSchema, listProjectsPaginated, ProjectResponse, TenantIdParamsSchema, getProject, ProjectApiInsertSchema, createProject, ProjectApiUpdateSchema, updateProject, deleteProject, ArtifactComponentApiSelectSchema, getArtifactComponentsForAgent, getAgentsUsingArtifactComponent, SubAgentArtifactComponentApiInsertSchema, SubAgentArtifactComponentApiSelectSchema, getSubAgentById, isArtifactComponentAssociatedWithAgent, associateArtifactComponentWithAgent, RemovedResponseSchema, removeArtifactComponentFromAgent, ExistsResponseSchema, DataComponentApiSelectSchema, getDataComponentsForAgent, getAgentsUsingDataComponent, SubAgentDataComponentApiInsertSchema, SubAgentDataComponentApiSelectSchema, isDataComponentAssociatedWithAgent, associateDataComponentWithAgent, removeDataComponentFromAgent, SubAgentRelationApiSelectSchema, SubAgentRelationQuerySchema, getAgentRelationsBySource, getSubAgentRelationsByTarget, getExternalAgentRelations, listAgentRelations, getAgentRelationById, SubAgentRelationApiInsertSchema, validateExternalAgent, validateInternalSubAgent, createSubAgentRelation, SubAgentRelationApiUpdateSchema, updateAgentRelation, deleteSubAgentRelation, SubAgentListResponse, listSubAgentsPaginated, SubAgentResponse, SubAgentApiInsertSchema, createSubAgent, SubAgentApiUpdateSchema, updateSubAgent, deleteSubAgent, SubAgentToolRelationApiSelectSchema, getAgentToolRelationByAgent, getAgentToolRelationByTool, listAgentToolRelations, getAgentToolRelationById, getAgentsForTool, SubAgentToolRelationApiInsertSchema, createAgentToolRelation, SubAgentToolRelationApiUpdateSchema, updateAgentToolRelation, deleteAgentToolRelation, McpToolSchema, ToolStatusSchema, listTools, dbResultToMcpTool, getToolById, ToolApiInsertSchema, createTool, ToolApiUpdateSchema, updateTool, deleteTool, generateIdFromName, FullProjectDefinitionSchema, createFullProjectServerSide, getFullProject, updateFullProjectServerSide, deleteFullProject, createDefaultCredentialStores, CredentialStoreRegistry, initiateMcpOAuthFlow, exchangeMcpAuthorizationCode, handleApiError } from '@inkeep/agents-core';
|
|
2
2
|
import { OpenAPIHono, createRoute, z as z$1 } from '@hono/zod-openapi';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import { cors } from 'hono/cors';
|
|
@@ -4530,8 +4530,16 @@ app19.route("/projects/:projectId/agent", agentFull_default);
|
|
|
4530
4530
|
var routes_default = app19;
|
|
4531
4531
|
var logger6 = getLogger("oauth-service");
|
|
4532
4532
|
var pkceStore = /* @__PURE__ */ new Map();
|
|
4533
|
-
function storePKCEVerifier(state, codeVerifier, toolId, tenantId, projectId,
|
|
4534
|
-
pkceStore.set(state, {
|
|
4533
|
+
function storePKCEVerifier(state, codeVerifier, toolId, tenantId, projectId, clientInformation, metadata, resourceUrl) {
|
|
4534
|
+
pkceStore.set(state, {
|
|
4535
|
+
codeVerifier,
|
|
4536
|
+
toolId,
|
|
4537
|
+
tenantId,
|
|
4538
|
+
projectId,
|
|
4539
|
+
clientInformation,
|
|
4540
|
+
metadata,
|
|
4541
|
+
resourceUrl
|
|
4542
|
+
});
|
|
4535
4543
|
setTimeout(
|
|
4536
4544
|
() => {
|
|
4537
4545
|
pkceStore.delete(state);
|
|
@@ -4559,216 +4567,74 @@ var OAuthService = class {
|
|
|
4559
4567
|
};
|
|
4560
4568
|
}
|
|
4561
4569
|
/**
|
|
4562
|
-
* Initiate OAuth flow for an MCP tool
|
|
4570
|
+
* Initiate OAuth flow for an MCP tool using MCP SDK
|
|
4563
4571
|
*/
|
|
4564
4572
|
async initiateOAuthFlow(params) {
|
|
4565
|
-
const {
|
|
4566
|
-
if (tool.config.type !== "mcp") {
|
|
4567
|
-
throw new Error("OAuth is only supported for MCP tools");
|
|
4568
|
-
}
|
|
4569
|
-
const oAuthConfig = await discoverOAuthEndpoints(tool.config.mcp.server.url, logger6);
|
|
4570
|
-
if (!oAuthConfig) {
|
|
4571
|
-
throw new Error("OAuth not supported by this server");
|
|
4572
|
-
}
|
|
4573
|
-
const { codeVerifier, codeChallenge } = await this.generatePKCEInternal();
|
|
4573
|
+
const { tenantId, projectId, toolId, mcpServerUrl, baseUrl } = params;
|
|
4574
4574
|
const redirectBaseUrl = baseUrl || this.defaultConfig.redirectBaseUrl;
|
|
4575
4575
|
const redirectUri = `${redirectBaseUrl}/oauth/callback`;
|
|
4576
|
-
let clientId = this.defaultConfig.defaultClientId;
|
|
4577
|
-
if (oAuthConfig.supportsDynamicRegistration && oAuthConfig.registrationUrl) {
|
|
4578
|
-
clientId = await this.performDynamicClientRegistration(
|
|
4579
|
-
oAuthConfig.registrationUrl,
|
|
4580
|
-
redirectUri
|
|
4581
|
-
);
|
|
4582
|
-
}
|
|
4583
4576
|
const state = `tool_${toolId}`;
|
|
4584
|
-
const
|
|
4585
|
-
|
|
4586
|
-
clientId,
|
|
4577
|
+
const authResult = await initiateMcpOAuthFlow({
|
|
4578
|
+
mcpServerUrl,
|
|
4587
4579
|
redirectUri,
|
|
4588
4580
|
state,
|
|
4589
|
-
|
|
4590
|
-
|
|
4581
|
+
clientName: this.defaultConfig.clientName,
|
|
4582
|
+
clientUri: this.defaultConfig.clientUri,
|
|
4583
|
+
logoUri: this.defaultConfig.logoUri,
|
|
4584
|
+
defaultClientId: this.defaultConfig.defaultClientId,
|
|
4585
|
+
logger: logger6
|
|
4591
4586
|
});
|
|
4592
|
-
storePKCEVerifier(
|
|
4593
|
-
|
|
4587
|
+
storePKCEVerifier(
|
|
4588
|
+
state,
|
|
4589
|
+
authResult.codeVerifier,
|
|
4590
|
+
toolId,
|
|
4591
|
+
tenantId,
|
|
4592
|
+
projectId,
|
|
4593
|
+
authResult.clientInformation,
|
|
4594
|
+
authResult.metadata,
|
|
4595
|
+
authResult.resourceUrl
|
|
4596
|
+
);
|
|
4597
|
+
logger6.info(
|
|
4598
|
+
{
|
|
4599
|
+
toolId,
|
|
4600
|
+
authorizationUrl: authResult.authorizationUrl,
|
|
4601
|
+
tenantId,
|
|
4602
|
+
projectId,
|
|
4603
|
+
scopes: authResult.scopes
|
|
4604
|
+
},
|
|
4605
|
+
"MCP OAuth flow initiated successfully"
|
|
4606
|
+
);
|
|
4594
4607
|
return {
|
|
4595
|
-
redirectUrl:
|
|
4608
|
+
redirectUrl: authResult.authorizationUrl,
|
|
4596
4609
|
state
|
|
4597
4610
|
};
|
|
4598
4611
|
}
|
|
4599
4612
|
/**
|
|
4600
|
-
* Exchange authorization code for access tokens
|
|
4613
|
+
* Exchange authorization code for access tokens using MCP SDK with stored metadata
|
|
4601
4614
|
*/
|
|
4602
4615
|
async exchangeCodeForTokens(params) {
|
|
4603
|
-
const { code, codeVerifier,
|
|
4604
|
-
if (tool.config.type !== "mcp") {
|
|
4605
|
-
throw new Error("OAuth is only supported for MCP tools");
|
|
4606
|
-
}
|
|
4607
|
-
const oAuthConfig = await discoverOAuthEndpoints(tool.config.mcp.server.url, logger6);
|
|
4608
|
-
if (!oAuthConfig?.tokenUrl) {
|
|
4609
|
-
throw new Error("Could not discover OAuth token endpoint");
|
|
4610
|
-
}
|
|
4616
|
+
const { code, codeVerifier, clientInformation, metadata, resourceUrl, mcpServerUrl, baseUrl } = params;
|
|
4611
4617
|
const redirectBaseUrl = baseUrl || this.defaultConfig.redirectBaseUrl;
|
|
4612
4618
|
const redirectUri = `${redirectBaseUrl}/oauth/callback`;
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
logger6.info({ tokenType: tokens.token_type }, "Token exchange successful with openid-client");
|
|
4623
|
-
} catch (error) {
|
|
4624
|
-
logger6.warn(
|
|
4625
|
-
{ error: error instanceof Error ? error.message : error },
|
|
4626
|
-
"openid-client failed, falling back to manual token exchange"
|
|
4627
|
-
);
|
|
4628
|
-
tokens = await this.exchangeManually({
|
|
4629
|
-
oAuthConfig,
|
|
4630
|
-
clientId,
|
|
4631
|
-
code,
|
|
4632
|
-
codeVerifier,
|
|
4633
|
-
redirectUri
|
|
4634
|
-
});
|
|
4635
|
-
logger6.info({ tokenType: tokens.token_type }, "Manual token exchange successful");
|
|
4636
|
-
}
|
|
4637
|
-
return { tokens, oAuthConfig };
|
|
4638
|
-
}
|
|
4639
|
-
/**
|
|
4640
|
-
* Perform dynamic client registration
|
|
4641
|
-
*/
|
|
4642
|
-
async performDynamicClientRegistration(registrationUrl, redirectUri) {
|
|
4643
|
-
logger6.info({ registrationUrl }, "Attempting dynamic client registration");
|
|
4644
|
-
try {
|
|
4645
|
-
const registrationResponse = await fetch(registrationUrl, {
|
|
4646
|
-
method: "POST",
|
|
4647
|
-
headers: {
|
|
4648
|
-
"Content-Type": "application/json",
|
|
4649
|
-
Accept: "application/json"
|
|
4650
|
-
},
|
|
4651
|
-
body: JSON.stringify({
|
|
4652
|
-
client_name: this.defaultConfig.clientName,
|
|
4653
|
-
client_uri: this.defaultConfig.clientUri,
|
|
4654
|
-
logo_uri: this.defaultConfig.logoUri,
|
|
4655
|
-
redirect_uris: [redirectUri],
|
|
4656
|
-
grant_types: ["authorization_code"],
|
|
4657
|
-
response_types: ["code"],
|
|
4658
|
-
token_endpoint_auth_method: "none",
|
|
4659
|
-
// PKCE only, no client secret
|
|
4660
|
-
application_type: "native"
|
|
4661
|
-
// For PKCE flows
|
|
4662
|
-
})
|
|
4663
|
-
});
|
|
4664
|
-
if (registrationResponse.ok) {
|
|
4665
|
-
const registration = await registrationResponse.json();
|
|
4666
|
-
logger6.info({ clientId: registration.client_id }, "Dynamic client registration successful");
|
|
4667
|
-
return registration.client_id;
|
|
4668
|
-
} else {
|
|
4669
|
-
const errorText = await registrationResponse.text();
|
|
4670
|
-
logger6.warn(
|
|
4671
|
-
{
|
|
4672
|
-
status: registrationResponse.status,
|
|
4673
|
-
errorText
|
|
4674
|
-
},
|
|
4675
|
-
"Dynamic client registration failed, using default client_id"
|
|
4676
|
-
);
|
|
4677
|
-
}
|
|
4678
|
-
} catch (regError) {
|
|
4679
|
-
logger6.warn(
|
|
4680
|
-
{ error: regError },
|
|
4681
|
-
"Dynamic client registration error, using default client_id"
|
|
4682
|
-
);
|
|
4683
|
-
}
|
|
4684
|
-
return this.defaultConfig.defaultClientId;
|
|
4685
|
-
}
|
|
4686
|
-
/**
|
|
4687
|
-
* Build authorization URL
|
|
4688
|
-
*/
|
|
4689
|
-
buildAuthorizationUrl(params) {
|
|
4690
|
-
const { oAuthConfig, clientId, redirectUri, state, codeChallenge, resource } = params;
|
|
4691
|
-
const authUrl = new URL(oAuthConfig.authorizationUrl);
|
|
4692
|
-
authUrl.searchParams.set("response_type", "code");
|
|
4693
|
-
authUrl.searchParams.set("client_id", clientId);
|
|
4694
|
-
authUrl.searchParams.set("redirect_uri", redirectUri);
|
|
4695
|
-
authUrl.searchParams.set("state", state);
|
|
4696
|
-
authUrl.searchParams.set("code_challenge", codeChallenge);
|
|
4697
|
-
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
4698
|
-
authUrl.searchParams.set("resource", resource);
|
|
4699
|
-
return authUrl.toString();
|
|
4700
|
-
}
|
|
4701
|
-
/**
|
|
4702
|
-
* Exchange code using openid-client library
|
|
4703
|
-
*/
|
|
4704
|
-
async exchangeWithOpenIdClient(params) {
|
|
4705
|
-
const { oAuthConfig, clientId, code, codeVerifier, redirectUri } = params;
|
|
4706
|
-
const oauth = await import('openid-client');
|
|
4707
|
-
const tokenUrl = new URL(oAuthConfig.tokenUrl);
|
|
4708
|
-
const oauthServerUrl = `${tokenUrl.protocol}//${tokenUrl.host}`;
|
|
4709
|
-
logger6.info({ oauthServerUrl, clientId }, "Attempting openid-client discovery");
|
|
4710
|
-
const config = await oauth.discovery(
|
|
4711
|
-
new URL(oauthServerUrl),
|
|
4712
|
-
clientId,
|
|
4713
|
-
void 0
|
|
4714
|
-
// No client secret for PKCE
|
|
4715
|
-
);
|
|
4716
|
-
const callbackUrl = new URL(
|
|
4717
|
-
`${redirectUri}?${new URLSearchParams({ code, state: "unused" }).toString()}`
|
|
4718
|
-
);
|
|
4719
|
-
return await oauth.authorizationCodeGrant(config, callbackUrl, {
|
|
4720
|
-
pkceCodeVerifier: codeVerifier
|
|
4619
|
+
const tokens = await exchangeMcpAuthorizationCode({
|
|
4620
|
+
mcpServerUrl,
|
|
4621
|
+
metadata,
|
|
4622
|
+
clientInformation,
|
|
4623
|
+
authorizationCode: code,
|
|
4624
|
+
codeVerifier,
|
|
4625
|
+
redirectUri,
|
|
4626
|
+
resourceUrl,
|
|
4627
|
+
logger: logger6
|
|
4721
4628
|
});
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
const codeVerifier = Buffer.from(
|
|
4728
|
-
Array.from(crypto.getRandomValues(new Uint8Array(32)))
|
|
4729
|
-
).toString("base64url");
|
|
4730
|
-
const encoder = new TextEncoder();
|
|
4731
|
-
const data = encoder.encode(codeVerifier);
|
|
4732
|
-
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
4733
|
-
const codeChallenge = Buffer.from(hash).toString("base64url");
|
|
4734
|
-
return { codeVerifier, codeChallenge };
|
|
4735
|
-
}
|
|
4736
|
-
/**
|
|
4737
|
-
* Manual token exchange fallback
|
|
4738
|
-
*/
|
|
4739
|
-
async exchangeManually(params) {
|
|
4740
|
-
const { oAuthConfig, clientId, code, codeVerifier, redirectUri } = params;
|
|
4741
|
-
logger6.info({ tokenUrl: oAuthConfig.tokenUrl }, "Attempting manual token exchange");
|
|
4742
|
-
const tokenResponse = await fetch(oAuthConfig.tokenUrl, {
|
|
4743
|
-
method: "POST",
|
|
4744
|
-
headers: {
|
|
4745
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
4746
|
-
Accept: "application/json"
|
|
4629
|
+
logger6.info(
|
|
4630
|
+
{
|
|
4631
|
+
tokenType: tokens.token_type,
|
|
4632
|
+
hasRefreshToken: !!tokens.refresh_token,
|
|
4633
|
+
clientId: clientInformation.client_id
|
|
4747
4634
|
},
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
redirect_uri: redirectUri,
|
|
4752
|
-
client_id: clientId,
|
|
4753
|
-
code_verifier: codeVerifier
|
|
4754
|
-
// PKCE verification
|
|
4755
|
-
})
|
|
4756
|
-
});
|
|
4757
|
-
if (!tokenResponse.ok) {
|
|
4758
|
-
const errorText = await tokenResponse.text();
|
|
4759
|
-
logger6.error(
|
|
4760
|
-
{
|
|
4761
|
-
status: tokenResponse.status,
|
|
4762
|
-
statusText: tokenResponse.statusText,
|
|
4763
|
-
...process.env.NODE_ENV === "development" && { errorText },
|
|
4764
|
-
clientId,
|
|
4765
|
-
tokenUrl: oAuthConfig.tokenUrl
|
|
4766
|
-
},
|
|
4767
|
-
"Token exchange failed"
|
|
4768
|
-
);
|
|
4769
|
-
throw new Error("Authentication failed. Please try again or contact support.");
|
|
4770
|
-
}
|
|
4771
|
-
return await tokenResponse.json();
|
|
4635
|
+
"MCP token exchange successful"
|
|
4636
|
+
);
|
|
4637
|
+
return { tokens };
|
|
4772
4638
|
}
|
|
4773
4639
|
};
|
|
4774
4640
|
var oauthService = new OAuthService();
|
|
@@ -4935,14 +4801,12 @@ app20.openapi(
|
|
|
4935
4801
|
logger7.error({ toolId, tenantId, projectId }, "Tool not found for OAuth login");
|
|
4936
4802
|
return c.text("Tool not found", 404);
|
|
4937
4803
|
}
|
|
4938
|
-
const credentialStores = c.get("credentialStores");
|
|
4939
|
-
const mcpTool = await dbResultToMcpTool(tool, dbClient_default, credentialStores);
|
|
4940
4804
|
const baseUrl = getBaseUrlFromRequest(c);
|
|
4941
4805
|
const { redirectUrl } = await oauthService.initiateOAuthFlow({
|
|
4942
|
-
tool: mcpTool,
|
|
4943
4806
|
tenantId,
|
|
4944
4807
|
projectId,
|
|
4945
4808
|
toolId,
|
|
4809
|
+
mcpServerUrl: tool.config.mcp.server.url,
|
|
4946
4810
|
baseUrl
|
|
4947
4811
|
});
|
|
4948
4812
|
return c.redirect(redirectUrl, 302);
|
|
@@ -5011,7 +4875,15 @@ app20.openapi(
|
|
|
5011
4875
|
});
|
|
5012
4876
|
return c.html(expiredPage);
|
|
5013
4877
|
}
|
|
5014
|
-
const {
|
|
4878
|
+
const {
|
|
4879
|
+
codeVerifier,
|
|
4880
|
+
toolId,
|
|
4881
|
+
tenantId,
|
|
4882
|
+
projectId,
|
|
4883
|
+
clientInformation,
|
|
4884
|
+
metadata,
|
|
4885
|
+
resourceUrl
|
|
4886
|
+
} = pkceData;
|
|
5015
4887
|
const tool = await getToolById(dbClient_default)({
|
|
5016
4888
|
scopes: { tenantId, projectId },
|
|
5017
4889
|
toolId
|
|
@@ -5022,13 +4894,14 @@ app20.openapi(
|
|
|
5022
4894
|
logger7.info({ toolId, tenantId, projectId }, "Processing OAuth callback");
|
|
5023
4895
|
logger7.info({ toolId }, "Exchanging authorization code for access token");
|
|
5024
4896
|
const credentialStores = c.get("credentialStores");
|
|
5025
|
-
const mcpTool = await dbResultToMcpTool(tool, dbClient_default, credentialStores);
|
|
5026
4897
|
const baseUrl = getBaseUrlFromRequest(c);
|
|
5027
4898
|
const { tokens } = await oauthService.exchangeCodeForTokens({
|
|
5028
4899
|
code,
|
|
5029
4900
|
codeVerifier,
|
|
5030
|
-
|
|
5031
|
-
|
|
4901
|
+
clientInformation,
|
|
4902
|
+
metadata,
|
|
4903
|
+
resourceUrl,
|
|
4904
|
+
mcpServerUrl: tool.config.mcp.server.url,
|
|
5032
4905
|
baseUrl
|
|
5033
4906
|
});
|
|
5034
4907
|
logger7.info(
|
|
@@ -5037,39 +4910,23 @@ app20.openapi(
|
|
|
5037
4910
|
);
|
|
5038
4911
|
const credentialTokenKey = `oauth_token_${toolId}`;
|
|
5039
4912
|
let newCredentialData;
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
try {
|
|
5058
|
-
await keychainStore.set(credentialTokenKey, JSON.stringify(tokens));
|
|
5059
|
-
newCredentialData = {
|
|
5060
|
-
id: generateIdFromName(mcpTool.name),
|
|
5061
|
-
type: CredentialStoreType.keychain,
|
|
5062
|
-
credentialStoreId: "keychain-default",
|
|
5063
|
-
retrievalParams: {
|
|
5064
|
-
key: credentialTokenKey
|
|
5065
|
-
}
|
|
5066
|
-
};
|
|
5067
|
-
} catch (error2) {
|
|
5068
|
-
logger7.info(
|
|
5069
|
-
{ error: error2 instanceof Error ? error2.message : error2 },
|
|
5070
|
-
"Keychain store not available."
|
|
5071
|
-
);
|
|
5072
|
-
}
|
|
4913
|
+
const keychainStore = credentialStores.get("keychain-default");
|
|
4914
|
+
if (keychainStore) {
|
|
4915
|
+
try {
|
|
4916
|
+
await keychainStore.set(credentialTokenKey, JSON.stringify(tokens));
|
|
4917
|
+
newCredentialData = {
|
|
4918
|
+
id: generateIdFromName(tool.name),
|
|
4919
|
+
type: CredentialStoreType.keychain,
|
|
4920
|
+
credentialStoreId: "keychain-default",
|
|
4921
|
+
retrievalParams: {
|
|
4922
|
+
key: credentialTokenKey
|
|
4923
|
+
}
|
|
4924
|
+
};
|
|
4925
|
+
} catch (error2) {
|
|
4926
|
+
logger7.info(
|
|
4927
|
+
{ error: error2 instanceof Error ? error2.message : error2 },
|
|
4928
|
+
"Keychain store not available."
|
|
4929
|
+
);
|
|
5073
4930
|
}
|
|
5074
4931
|
}
|
|
5075
4932
|
if (!newCredentialData) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-manage-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Agents Manage API for Inkeep Agent Framework - handles CRUD operations and OAuth",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"@hono/node-server": "^1.14.3",
|
|
14
14
|
"@hono/swagger-ui": "^0.5.1",
|
|
15
15
|
"@hono/zod-openapi": "^1.0.2",
|
|
16
|
-
"@nangohq/node": "^0.
|
|
17
|
-
"@nangohq/types": "^0.
|
|
16
|
+
"@nangohq/node": "^0.69.3",
|
|
17
|
+
"@nangohq/types": "^0.69.3",
|
|
18
18
|
"dotenv": "^17.2.1",
|
|
19
19
|
"drizzle-orm": "^0.44.4",
|
|
20
20
|
"hono": "^4.9.7",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"openid-client": "^6.6.4",
|
|
24
24
|
"pino": "^9.7.0",
|
|
25
25
|
"zod": "^4.1.11",
|
|
26
|
-
"@inkeep/agents-core": "^0.
|
|
26
|
+
"@inkeep/agents-core": "^0.23.0"
|
|
27
27
|
},
|
|
28
28
|
"optionalDependencies": {
|
|
29
29
|
"keytar": "^7.9.0"
|