neotoma 0.18.8 → 0.19.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/actions.d.ts +1 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +201 -6
- package/dist/actions.js.map +1 -1
- package/dist/docs/developer/cli_reference.md +1 -1
- package/dist/docs/developer/mcp/proxy.md +6 -4
- package/dist/docs/foundation/entity_resolution.md +34 -7
- package/dist/docs/foundation/what_to_store.md +1 -1
- package/dist/docs/infrastructure/client_instance_deployment.md +151 -0
- package/dist/docs/reference/error_codes.md +75 -23
- package/dist/docs/testing/automated_test_catalog.md +16 -8
- package/dist/inspector/assets/access_policies-6-6DPI39.js +1 -0
- package/dist/inspector/assets/{agent_badge-D5c8UAE9.js → agent_badge-CXSO0sXJ.js} +1 -1
- package/dist/inspector/assets/{agent_detail-lZm2dWDR.js → agent_detail-Cr7iqdye.js} +1 -1
- package/dist/inspector/assets/{agent_filter-_s9ctnZg.js → agent_filter-DQvQyxMp.js} +1 -1
- package/dist/inspector/assets/{agent_grant_detail-jPlKCXYO.js → agent_grant_detail-DRRM7KWw.js} +1 -1
- package/dist/inspector/assets/{agent_grant_form-BUQdfq4A.js → agent_grant_form-DNfWiVBQ.js} +1 -1
- package/dist/inspector/assets/{agent_grants-D7dYlLNX.js → agent_grants-BWgOPiOe.js} +1 -1
- package/dist/inspector/assets/{agents-Bl50GiDS.js → agents-CPLAQelS.js} +1 -1
- package/dist/inspector/assets/{api_not_configured_state-GASK-mhp.js → api_not_configured_state-DHesochj.js} +1 -1
- package/dist/inspector/assets/{attribution_card-Dks_zpQx.js → attribution_card-CCINKjRY.js} +1 -1
- package/dist/inspector/assets/{attribution_summary-Cli2qL-J.js → attribution_summary-Dkwz1aNS.js} +1 -1
- package/dist/inspector/assets/{bundles-4y41Dsvz.js → bundles-f-bRlQYm.js} +1 -1
- package/dist/inspector/assets/{card-DyP1iupa.js → card-18-eZw0x.js} +1 -1
- package/dist/inspector/assets/{checkbox-CIUQh9NP.js → checkbox-DUu6AMCH.js} +1 -1
- package/dist/inspector/assets/{compliance-CZT3IVp5.js → compliance-C1iqMRYK.js} +1 -1
- package/dist/inspector/assets/{confirm-dialog-DwPqhney.js → confirm-dialog-KIPuwTQR.js} +1 -1
- package/dist/inspector/assets/{conversation_common-DqXXK2sj.js → conversation_common-aPvd5zmX.js} +1 -1
- package/dist/inspector/assets/{conversation_detail-BUqgnrpM.js → conversation_detail-nJDDMCfc.js} +1 -1
- package/dist/inspector/assets/{copy_id_button-CFvm8hKT.js → copy_id_button-BwaRGKNA.js} +1 -1
- package/dist/inspector/assets/{copyable_code_block-Ds_m6kph.js → copyable_code_block-DDi03yAz.js} +1 -1
- package/dist/inspector/assets/{corrections-CYBwDzLB.js → corrections-Dz2v9ju9.js} +1 -1
- package/dist/inspector/assets/{dashboard-Bn74vHnA.js → dashboard-CZOdnoJJ.js} +1 -1
- package/dist/inspector/assets/{data-table-BdvHAu9o.js → data-table-5i_gqEfj.js} +1 -1
- package/dist/inspector/assets/{design-CvkXmrg8.js → design-BdKBUVmX.js} +1 -1
- package/dist/inspector/assets/{dialog-ClLKFBmR.js → dialog-CNJoZoQS.js} +1 -1
- package/dist/inspector/assets/{docs-DsWM97KO.js → docs-sXzc0LTz.js} +1 -1
- package/dist/inspector/assets/{docs_page_layout-B2uZRfVC.js → docs_page_layout-CGg8ubQX.js} +1 -1
- package/dist/inspector/assets/{embed_graph-dvewK9nr.js → embed_graph-BpLLD_vX.js} +1 -1
- package/dist/inspector/assets/{empty_state-Bc-ujW2X.js → empty_state-DNk61WLW.js} +1 -1
- package/dist/inspector/assets/{entities-BOrwMORJ.js → entities-Cexhp3qr.js} +1 -1
- package/dist/inspector/assets/{entity_correct-r178klDI.js → entity_correct-CfSggXgT.js} +1 -1
- package/dist/inspector/assets/{entity_history-CKLn3lKb.js → entity_history-CGila0eu.js} +1 -1
- package/dist/inspector/assets/{entity_history_sections-FVZdr00Y.js → entity_history_sections-CXYX1gph.js} +1 -1
- package/dist/inspector/assets/{entity_link-yKDYqbhx.js → entity_link-DUdsaj-A.js} +1 -1
- package/dist/inspector/assets/{entity_relationships_by_type-SQLvwlXL.js → entity_relationships_by_type-B_PH1APK.js} +1 -1
- package/dist/inspector/assets/{entity_segment_page-BXDQbUUp.js → entity_segment_page-DRYjT1AU.js} +1 -1
- package/dist/inspector/assets/{entity_table_column_toggle-D7CwUiAH.js → entity_table_column_toggle-DwwHY7Y8.js} +1 -1
- package/dist/inspector/assets/{entity_timeline-Dg0wEuRA.js → entity_timeline-B4XYY56n.js} +1 -1
- package/dist/inspector/assets/{entity_types-DLlkd4ex.js → entity_types-ByB2PWZM.js} +1 -1
- package/dist/inspector/assets/{faq-KbswV10B.js → faq-B-PEHwkf.js} +1 -1
- package/dist/inspector/assets/{graph_auto_fit-SqyYePaZ.js → graph_auto_fit-ClZnIOoR.js} +1 -1
- package/dist/inspector/assets/{graph_explorer-DZgjc-hi.js → graph_explorer-C-Xo8VWP.js} +1 -1
- package/dist/inspector/assets/{home-CUYUSmke.js → home-D1UVMr6_.js} +1 -1
- package/dist/inspector/assets/{index-BGqcUFFW.js → index-C6fxoS_Z.js} +1582 -1582
- package/dist/inspector/assets/{index-CBJY_OOI.js → index-Cp0BQ57U.js} +1 -1
- package/dist/inspector/assets/{index-DOxiDdC1.js → index-MnCv_KTr.js} +1 -1
- package/dist/inspector/assets/interpretations-BCs9qtw0.js +1 -0
- package/dist/inspector/assets/{interpretations-CSeyL3hr.js → interpretations-DG5kUN-V.js} +1 -1
- package/dist/inspector/assets/{issue_author_attribution-Czyui6JR.js → issue_author_attribution-D7_vwrHJ.js} +1 -1
- package/dist/inspector/assets/{issue_detail-DgdqvrIo.js → issue_detail-DKYUwKt_.js} +1 -1
- package/dist/inspector/assets/{issues-dw8Q41vn.js → issues-DcSMjt-p.js} +1 -1
- package/dist/inspector/assets/{json_viewer-CEMz7ftn.js → json_viewer-BKa7wwrs.js} +1 -1
- package/dist/inspector/assets/{label-qbFxe1yC.js → label-BO-aVMjO.js} +1 -1
- package/dist/inspector/assets/{live_relative_time-CVpdUZRq.js → live_relative_time-Dx00M9I6.js} +1 -1
- package/dist/inspector/assets/mobile_filter_popover-I9fJvTGr.js +1 -0
- package/dist/inspector/assets/{not_found-DFUrM9eP.js → not_found-DuCJouBh.js} +1 -1
- package/dist/inspector/assets/oauth_callback-w0kyGAb4.js +1 -0
- package/dist/inspector/assets/oauth_signin-3LQrxsKz.js +1 -0
- package/dist/inspector/assets/{observations-BO6KImWs.js → observations-Bq6mvl5m.js} +1 -1
- package/dist/inspector/assets/{page_shell-COxcPFXG.js → page_shell-BoTb5of6.js} +1 -1
- package/dist/inspector/assets/{pagination-NLnVe1CU.js → pagination-BJtT1Wgy.js} +1 -1
- package/dist/inspector/assets/{peer_detail-DdtQsiwD.js → peer_detail-BM1jhSS2.js} +1 -1
- package/dist/inspector/assets/{peers-D0bzQeyz.js → peers-CYSx-jAx.js} +1 -1
- package/dist/inspector/assets/{pin_primitive_button-BtuY3Ig7.js → pin_primitive_button-BdAR3e5K.js} +1 -1
- package/dist/inspector/assets/{recent_activity-8t3t2hCi.js → recent_activity-Dio9UBCA.js} +1 -1
- package/dist/inspector/assets/{recent_conversations-xURWFQ1G.js → recent_conversations-Be7S63h9.js} +1 -1
- package/dist/inspector/assets/{recent_conversations-B351X_is.js → recent_conversations-iJTSJf5e.js} +1 -1
- package/dist/inspector/assets/{recent_records_feed-C0auJYwP.js → recent_records_feed-ZxHjVjQ6.js} +1 -1
- package/dist/inspector/assets/record_activity-BmMC7Q7l.js +1 -0
- package/dist/inspector/assets/{relationship_detail-B9y50i1N.js → relationship_detail-i9rsGxA6.js} +1 -1
- package/dist/inspector/assets/{relationship_panel_groups-DgC2aJin.js → relationship_panel_groups-CXFlrRHU.js} +1 -1
- package/dist/inspector/assets/{relationships-u7QTLzYr.js → relationships-DqAzfnlB.js} +1 -1
- package/dist/inspector/assets/{relationships-DvN6JCJC.js → relationships-DvWtOU7W.js} +1 -1
- package/dist/inspector/assets/{sandbox-DzEfLQAo.js → sandbox-Cn4vq2Pz.js} +1 -1
- package/dist/inspector/assets/{schema_detail-BI3lLXFK.js → schema_detail-BdORXewP.js} +1 -1
- package/dist/inspector/assets/{schemas-DpAQVcki.js → schemas-HYsBtoHT.js} +1 -1
- package/dist/inspector/assets/{search-CjE75jdm.js → search-LzJnqvTB.js} +1 -1
- package/dist/inspector/assets/{segmented_control-D9QbgEtB.js → segmented_control-CHJO5zMt.js} +1 -1
- package/dist/inspector/assets/{select-KOFjYHgz.js → select-DFzP9laV.js} +1 -1
- package/dist/inspector/assets/settings-Bm0jNa4p.js +1 -0
- package/dist/inspector/assets/{source_content-Bi_jkeg2.js → source_content-PwVSPaIU.js} +1 -1
- package/dist/inspector/assets/{source_content_open_button-B9mhDPoj.js → source_content_open_button-C7NKRG7q.js} +1 -1
- package/dist/inspector/assets/{source_detail-B3jsntel.js → source_detail-C2D885Zy.js} +1 -1
- package/dist/inspector/assets/{source_link-DrAAN7IB.js → source_link-6lMlhQnK.js} +1 -1
- package/dist/inspector/assets/{sources-B7H4Tgy7.js → sources-BvGo5OZp.js} +1 -1
- package/dist/inspector/assets/{subscriptions-B79INOqC.js → subscriptions-BGYmtTLV.js} +1 -1
- package/dist/inspector/assets/{switch-DEw5ZD9Y.js → switch-DkusEYsE.js} +1 -1
- package/dist/inspector/assets/{tabs-CZDCOqHp.js → tabs-hkbPHxT0.js} +1 -1
- package/dist/inspector/assets/{textarea-DM2MsnIS.js → textarea-BhC7xtLk.js} +1 -1
- package/dist/inspector/assets/{timeline-DtGp-dM7.js → timeline-CHi-lYcV.js} +1 -1
- package/dist/inspector/assets/{timeline-CwKOl2cK.js → timeline-DmjoODDd.js} +1 -1
- package/dist/inspector/assets/{timeline_event_detail-D-gU-DZY.js → timeline_event_detail-BfKrsQih.js} +1 -1
- package/dist/inspector/assets/{turn_detail-D20KYWIY.js → turn_detail-DGj1lT0k.js} +1 -1
- package/dist/inspector/assets/{turns-CCukFhV6.js → turns-CHfOIg9X.js} +1 -1
- package/dist/inspector/assets/{use_agents-Duqes0yE.js → use_agents-6sUtEOpZ.js} +1 -1
- package/dist/inspector/assets/{use_entities-CAYbeIfx.js → use_entities-DeIlqnzx.js} +1 -1
- package/dist/inspector/assets/use_interpretations-DvfzvGu3.js +1 -0
- package/dist/inspector/assets/{use_mutations-CaZO8lpD.js → use_mutations-CQ3_5Ppg.js} +1 -1
- package/dist/inspector/assets/{use_peers-CGLvEf5V.js → use_peers-CW3OAs41.js} +1 -1
- package/dist/inspector/assets/{use_relationships-B8fSaOmY.js → use_relationships-Dbtmx8X8.js} +1 -1
- package/dist/inspector/assets/{use_stats-DHAaJFKE.js → use_stats-OyHBzetJ.js} +1 -1
- package/dist/inspector/assets/{use_timeline-BMIPVqoi.js → use_timeline-FINsibXm.js} +1 -1
- package/dist/inspector/assets/{use_turns-DRAnBf4e.js → use_turns-D4AhGAvM.js} +1 -1
- package/dist/inspector/assets/{world_time_event_timeline-CWFM4Q3K.js → world_time_event_timeline-F0elR7Vc.js} +1 -1
- package/dist/inspector/index.html +1 -1
- package/dist/proxy/mcp_stdio_proxy.d.ts +11 -5
- package/dist/proxy/mcp_stdio_proxy.d.ts.map +1 -1
- package/dist/proxy/mcp_stdio_proxy.js +12 -6
- package/dist/proxy/mcp_stdio_proxy.js.map +1 -1
- package/dist/repositories/sqlite/local_db_adapter.d.ts.map +1 -1
- package/dist/repositories/sqlite/local_db_adapter.js +12 -0
- package/dist/repositories/sqlite/local_db_adapter.js.map +1 -1
- package/dist/seed_schemas_entry.d.ts +28 -0
- package/dist/seed_schemas_entry.d.ts.map +1 -0
- package/dist/seed_schemas_entry.js +142 -0
- package/dist/seed_schemas_entry.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +92 -2
- package/dist/server.js.map +1 -1
- package/dist/services/company_query.d.ts +54 -0
- package/dist/services/company_query.d.ts.map +1 -0
- package/dist/services/company_query.js +175 -0
- package/dist/services/company_query.js.map +1 -0
- package/dist/services/company_resolution.d.ts +86 -0
- package/dist/services/company_resolution.d.ts.map +1 -0
- package/dist/services/company_resolution.js +195 -0
- package/dist/services/company_resolution.js.map +1 -0
- package/dist/services/entity_resolution.d.ts.map +1 -1
- package/dist/services/entity_resolution.js +12 -2
- package/dist/services/entity_resolution.js.map +1 -1
- package/dist/services/google_oidc.d.ts +110 -0
- package/dist/services/google_oidc.d.ts.map +1 -0
- package/dist/services/google_oidc.js +249 -0
- package/dist/services/google_oidc.js.map +1 -0
- package/dist/services/inspector_mount.d.ts.map +1 -1
- package/dist/services/inspector_mount.js +9 -0
- package/dist/services/inspector_mount.js.map +1 -1
- package/dist/services/issues/observer_import.d.ts +1 -1
- package/dist/services/issues/observer_import.d.ts.map +1 -1
- package/dist/services/issues/observer_import.js +3 -3
- package/dist/services/issues/observer_import.js.map +1 -1
- package/dist/services/mcp_oauth.d.ts +1 -1
- package/dist/services/mcp_oauth.d.ts.map +1 -1
- package/dist/services/mcp_oauth.js +11 -1
- package/dist/services/mcp_oauth.js.map +1 -1
- package/dist/services/schema_definitions.d.ts.map +1 -1
- package/dist/services/schema_definitions.js +27 -1
- package/dist/services/schema_definitions.js.map +1 -1
- package/dist/services/schema_reference_linking.d.ts +61 -2
- package/dist/services/schema_reference_linking.d.ts.map +1 -1
- package/dist/services/schema_reference_linking.js +264 -21
- package/dist/services/schema_reference_linking.js.map +1 -1
- package/dist/services/schema_registry.d.ts +13 -0
- package/dist/services/schema_registry.d.ts.map +1 -1
- package/dist/services/schema_registry.js +3 -0
- package/dist/services/schema_registry.js.map +1 -1
- package/dist/shared/action_handlers/entity_identifier_handler.d.ts.map +1 -1
- package/dist/shared/action_handlers/entity_identifier_handler.js +131 -4
- package/dist/shared/action_handlers/entity_identifier_handler.js.map +1 -1
- package/dist/shared/action_schemas.d.ts +43 -18
- package/dist/shared/action_schemas.d.ts.map +1 -1
- package/dist/shared/action_schemas.js +17 -0
- package/dist/shared/action_schemas.js.map +1 -1
- package/dist/shared/contract_mappings.d.ts.map +1 -1
- package/dist/shared/contract_mappings.js +9 -0
- package/dist/shared/contract_mappings.js.map +1 -1
- package/dist/shared/openapi_types.d.ts +130 -0
- package/dist/shared/openapi_types.d.ts.map +1 -1
- package/dist/tool_definitions.d.ts +1 -1
- package/dist/tool_definitions.d.ts.map +1 -1
- package/dist/tool_definitions.js +6 -0
- package/dist/tool_definitions.js.map +1 -1
- package/openapi.yaml +122 -0
- package/package.json +1 -1
- package/dist/inspector/assets/access_policies-C0QzIgOo.js +0 -1
- package/dist/inspector/assets/interpretations-B1shK6Is.js +0 -1
- package/dist/inspector/assets/mobile_filter_popover-CI_BhFTn.js +0 -1
- package/dist/inspector/assets/record_activity-DUwg1WBC.js +0 -1
- package/dist/inspector/assets/settings-CHzeuzGL.js +0 -1
- package/dist/inspector/assets/use_interpretations-D_RbNlHg.js +0 -1
package/dist/actions.d.ts
CHANGED
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAsC9B,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAarC,OAAO,EAGL,KAAK,aAAa,EAGnB,MAAM,4BAA4B,CAAC;AA4BpC,OAAO,EAQL,KAAK,sBAAsB,EAC5B,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/actions.js
CHANGED
|
@@ -53,6 +53,7 @@ import { resolveSandboxReportTransport } from "./services/sandbox/transport.js";
|
|
|
53
53
|
import { getSqliteDb } from "./repositories/sqlite/sqlite_client.js";
|
|
54
54
|
import { getMcpAuthToken } from "./crypto/mcp_auth_token.js";
|
|
55
55
|
import { isOauthKeyCredentialValid, normalizeOauthNextPath, OAuthKeySessionStore, } from "./services/oauth_key_gate.js";
|
|
56
|
+
import { buildGoogleAuthorizeUrl, createGoogleSigninNonce, consumeGoogleSigninNonce, exchangeGoogleAuthorizationCode, getSharedGraphUserId, GoogleIdTokenError, isGoogleSigninEnabled, verifyGoogleIdToken, } from "./services/google_oidc.js";
|
|
56
57
|
import { AnalyzeSchemaCandidatesRequestSchema, AuditUndeclaredFragmentsRequestSchema, CorrectEntityRequestSchema, CreateInterpretationRequestSchema, CreateRelationshipsRequestSchema, CreateRelationshipRequestSchema, DeleteEntityRequestSchema, DeleteRelationshipRequestSchema, IssuesBulkEntityIdsRequestSchema, IssuesAddMessageRequestSchema, IssuesGetStatusRequestSchema, IssuesSubmitRequestSchema, IssuesSyncRequestSchema, EntitiesQueryRequestSchema, EntitySnapshotRequestSchema, FieldProvenanceRequestSchema, GetSchemaRecommendationsRequestSchema, ListObservationsRequestSchema, ListRelationshipsRequestSchema, MergeEntitiesRequestSchema, SplitEntityRequestSchema, ObservationsQueryRequestSchema, RegisterSchemaRequestSchema, RelationshipSnapshotRequestSchema, RestoreEntityRequestSchema, RestoreRelationshipRequestSchema, RetrieveEntityByIdentifierSchema, RetrieveGraphNeighborhoodSchema, RetrieveRelatedEntitiesSchema, RELATIONSHIP_ENTITY_ID_FORMAT_HINT, RELATIONSHIP_ENTITY_ID_FORMAT_ISSUE_CODE, StoreRequestSchema, UpdateSchemaIncrementalRequestSchema, } from "./shared/action_schemas.js";
|
|
57
58
|
import { getMimeTypeFromExtension } from "./services/file_text_extraction.js";
|
|
58
59
|
import { queryEntitiesWithCount } from "./shared/action_handlers/entity_handlers.js";
|
|
@@ -1096,6 +1097,16 @@ export function isLocalRequest(req) {
|
|
|
1096
1097
|
}
|
|
1097
1098
|
const OAUTH_KEY_SESSION_COOKIE = "neotoma_oauth_key_session";
|
|
1098
1099
|
const oauthKeySessions = new OAuthKeySessionStore();
|
|
1100
|
+
/**
|
|
1101
|
+
* Maps an OAuth key-session token to the user_id resolved via Google
|
|
1102
|
+
* sign-in for that browser session. Populated only by the
|
|
1103
|
+
* `/mcp/oauth/google/callback` route; every other credential path
|
|
1104
|
+
* (private key / mnemonic / bearer) never writes here, so
|
|
1105
|
+
* `/mcp/oauth/local-login` falls through to `ensureLocalDevUser()`
|
|
1106
|
+
* exactly as before when this map has no entry — behavior for every
|
|
1107
|
+
* existing deploy (Google flag off) is unchanged.
|
|
1108
|
+
*/
|
|
1109
|
+
const googleVerifiedUserBySessionToken = new Map();
|
|
1099
1110
|
function readCookie(req, name) {
|
|
1100
1111
|
const header = (req.headers["cookie"] || req.headers["Cookie"] || "");
|
|
1101
1112
|
if (!header)
|
|
@@ -1335,6 +1346,14 @@ function setOAuthKeySessionCookie(req, res) {
|
|
|
1335
1346
|
path: "/mcp/oauth",
|
|
1336
1347
|
maxAge: 15 * 60 * 1000,
|
|
1337
1348
|
});
|
|
1349
|
+
return token;
|
|
1350
|
+
}
|
|
1351
|
+
/** Resolve the local-auth user_id a Google-verified session (if any) mapped to this request. */
|
|
1352
|
+
function getGoogleVerifiedUserId(req) {
|
|
1353
|
+
const token = readCookie(req, OAUTH_KEY_SESSION_COOKIE);
|
|
1354
|
+
if (!token || !oauthKeySessions.isValid(token))
|
|
1355
|
+
return undefined;
|
|
1356
|
+
return googleVerifiedUserBySessionToken.get(token);
|
|
1338
1357
|
}
|
|
1339
1358
|
/**
|
|
1340
1359
|
* Derive the canonical `@authority` the AAuth profile requires (AAuth §10.3.1).
|
|
@@ -1631,11 +1650,11 @@ app.all("/mcp", async (req, res) => {
|
|
|
1631
1650
|
const hadSessionHeader = typeof sessionId === "string" && sessionId.length > 0;
|
|
1632
1651
|
if (hadSessionHeader) {
|
|
1633
1652
|
logger.warn(`[MCP HTTP] Unknown or expired Mcp-Session-Id (first 8 chars): ${sessionId.slice(0, 8)}... often wrong replica behind a load balancer, API restart, or stale client state`);
|
|
1634
|
-
return res.status(
|
|
1653
|
+
return res.status(404).json({
|
|
1635
1654
|
jsonrpc: "2.0",
|
|
1636
1655
|
error: {
|
|
1637
1656
|
code: -32001,
|
|
1638
|
-
message: "
|
|
1657
|
+
message: "Not Found: MCP session is unknown or expired on this API instance. The client should re-initialize by sending a new InitializeRequest without a session ID. If you run multiple replicas, enable sticky sessions for POST /mcp (or route /mcp to a single instance).",
|
|
1639
1658
|
},
|
|
1640
1659
|
id: rpcId,
|
|
1641
1660
|
});
|
|
@@ -2104,10 +2123,19 @@ app.get("/mcp/oauth/key-auth", async (req, res) => {
|
|
|
2104
2123
|
const nextPathEscaped = escapeHtml(nextPath);
|
|
2105
2124
|
const hasBearerFallback = Boolean((process.env.NEOTOMA_BEARER_TOKEN || "").trim());
|
|
2106
2125
|
const defaultCredentialMode = hasBearerFallback ? "bearer" : "private_key";
|
|
2126
|
+
const googleEnabled = isGoogleSigninEnabled();
|
|
2127
|
+
const googleStartHref = `/mcp/oauth/google/start?next=${encodeURIComponent(nextPath)}`;
|
|
2107
2128
|
return res.send(renderOauthPage({
|
|
2108
2129
|
title: "Authenticate OAuth preflight",
|
|
2109
2130
|
subtitle: "Choose one credential path below, then continue to complete OAuth authorization.",
|
|
2110
2131
|
contentHtml: `
|
|
2132
|
+
${googleEnabled
|
|
2133
|
+
? `<div class="actions" style="margin-bottom: 1rem;">
|
|
2134
|
+
<a class="btn-link" href="${escapeHtml(googleStartHref)}">Sign in with Google</a>
|
|
2135
|
+
</div>
|
|
2136
|
+
<div class="notice">Signs you in as your own Neotoma user if your Google account's verified email is on this server's approved list. Doesn't require a private key.</div>
|
|
2137
|
+
<hr style="margin: 1.5rem 0; border: none; border-top: 1px solid hsl(var(--border));" />`
|
|
2138
|
+
: ""}
|
|
2111
2139
|
<form method="post" action="/mcp/oauth/key-auth" id="oauth-key-auth-form">
|
|
2112
2140
|
<input type="hidden" name="next" value="${nextPathEscaped}" />
|
|
2113
2141
|
<input type="hidden" name="credential_mode" id="credential_mode" value="${defaultCredentialMode}" />
|
|
@@ -2213,6 +2241,107 @@ app.post("/mcp/oauth/key-auth", express.urlencoded({ extended: true }), async (r
|
|
|
2213
2241
|
setOAuthKeySessionCookie(req, res);
|
|
2214
2242
|
return res.redirect(nextPath);
|
|
2215
2243
|
});
|
|
2244
|
+
/**
|
|
2245
|
+
* "Sign in with Google" entry point. Additive to, and independent of, the
|
|
2246
|
+
* key/mnemonic/bearer credential form above — feature-flagged off unless
|
|
2247
|
+
* NEOTOMA_GOOGLE_CLIENT_ID + NEOTOMA_APPROVED_EMAILS are both configured.
|
|
2248
|
+
* AUTH-LAYER ONLY: this establishes who the person is (their own user_id
|
|
2249
|
+
* via the existing per-email primitive); it does not touch data-sharing or
|
|
2250
|
+
* read-scoping.
|
|
2251
|
+
*/
|
|
2252
|
+
app.get("/mcp/oauth/google/start", async (req, res) => {
|
|
2253
|
+
if (!isGoogleSigninEnabled()) {
|
|
2254
|
+
return res.status(404).send("Not found");
|
|
2255
|
+
}
|
|
2256
|
+
const nextPath = normalizeOauthNextPath(req.query.next || undefined);
|
|
2257
|
+
const nonce = createGoogleSigninNonce(nextPath);
|
|
2258
|
+
const redirectUri = `${req.protocol}://${req.get("host") || ""}/mcp/oauth/google/callback`;
|
|
2259
|
+
try {
|
|
2260
|
+
const authorizeUrl = buildGoogleAuthorizeUrl({ redirectUri, nonce });
|
|
2261
|
+
return res.redirect(authorizeUrl);
|
|
2262
|
+
}
|
|
2263
|
+
catch (error) {
|
|
2264
|
+
logError("GoogleOAuthStart", req, error);
|
|
2265
|
+
return res.status(500).send(error?.message ?? "Failed to start Google sign-in");
|
|
2266
|
+
}
|
|
2267
|
+
});
|
|
2268
|
+
app.get("/mcp/oauth/google/callback", async (req, res) => {
|
|
2269
|
+
if (!isGoogleSigninEnabled()) {
|
|
2270
|
+
return res.status(404).send("Not found");
|
|
2271
|
+
}
|
|
2272
|
+
const errorParam = req.query.error?.trim();
|
|
2273
|
+
const code = req.query.code?.trim();
|
|
2274
|
+
const nonceParam = req.query.state?.trim();
|
|
2275
|
+
const failWith = (subtitle) => {
|
|
2276
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
2277
|
+
return res.status(401).send(renderOauthPage({
|
|
2278
|
+
title: "Google sign-in failed",
|
|
2279
|
+
subtitle,
|
|
2280
|
+
contentHtml: `<div class="actions">
|
|
2281
|
+
<a class="btn-link secondary" href="/mcp/oauth/key-auth">Back to authentication</a>
|
|
2282
|
+
</div>`,
|
|
2283
|
+
}));
|
|
2284
|
+
};
|
|
2285
|
+
if (errorParam) {
|
|
2286
|
+
logger.warn("[Google OAuth] Callback returned an error", { error: errorParam });
|
|
2287
|
+
return failWith("Google sign-in was cancelled or denied.");
|
|
2288
|
+
}
|
|
2289
|
+
if (!code || !nonceParam) {
|
|
2290
|
+
return failWith("Missing code or state from Google callback.");
|
|
2291
|
+
}
|
|
2292
|
+
const nonceEntry = consumeGoogleSigninNonce(nonceParam);
|
|
2293
|
+
if (!nonceEntry) {
|
|
2294
|
+
return failWith("This sign-in link has expired or was already used. Please try again.");
|
|
2295
|
+
}
|
|
2296
|
+
// Same nextPath contract as the key/mnemonic/bearer path above: normalized
|
|
2297
|
+
// back to a /mcp/oauth/* path (typically /mcp/oauth/authorize?...), never
|
|
2298
|
+
// an external URL.
|
|
2299
|
+
const nextPath = normalizeOauthNextPath(nonceEntry.next);
|
|
2300
|
+
const redirectUri = `${req.protocol}://${req.get("host") || ""}/mcp/oauth/google/callback`;
|
|
2301
|
+
try {
|
|
2302
|
+
const { idToken } = await exchangeGoogleAuthorizationCode({ code, redirectUri });
|
|
2303
|
+
const { email } = await verifyGoogleIdToken(idToken);
|
|
2304
|
+
// Resolve the verified email to a stable user_id via the EXISTING per-email
|
|
2305
|
+
// primitive (local_auth.ts) — the same primitive createLocalAuthUser /
|
|
2306
|
+
// hashEmailToUserId already uses elsewhere. By default this person is
|
|
2307
|
+
// admitted as their own isolated user_id, same as any other local-auth user.
|
|
2308
|
+
const { createLocalAuthUser } = await import("./services/local_auth.js");
|
|
2309
|
+
const { randomBytes } = await import("node:crypto");
|
|
2310
|
+
// Password is unused for Google-authenticated users (they never log in
|
|
2311
|
+
// with it) — generate an unguessable throwaway so createLocalAuthUser's
|
|
2312
|
+
// shared code path is satisfied without weakening any other account.
|
|
2313
|
+
const throwawayPassword = randomBytes(32).toString("hex");
|
|
2314
|
+
const perEmailUser = createLocalAuthUser(email, throwawayPassword);
|
|
2315
|
+
// Shared-graph opt-in: when NEOTOMA_SHARED_GRAPH_USER_ID is set, an
|
|
2316
|
+
// approved teammate (the email already passed the allowlist inside
|
|
2317
|
+
// verifyGoogleIdToken) is bound to the shared graph's user_id instead of
|
|
2318
|
+
// their isolated per-email one — so the whole allowlisted team, plus the
|
|
2319
|
+
// bearer/MCP identity that owns the data, share one populated graph. Unset
|
|
2320
|
+
// → isolated per-email behavior (unchanged). See getSharedGraphUserId.
|
|
2321
|
+
const resolvedUserId = getSharedGraphUserId() ?? perEmailUser.id;
|
|
2322
|
+
// Mark this browser session as Google-verified and bound to the resolved
|
|
2323
|
+
// user_id, exactly the same OAuth key-session cookie the private-key/
|
|
2324
|
+
// mnemonic/bearer path sets. `/mcp/oauth/authorize` -> `/mcp/oauth/
|
|
2325
|
+
// local-login` then runs completely unmodified, except local-login now
|
|
2326
|
+
// resolves the user via this session instead of always ensureLocalDevUser().
|
|
2327
|
+
const sessionToken = setOAuthKeySessionCookie(req, res);
|
|
2328
|
+
googleVerifiedUserBySessionToken.set(sessionToken, resolvedUserId);
|
|
2329
|
+
return res.redirect(nextPath);
|
|
2330
|
+
}
|
|
2331
|
+
catch (error) {
|
|
2332
|
+
logError("GoogleOAuthCallback", req, error);
|
|
2333
|
+
if (error instanceof GoogleIdTokenError) {
|
|
2334
|
+
if (error.code === "EMAIL_NOT_APPROVED") {
|
|
2335
|
+
return failWith("Your Google account is not on the approved list for this server.");
|
|
2336
|
+
}
|
|
2337
|
+
if (error.code === "EMAIL_NOT_VERIFIED") {
|
|
2338
|
+
return failWith("Your Google account's email is not verified.");
|
|
2339
|
+
}
|
|
2340
|
+
return failWith("Google sign-in could not be verified.");
|
|
2341
|
+
}
|
|
2342
|
+
return failWith(error?.message ?? "Google sign-in failed.");
|
|
2343
|
+
}
|
|
2344
|
+
});
|
|
2216
2345
|
// RFC 8414 authorization endpoint (GET) for Cursor and other OAuth clients
|
|
2217
2346
|
app.get("/mcp/oauth/authorize", async (req, res) => {
|
|
2218
2347
|
try {
|
|
@@ -2263,7 +2392,10 @@ app.get("/mcp/oauth/authorize", async (req, res) => {
|
|
|
2263
2392
|
// When reached via tunnel, only allow redirect_uri to localhost, app schemes, or OpenAI Custom GPT
|
|
2264
2393
|
if (!isLocalRequest(req)) {
|
|
2265
2394
|
const { isRedirectUriAllowedForTunnel } = await import("./services/mcp_oauth.js");
|
|
2266
|
-
|
|
2395
|
+
// Public host as seen from outside the tunnel (x-forwarded-host set by the
|
|
2396
|
+
// proxy) so an Inspector callback on this instance's own origin is allowed.
|
|
2397
|
+
const selfHost = req.header("x-forwarded-host")?.split(",")[0]?.trim() || req.get("host");
|
|
2398
|
+
if (!isRedirectUriAllowedForTunnel(redirect_uri, selfHost)) {
|
|
2267
2399
|
logger.warn("[MCP OAuth] Authorize rejected: redirect_uri not allowed for tunnel", {
|
|
2268
2400
|
redirect_uri: sanitizeRedirectUriForLog(redirect_uri),
|
|
2269
2401
|
});
|
|
@@ -2378,9 +2510,15 @@ app.get("/mcp/oauth/local-login", async (req, res) => {
|
|
|
2378
2510
|
}));
|
|
2379
2511
|
}
|
|
2380
2512
|
try {
|
|
2381
|
-
|
|
2513
|
+
// If this browser session was admitted via Google sign-in (see
|
|
2514
|
+
// /mcp/oauth/google/callback), complete authorization as THAT verified
|
|
2515
|
+
// user's own user_id instead of the shared dev user. Every other path
|
|
2516
|
+
// (no Google session on this cookie — the default, and the only
|
|
2517
|
+
// possibility when the Google feature flag is off) is unchanged.
|
|
2518
|
+
const googleUserId = getGoogleVerifiedUserId(req);
|
|
2519
|
+
const resolvedUserId = googleUserId ?? ensureLocalDevUser().id;
|
|
2382
2520
|
const { completeLocalAuthorization } = await import("./services/mcp_oauth.js");
|
|
2383
|
-
const { connectionId, redirectUri, clientState } = await completeLocalAuthorization(state,
|
|
2521
|
+
const { connectionId, redirectUri, clientState } = await completeLocalAuthorization(state, resolvedUserId);
|
|
2384
2522
|
const frontendBase = process.env.NEOTOMA_FRONTEND_URL || process.env.FRONTEND_URL || "http://localhost:5195";
|
|
2385
2523
|
const frontendOauth = `${frontendBase}/oauth`;
|
|
2386
2524
|
if (redirectUri) {
|
|
@@ -5834,6 +5972,12 @@ export async function storeStructuredForApi(params) {
|
|
|
5834
5972
|
// entity_id.
|
|
5835
5973
|
const priorSnapshotByEntityId = new Map();
|
|
5836
5974
|
const newSnapshotByEntityId = new Map();
|
|
5975
|
+
// #1963: auto-link may retract a stale reference-field edge (e.g. a contact's
|
|
5976
|
+
// organization moved companies). A retraction *failure* must not be silent —
|
|
5977
|
+
// that would reproduce the very silent-drift bug this fix exists to close, one
|
|
5978
|
+
// layer up. Accumulate per-observation retraction outcomes here so the
|
|
5979
|
+
// schemaStoreWarnings pass below can surface them on the store response.
|
|
5980
|
+
const autoLinkRetractionByObsIndex = new Map();
|
|
5837
5981
|
for (const r of resolved) {
|
|
5838
5982
|
let observation_id = null;
|
|
5839
5983
|
let snapshotAfter = null;
|
|
@@ -5917,14 +6061,25 @@ export async function storeStructuredForApi(params) {
|
|
|
5917
6061
|
const schemaEntry = await schemaRegistry.loadActiveSchema(r.entity_type, userId);
|
|
5918
6062
|
if (schemaEntry?.schema_definition?.reference_fields?.length) {
|
|
5919
6063
|
const { autoLinkReferenceFields } = await import("./services/schema_reference_linking.js");
|
|
5920
|
-
await autoLinkReferenceFields({
|
|
6064
|
+
const autoLinkResult = await autoLinkReferenceFields({
|
|
5921
6065
|
entityId: r.entity_id,
|
|
5922
6066
|
entityType: r.entity_type,
|
|
5923
6067
|
fields: r.fields,
|
|
5924
6068
|
schema: schemaEntry.schema_definition,
|
|
5925
6069
|
userId,
|
|
5926
6070
|
sourceId: observationSourceId,
|
|
6071
|
+
commit,
|
|
5927
6072
|
});
|
|
6073
|
+
if (autoLinkResult.retracted > 0 || autoLinkResult.retraction_failures > 0) {
|
|
6074
|
+
autoLinkRetractionByObsIndex.set(r.observation_index, {
|
|
6075
|
+
entity_type: r.entity_type,
|
|
6076
|
+
entity_id: r.entity_id,
|
|
6077
|
+
retracted: autoLinkResult.retracted,
|
|
6078
|
+
retraction_failures: autoLinkResult.retraction_failures,
|
|
6079
|
+
failed_target_entity_ids: autoLinkResult.failed_retraction_target_entity_ids,
|
|
6080
|
+
failed_retractions: autoLinkResult.failed_retractions,
|
|
6081
|
+
});
|
|
6082
|
+
}
|
|
5928
6083
|
}
|
|
5929
6084
|
}
|
|
5930
6085
|
catch (linkErr) {
|
|
@@ -6254,6 +6409,46 @@ export async function storeStructuredForApi(params) {
|
|
|
6254
6409
|
}
|
|
6255
6410
|
}
|
|
6256
6411
|
}
|
|
6412
|
+
// #1963: surface auto-link edge retractions on the store response so a
|
|
6413
|
+
// retraction — and especially a retraction *failure* — is never silent. A
|
|
6414
|
+
// failure means a stale reference-field edge may still be live despite the
|
|
6415
|
+
// store reporting success, so it is emitted as its own actionable warning.
|
|
6416
|
+
for (const [obsIndex, rec] of autoLinkRetractionByObsIndex) {
|
|
6417
|
+
if (rec.retraction_failures > 0) {
|
|
6418
|
+
schemaStoreWarnings.push({
|
|
6419
|
+
code: "AUTO_LINK_RETRACTION_FAILED",
|
|
6420
|
+
message: `Auto-link retraction failed for ${rec.retraction_failures} stale ` +
|
|
6421
|
+
`reference-field edge(s) on ${rec.entity_type}/${rec.entity_id}. ` +
|
|
6422
|
+
`A superseded edge (e.g. a prior works_at) may still be live even though ` +
|
|
6423
|
+
`the store succeeded. To clean up, call delete_relationship for each ` +
|
|
6424
|
+
`stale edge in details.stale_edges, or re-run the store.`,
|
|
6425
|
+
observation_index: obsIndex,
|
|
6426
|
+
entity_type: rec.entity_type,
|
|
6427
|
+
entity_id: rec.entity_id,
|
|
6428
|
+
// Structured remediation: each entry is a ready-to-use delete_relationship
|
|
6429
|
+
// argument set, so the caller needs no knowledge of its own schema.
|
|
6430
|
+
details: {
|
|
6431
|
+
stale_edges: rec.failed_retractions.map((f) => ({
|
|
6432
|
+
source_entity_id: rec.entity_id,
|
|
6433
|
+
target_entity_id: f.target_entity_id,
|
|
6434
|
+
relationship_type: f.relationship_type,
|
|
6435
|
+
field_name: f.field,
|
|
6436
|
+
})),
|
|
6437
|
+
},
|
|
6438
|
+
});
|
|
6439
|
+
}
|
|
6440
|
+
else if (rec.retracted > 0) {
|
|
6441
|
+
schemaStoreWarnings.push({
|
|
6442
|
+
code: "AUTO_LINK_EDGE_RETRACTED",
|
|
6443
|
+
message: `Retracted ${rec.retracted} stale auto-linked reference-field edge(s) on ` +
|
|
6444
|
+
`${rec.entity_type}/${rec.entity_id} because the field's resolved target ` +
|
|
6445
|
+
`changed (#1963).`,
|
|
6446
|
+
observation_index: obsIndex,
|
|
6447
|
+
entity_type: rec.entity_type,
|
|
6448
|
+
entity_id: rec.entity_id,
|
|
6449
|
+
});
|
|
6450
|
+
}
|
|
6451
|
+
}
|
|
6257
6452
|
const unknownFieldNames = Array.from(unknownFieldNamesSet).sort();
|
|
6258
6453
|
// Conditional hint (#1549): update_schema_incremental requires the schema to
|
|
6259
6454
|
// declare canonical_name_fields, else it dead-ends on
|