studiograph 1.3.3-next.9 → 1.3.4

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.
Files changed (282) hide show
  1. package/dist/agent/orchestrator.d.ts +2 -0
  2. package/dist/agent/orchestrator.js +13 -5
  3. package/dist/agent/orchestrator.js.map +1 -1
  4. package/dist/agent/skills/sync-configuration.md +4 -29
  5. package/dist/agent/skills/sync-setup.md +2 -4
  6. package/dist/agent/tools/ops-tools.js +15 -126
  7. package/dist/agent/tools/ops-tools.js.map +1 -1
  8. package/dist/agent/tools/sync-tools.d.ts +7 -6
  9. package/dist/agent/tools/sync-tools.js +205 -178
  10. package/dist/agent/tools/sync-tools.js.map +1 -1
  11. package/dist/cli/commands/about.d.ts +13 -0
  12. package/dist/cli/commands/about.js +97 -0
  13. package/dist/cli/commands/about.js.map +1 -0
  14. package/dist/cli/commands/clone.d.ts +5 -2
  15. package/dist/cli/commands/clone.js +131 -62
  16. package/dist/cli/commands/clone.js.map +1 -1
  17. package/dist/cli/commands/connector.d.ts +2 -16
  18. package/dist/cli/commands/connector.js +32 -109
  19. package/dist/cli/commands/connector.js.map +1 -1
  20. package/dist/cli/commands/deploy.d.ts +0 -1
  21. package/dist/cli/commands/deploy.js +13 -103
  22. package/dist/cli/commands/deploy.js.map +1 -1
  23. package/dist/cli/commands/init.js +6 -93
  24. package/dist/cli/commands/init.js.map +1 -1
  25. package/dist/cli/commands/join.js +51 -1
  26. package/dist/cli/commands/join.js.map +1 -1
  27. package/dist/cli/commands/redeploy.js +1 -2
  28. package/dist/cli/commands/redeploy.js.map +1 -1
  29. package/dist/cli/commands/serve.d.ts +1 -3
  30. package/dist/cli/commands/serve.js +29 -109
  31. package/dist/cli/commands/serve.js.map +1 -1
  32. package/dist/cli/commands/start.js +1 -1
  33. package/dist/cli/commands/start.js.map +1 -1
  34. package/dist/cli/commands/sync-collection.d.ts +14 -0
  35. package/dist/cli/commands/sync-collection.js +366 -0
  36. package/dist/cli/commands/sync-collection.js.map +1 -0
  37. package/dist/cli/commands/sync.js +518 -82
  38. package/dist/cli/commands/sync.js.map +1 -1
  39. package/dist/cli/index.js +12 -30
  40. package/dist/cli/index.js.map +1 -1
  41. package/dist/cli/setup-wizard.d.ts +0 -13
  42. package/dist/cli/setup-wizard.js +6 -81
  43. package/dist/cli/setup-wizard.js.map +1 -1
  44. package/dist/core/types.d.ts +140 -21
  45. package/dist/core/types.js +15 -4
  46. package/dist/core/types.js.map +1 -1
  47. package/dist/core/workspace.d.ts +11 -4
  48. package/dist/core/workspace.js +61 -26
  49. package/dist/core/workspace.js.map +1 -1
  50. package/dist/integrations/asana.d.ts +26 -0
  51. package/dist/integrations/asana.js +77 -0
  52. package/dist/integrations/asana.js.map +1 -0
  53. package/dist/integrations/figma-local.d.ts +16 -0
  54. package/dist/integrations/figma-local.js +10 -0
  55. package/dist/integrations/figma-local.js.map +1 -0
  56. package/dist/integrations/figma.d.ts +17 -0
  57. package/dist/integrations/figma.js +16 -0
  58. package/dist/integrations/figma.js.map +1 -0
  59. package/dist/integrations/granola.d.ts +24 -0
  60. package/dist/integrations/granola.js +59 -0
  61. package/dist/integrations/granola.js.map +1 -0
  62. package/dist/integrations/linear.d.ts +14 -0
  63. package/dist/integrations/linear.js +70 -0
  64. package/dist/integrations/linear.js.map +1 -0
  65. package/dist/integrations/paper-local.d.ts +14 -0
  66. package/dist/integrations/paper-local.js +10 -0
  67. package/dist/integrations/paper-local.js.map +1 -0
  68. package/dist/integrations/paper.d.ts +2 -0
  69. package/dist/integrations/paper.js +10 -0
  70. package/dist/integrations/paper.js.map +1 -0
  71. package/dist/integrations/pipedrive.d.ts +26 -0
  72. package/dist/integrations/pipedrive.js +97 -0
  73. package/dist/integrations/pipedrive.js.map +1 -0
  74. package/dist/integrations/registry.d.ts +15 -0
  75. package/dist/integrations/registry.js +27 -0
  76. package/dist/integrations/registry.js.map +1 -0
  77. package/dist/integrations/types.d.ts +34 -0
  78. package/dist/integrations/types.js +9 -0
  79. package/dist/integrations/types.js.map +1 -0
  80. package/dist/mcp/connector-manager.d.ts +45 -31
  81. package/dist/mcp/connector-manager.js +164 -116
  82. package/dist/mcp/connector-manager.js.map +1 -1
  83. package/dist/mcp/server-oauth-provider.d.ts +56 -0
  84. package/dist/mcp/server-oauth-provider.js +138 -0
  85. package/dist/mcp/server-oauth-provider.js.map +1 -0
  86. package/dist/server/chrome/chrome.css +142 -28
  87. package/dist/server/chrome/chrome.js +51 -25
  88. package/dist/server/collab-authority.d.ts +70 -0
  89. package/dist/server/collab-authority.js +218 -0
  90. package/dist/server/collab-authority.js.map +1 -0
  91. package/dist/server/collab.d.ts +29 -0
  92. package/dist/server/collab.js +195 -0
  93. package/dist/server/collab.js.map +1 -0
  94. package/dist/server/commit-scheduler.d.ts +1 -1
  95. package/dist/server/commit-scheduler.js +18 -4
  96. package/dist/server/commit-scheduler.js.map +1 -1
  97. package/dist/server/index.d.ts +0 -2
  98. package/dist/server/index.js +89 -18
  99. package/dist/server/index.js.map +1 -1
  100. package/dist/server/routes/auth-api.d.ts +6 -0
  101. package/dist/server/routes/auth-api.js +55 -0
  102. package/dist/server/routes/auth-api.js.map +1 -1
  103. package/dist/server/routes/collab.d.ts +6 -0
  104. package/dist/server/routes/collab.js +10 -0
  105. package/dist/server/routes/collab.js.map +1 -0
  106. package/dist/server/routes/git-http.d.ts +1 -1
  107. package/dist/server/routes/git-http.js +53 -15
  108. package/dist/server/routes/git-http.js.map +1 -1
  109. package/dist/server/routes/graph-api.d.ts +2 -2
  110. package/dist/server/routes/graph-api.js +59 -55
  111. package/dist/server/routes/graph-api.js.map +1 -1
  112. package/dist/server/routes/mcp.d.ts +12 -0
  113. package/dist/server/routes/mcp.js +35 -0
  114. package/dist/server/routes/mcp.js.map +1 -0
  115. package/dist/server/routes/permissions-api.d.ts +2 -1
  116. package/dist/server/routes/permissions-api.js +16 -2
  117. package/dist/server/routes/permissions-api.js.map +1 -1
  118. package/dist/server/routes/sync-api.d.ts +26 -0
  119. package/dist/server/routes/sync-api.js +757 -0
  120. package/dist/server/routes/sync-api.js.map +1 -0
  121. package/dist/server/routes/ws.d.ts +4 -2
  122. package/dist/server/routes/ws.js +100 -4
  123. package/dist/server/routes/ws.js.map +1 -1
  124. package/dist/server/session-manager.d.ts +40 -0
  125. package/dist/server/session-manager.js +132 -0
  126. package/dist/server/session-manager.js.map +1 -0
  127. package/dist/server/ws-hub.d.ts +95 -1
  128. package/dist/server/ws-hub.js +192 -5
  129. package/dist/server/ws-hub.js.map +1 -1
  130. package/dist/server/yjs-manager.d.ts +59 -0
  131. package/dist/server/yjs-manager.js +194 -0
  132. package/dist/server/yjs-manager.js.map +1 -0
  133. package/dist/services/auth-service.d.ts +30 -2
  134. package/dist/services/auth-service.js +116 -11
  135. package/dist/services/auth-service.js.map +1 -1
  136. package/dist/services/git.d.ts +6 -0
  137. package/dist/services/git.js +32 -2
  138. package/dist/services/git.js.map +1 -1
  139. package/dist/services/sync/collection-sync.d.ts +73 -0
  140. package/dist/services/sync/collection-sync.js +726 -0
  141. package/dist/services/sync/collection-sync.js.map +1 -0
  142. package/dist/services/sync/commit.js +5 -20
  143. package/dist/services/sync/commit.js.map +1 -1
  144. package/dist/services/sync/data-fetcher.d.ts +31 -0
  145. package/dist/services/sync/data-fetcher.js +12 -0
  146. package/dist/services/sync/data-fetcher.js.map +1 -0
  147. package/dist/services/sync/entity-refresh.d.ts +30 -0
  148. package/dist/services/sync/entity-refresh.js +275 -0
  149. package/dist/services/sync/entity-refresh.js.map +1 -0
  150. package/dist/services/sync/frontmatter-extractor.d.ts +2 -2
  151. package/dist/services/sync/frontmatter-extractor.js +1 -2
  152. package/dist/services/sync/frontmatter-extractor.js.map +1 -1
  153. package/dist/services/sync/graph-match.js +1 -1
  154. package/dist/services/sync/graph-match.js.map +1 -1
  155. package/dist/services/sync/mcp-client.d.ts +16 -4
  156. package/dist/services/sync/mcp-client.js +34 -20
  157. package/dist/services/sync/mcp-client.js.map +1 -1
  158. package/dist/services/sync/prompts.js +1 -1
  159. package/dist/services/sync/reconciler.js +1 -2
  160. package/dist/services/sync/reconciler.js.map +1 -1
  161. package/dist/services/sync/rest-client.d.ts +40 -0
  162. package/dist/services/sync/rest-client.js +100 -0
  163. package/dist/services/sync/rest-client.js.map +1 -0
  164. package/dist/services/sync/source-config.d.ts +23 -1
  165. package/dist/services/sync/source-config.js +112 -16
  166. package/dist/services/sync/source-config.js.map +1 -1
  167. package/dist/services/sync/source-definitions/asana.d.ts +3 -4
  168. package/dist/services/sync/source-definitions/asana.js +7 -13
  169. package/dist/services/sync/source-definitions/asana.js.map +1 -1
  170. package/dist/services/sync/source-definitions/definitions.d.ts +5 -18
  171. package/dist/services/sync/source-definitions/definitions.js +4 -22
  172. package/dist/services/sync/source-definitions/definitions.js.map +1 -1
  173. package/dist/services/sync/source-definitions/granola.d.ts +1 -1
  174. package/dist/services/sync/source-definitions/granola.js +11 -18
  175. package/dist/services/sync/source-definitions/granola.js.map +1 -1
  176. package/dist/services/sync/source-definitions/linear.d.ts +1 -1
  177. package/dist/services/sync/source-definitions/linear.js +17 -15
  178. package/dist/services/sync/source-definitions/linear.js.map +1 -1
  179. package/dist/services/sync/source-definitions/pipedrive.d.ts +1 -1
  180. package/dist/services/sync/source-definitions/pipedrive.js +6 -15
  181. package/dist/services/sync/source-definitions/pipedrive.js.map +1 -1
  182. package/dist/services/sync/staging.js +1 -2
  183. package/dist/services/sync/staging.js.map +1 -1
  184. package/dist/services/sync/structured-extractor.d.ts +8 -2
  185. package/dist/services/sync/structured-extractor.js +243 -35
  186. package/dist/services/sync/structured-extractor.js.map +1 -1
  187. package/dist/services/sync/types.d.ts +192 -23
  188. package/dist/services/sync/unstructured-extractor.d.ts +1 -3
  189. package/dist/services/sync/unstructured-extractor.js +2 -14
  190. package/dist/services/sync/unstructured-extractor.js.map +1 -1
  191. package/dist/utils/git.d.ts +24 -20
  192. package/dist/utils/git.js +99 -65
  193. package/dist/utils/git.js.map +1 -1
  194. package/dist/utils/preflight.d.ts +1 -15
  195. package/dist/utils/preflight.js +1 -35
  196. package/dist/utils/preflight.js.map +1 -1
  197. package/dist/web/_app/immutable/assets/0.CupILLQs.css +1 -0
  198. package/dist/web/_app/immutable/assets/3.CtJi4Cy9.css +1 -0
  199. package/dist/web/_app/immutable/assets/5.CydFyZSu.css +1 -0
  200. package/dist/web/_app/immutable/assets/6.kqeOo0OW.css +1 -0
  201. package/dist/web/_app/immutable/assets/7.CseIx7qQ.css +1 -0
  202. package/dist/web/_app/immutable/assets/{8.Sm6jB3a0.css → 8.BYpFDZHK.css} +1 -1
  203. package/dist/web/_app/immutable/assets/AppShell.Ch_ef9hJ.css +1 -0
  204. package/dist/web/_app/immutable/assets/ChatPanel.CP-_8txt.css +1 -0
  205. package/dist/web/_app/immutable/chunks/0oxpWEgM.js +1 -0
  206. package/dist/web/_app/immutable/chunks/B1y7Wy5O.js +18 -0
  207. package/dist/web/_app/immutable/chunks/B7eduG_j.js +64 -0
  208. package/dist/web/_app/immutable/chunks/BBLgaWN8.js +1 -0
  209. package/dist/web/_app/immutable/chunks/BCB5cYCz.js +2 -0
  210. package/dist/web/_app/immutable/chunks/{aosHekRC.js → BPUy9_sS.js} +1 -1
  211. package/dist/web/_app/immutable/chunks/BVBRzmeQ.js +7 -0
  212. package/dist/web/_app/immutable/chunks/{CUzqHQY_.js → BXuvR8Ks.js} +2 -1
  213. package/dist/web/_app/immutable/chunks/BeBar3OL.js +1 -0
  214. package/dist/web/_app/immutable/chunks/BuOTIbJu.js +1 -0
  215. package/dist/web/_app/immutable/chunks/CLFba8FK.js +5 -0
  216. package/dist/web/_app/immutable/chunks/CQCkXCml.js +1 -0
  217. package/dist/web/_app/immutable/chunks/CXuhHL4d.js +1 -0
  218. package/dist/web/_app/immutable/chunks/Cg9NOuOl.js +27 -0
  219. package/dist/web/_app/immutable/chunks/Cs5oz2oJ.js +5 -0
  220. package/dist/web/_app/immutable/chunks/Cs_ROD7H.js +2 -0
  221. package/dist/web/_app/immutable/chunks/D2aTbzFm.js +3 -0
  222. package/dist/web/_app/immutable/chunks/D4FXhiC2.js +1 -0
  223. package/dist/web/_app/immutable/chunks/D4VHRYeB.js +1 -0
  224. package/dist/web/_app/immutable/chunks/DCGSm8Hl.js +1 -0
  225. package/dist/web/_app/immutable/chunks/DP09rP34.js +2 -0
  226. package/dist/web/_app/immutable/chunks/DiP47fAp.js +1 -0
  227. package/dist/web/_app/immutable/chunks/DptGlK8O.js +1 -0
  228. package/dist/web/_app/immutable/chunks/O0fx2ss6.js +1 -0
  229. package/dist/web/_app/immutable/chunks/xBRYfpah.js +1 -0
  230. package/dist/web/_app/immutable/entry/app.FgnywZP_.js +2 -0
  231. package/dist/web/_app/immutable/entry/start.Bsa-zlPf.js +1 -0
  232. package/dist/web/_app/immutable/nodes/0.D3SW-LMc.js +10 -0
  233. package/dist/web/_app/immutable/nodes/1.y0c5TQTP.js +1 -0
  234. package/dist/web/_app/immutable/nodes/2.BQfSep9-.js +1 -0
  235. package/dist/web/_app/immutable/nodes/3.CC4Y-xMM.js +11 -0
  236. package/dist/web/_app/immutable/nodes/4.Dp0Z-oPW.js +4 -0
  237. package/dist/web/_app/immutable/nodes/5.gjZ03DON.js +2 -0
  238. package/dist/web/_app/immutable/nodes/6.dRNIwcJQ.js +1 -0
  239. package/dist/web/_app/immutable/nodes/7.I4Gjes3o.js +2 -0
  240. package/dist/web/_app/immutable/nodes/8.Dj14D7uH.js +1 -0
  241. package/dist/web/_app/version.json +1 -1
  242. package/dist/web/index.html +10 -12
  243. package/package.json +4 -2
  244. package/dist/web/_app/immutable/assets/0.CF0XhAap.css +0 -1
  245. package/dist/web/_app/immutable/assets/3.BJy7pVXi.css +0 -1
  246. package/dist/web/_app/immutable/assets/4.Ad16uh9o.css +0 -1
  247. package/dist/web/_app/immutable/assets/6.Bm2i7O0j.css +0 -1
  248. package/dist/web/_app/immutable/assets/7.Cn2DG-J6.css +0 -1
  249. package/dist/web/_app/immutable/assets/AppShell.CztjTuKY.css +0 -1
  250. package/dist/web/_app/immutable/assets/ChatPanel.RFD5GGYI.css +0 -1
  251. package/dist/web/_app/immutable/assets/editor.CPAf2SRV.css +0 -1
  252. package/dist/web/_app/immutable/chunks/4QY4j-jX.js +0 -1
  253. package/dist/web/_app/immutable/chunks/B3Kdf1r4.js +0 -6
  254. package/dist/web/_app/immutable/chunks/BIo3H1KR.js +0 -2
  255. package/dist/web/_app/immutable/chunks/BJLM1w2L.js +0 -23
  256. package/dist/web/_app/immutable/chunks/BLCwEMdm.js +0 -1
  257. package/dist/web/_app/immutable/chunks/BSYvCVJt.js +0 -1
  258. package/dist/web/_app/immutable/chunks/Ba5JX1o9.js +0 -1
  259. package/dist/web/_app/immutable/chunks/Bj34y868.js +0 -64
  260. package/dist/web/_app/immutable/chunks/BrWpHgBJ.js +0 -1
  261. package/dist/web/_app/immutable/chunks/C3g_lwol.js +0 -1
  262. package/dist/web/_app/immutable/chunks/CXnPm09s.js +0 -1
  263. package/dist/web/_app/immutable/chunks/ClOTom10.js +0 -1
  264. package/dist/web/_app/immutable/chunks/CtT4aw_G.js +0 -1
  265. package/dist/web/_app/immutable/chunks/Dh_H7Owr.js +0 -18
  266. package/dist/web/_app/immutable/chunks/DnlgZ_Tk.js +0 -5
  267. package/dist/web/_app/immutable/chunks/DtVH--hH.js +0 -6
  268. package/dist/web/_app/immutable/chunks/Dzd9kdLj.js +0 -2
  269. package/dist/web/_app/immutable/chunks/L91a_BGe.js +0 -1
  270. package/dist/web/_app/immutable/chunks/bHAllEMt.js +0 -1
  271. package/dist/web/_app/immutable/entry/app.CdrgaaFb.js +0 -2
  272. package/dist/web/_app/immutable/entry/start.t9LMjt48.js +0 -1
  273. package/dist/web/_app/immutable/nodes/0.P-Xfebn4.js +0 -2
  274. package/dist/web/_app/immutable/nodes/1.DiZlq1e6.js +0 -1
  275. package/dist/web/_app/immutable/nodes/2.ByIZ5J2p.js +0 -1
  276. package/dist/web/_app/immutable/nodes/3.D7JhktsZ.js +0 -1
  277. package/dist/web/_app/immutable/nodes/4.BtMeWbPx.js +0 -16
  278. package/dist/web/_app/immutable/nodes/5.CCYG1pbQ.js +0 -4
  279. package/dist/web/_app/immutable/nodes/6.CL_Ah04j.js +0 -2
  280. package/dist/web/_app/immutable/nodes/7.BMTaosAj.js +0 -1
  281. package/dist/web/_app/immutable/nodes/8.mrPg67cz.js +0 -1
  282. /package/dist/web/_app/immutable/assets/{5.BhKgiXd2.css → 4.BhKgiXd2.css} +0 -0
@@ -4,25 +4,21 @@
4
4
  * Connects the Studiograph agent to third-party MCP servers so the agent can
5
5
  * query external data sources on demand.
6
6
  *
7
- * Three transport types are supported:
7
+ * Only HTTP transport is supported (Streamable HTTP). Connectors are configured
8
+ * with a URL and optional headers — same format as Cursor/Claude Code MCP configs.
8
9
  *
9
- * http — Remote streamable-HTTP server (e.g. Linear at https://mcp.linear.app/mcp).
10
- * Requires `url` and `token` fields. Token can be a literal string or a
11
- * $ENV_VAR reference resolved at runtime.
10
+ * Two-layer config:
12
11
  *
13
- * oauth Remote streamable-HTTP server with OAuth (e.g. Figma at mcp.figma.com/mcp).
14
- * Requires `url` only. Uses dynamic client registration + PKCE — no client
15
- * secrets needed. Browser opens for user authorization on first connect.
12
+ * Workspace layer (.studiograph/connectors/<name>.json)
13
+ * Non-secret transport config committed to git. Secrets replaced with
14
+ * $ENV_VAR placeholders resolved at runtime.
16
15
  *
17
- * stdio Local stdio MCP server (e.g. granola-mcp spawned as a child process).
18
- * Requires `command` and optionally `args` / `env`. No token needed —
19
- * the server reads its own credentials from wherever it stores them.
20
- *
21
- * Connector configs are stored per-user at ~/.studiograph/connectors/<name>.json
22
- * (mode 0600 — never committed to git).
16
+ * Homedir layer (~/.studiograph/connectors/<name>.json)
17
+ * Full config with literal secrets (mode 0600, never committed).
18
+ * When present, homedir fields override workspace fields.
23
19
  *
24
20
  * Each connector's tools are injected into the agent with a namespaced prefix:
25
- * linear__search_issues, granola__list_meetings, etc.
21
+ * linear__search_issues, etc.
26
22
  *
27
23
  * Connection failures are non-fatal — the failing connector is skipped with a warning.
28
24
  */
@@ -31,63 +27,118 @@ import { join } from 'path';
31
27
  import { homedir } from 'os';
32
28
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
33
29
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
34
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
35
- import { auth } from '@modelcontextprotocol/sdk/client/auth.js';
36
- import { ConnectorOAuthProvider, waitForOAuthCallback } from './oauth-provider.js';
37
30
  export const CONNECTORS_DIR = join(homedir(), '.studiograph', 'connectors');
31
+ /** Pre-listed connectors — derived from integration registry. */
32
+ export { KNOWN_CONNECTORS } from '../integrations/registry.js';
38
33
  // ── ConnectorManager ──────────────────────────────────────────────────────────
39
34
  export class ConnectorManager {
40
35
  // ── config persistence ────────────────────────────────────────────────────
41
- static loadConfigs() {
42
- if (!existsSync(CONNECTORS_DIR))
43
- return [];
44
- let entries;
45
- try {
46
- entries = readdirSync(CONNECTORS_DIR);
47
- }
48
- catch {
49
- return [];
50
- }
51
- const configs = [];
52
- for (const entry of entries) {
53
- if (!entry.endsWith('.json'))
54
- continue;
55
- try {
56
- const raw = JSON.parse(readFileSync(join(CONNECTORS_DIR, entry), 'utf-8'));
57
- if (typeof raw.name !== 'string' || !raw.name) {
58
- console.warn(`[connectors] Skipping malformed config (missing name): ${entry}`);
59
- continue;
60
- }
61
- const resolved = ConnectorManager._resolveType(raw);
62
- if (!ConnectorManager._validate(resolved, entry))
63
- continue;
64
- configs.push(resolved);
65
- }
66
- catch {
67
- console.warn(`[connectors] Could not parse ${entry} — skipping`);
68
- }
36
+ /**
37
+ * Load all connector configs, merging workspace + homedir layers.
38
+ * When workspacePath is provided, reads .studiograph/connectors/ first,
39
+ * then overlays homedir configs (homedir fields win).
40
+ */
41
+ static loadConfigs(workspacePath) {
42
+ const workspaceConfigs = workspacePath
43
+ ? ConnectorManager._readDir(join(workspacePath, '.studiograph', 'connectors'))
44
+ : [];
45
+ const homedirConfigs = ConnectorManager._readDir(CONNECTORS_DIR);
46
+ // Merge: workspace as base, homedir overrides
47
+ const merged = new Map();
48
+ for (const c of workspaceConfigs)
49
+ merged.set(c.name, c);
50
+ for (const c of homedirConfigs) {
51
+ const base = merged.get(c.name);
52
+ merged.set(c.name, base ? ConnectorManager._merge(base, c) : c);
69
53
  }
70
- return configs;
54
+ return Array.from(merged.values());
71
55
  }
56
+ /**
57
+ * Load connector configs from workspace .studiograph/connectors/ only.
58
+ * Used by the config bundle export endpoint.
59
+ */
60
+ static loadWorkspaceConfigs(workspacePath) {
61
+ return ConnectorManager._readDir(join(workspacePath, '.studiograph', 'connectors'));
62
+ }
63
+ /** Save full config to homedir (mode 0600, never committed). */
72
64
  static saveConfig(config) {
73
65
  mkdirSync(CONNECTORS_DIR, { recursive: true });
74
66
  const path = join(CONNECTORS_DIR, `${config.name}.json`);
75
67
  writeFileSync(path, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
76
68
  }
77
- static removeConfig(name) {
78
- const path = join(CONNECTORS_DIR, `${name}.json`);
79
- if (!existsSync(path))
80
- return false;
81
- unlinkSync(path);
82
- return true;
69
+ /** Save sanitized config to workspace .studiograph/connectors/ (git-tracked). */
70
+ static saveWorkspaceConfig(config, workspacePath) {
71
+ const dir = join(workspacePath, '.studiograph', 'connectors');
72
+ mkdirSync(dir, { recursive: true });
73
+ const stripped = ConnectorManager.stripSecrets(config);
74
+ const path = join(dir, `${config.name}.json`);
75
+ writeFileSync(path, JSON.stringify(stripped, null, 2) + '\n');
83
76
  }
84
- // ── token resolution ──────────────────────────────────────────────────────
85
- /** Expands $ENV_VAR references; returns the literal string otherwise. */
86
- static resolveToken(token) {
87
- if (token.startsWith('$')) {
88
- return process.env[token.slice(1)] ?? token;
77
+ static removeConfig(name, workspacePath) {
78
+ let removed = false;
79
+ const hdPath = join(CONNECTORS_DIR, `${name}.json`);
80
+ if (existsSync(hdPath)) {
81
+ unlinkSync(hdPath);
82
+ removed = true;
83
+ }
84
+ if (workspacePath) {
85
+ const wsPath = join(workspacePath, '.studiograph', 'connectors', `${name}.json`);
86
+ if (existsSync(wsPath)) {
87
+ unlinkSync(wsPath);
88
+ removed = true;
89
+ }
90
+ }
91
+ return removed;
92
+ }
93
+ /** Load a single connector, merging workspace + homedir layers. */
94
+ static loadConfig(name, workspacePath) {
95
+ let wsConfig = null;
96
+ if (workspacePath) {
97
+ const wsPath = join(workspacePath, '.studiograph', 'connectors', `${name}.json`);
98
+ if (existsSync(wsPath)) {
99
+ try {
100
+ wsConfig = (JSON.parse(readFileSync(wsPath, 'utf-8')));
101
+ }
102
+ catch { /* skip */ }
103
+ }
104
+ }
105
+ let hdConfig = null;
106
+ const hdPath = join(CONNECTORS_DIR, `${name}.json`);
107
+ if (existsSync(hdPath)) {
108
+ try {
109
+ hdConfig = (JSON.parse(readFileSync(hdPath, 'utf-8')));
110
+ }
111
+ catch { /* skip */ }
89
112
  }
90
- return token;
113
+ if (!wsConfig && !hdConfig)
114
+ return null;
115
+ if (!wsConfig)
116
+ return hdConfig;
117
+ if (!hdConfig)
118
+ return wsConfig;
119
+ return ConnectorManager._merge(wsConfig, hdConfig);
120
+ }
121
+ /**
122
+ * Strip secret fields from a connector config, replacing them with $ENV_VAR
123
+ * placeholders. Safe to commit to git.
124
+ */
125
+ static stripSecrets(config) {
126
+ const stripped = { ...config };
127
+ // Strip Authorization header
128
+ if (stripped.headers) {
129
+ stripped.headers = { ...stripped.headers };
130
+ for (const [key, value] of Object.entries(stripped.headers)) {
131
+ if (key.toLowerCase() === 'authorization' && !value.startsWith('$')) {
132
+ stripped.headers[key] = `$${config.name.toUpperCase().replace(/-/g, '_')}_AUTH`;
133
+ }
134
+ }
135
+ }
136
+ return stripped;
137
+ }
138
+ /** Expands $ENV_VAR references; returns the literal string otherwise. */
139
+ static resolveEnvVar(value) {
140
+ // Replace $ENV_VAR references anywhere in the string
141
+ return value.replace(/\$([A-Z_][A-Z0-9_]*)/g, (match, name) => process.env[name] ?? match);
91
142
  }
92
143
  // ── tool building ─────────────────────────────────────────────────────────
93
144
  /**
@@ -114,80 +165,77 @@ export class ConnectorManager {
114
165
  console.warn(`[connectors] ${config.name} skipped — local server not running (${config.url})`);
115
166
  }
116
167
  else {
117
- console.warn(`[connectors] Failed to connect to "${config.name}" (${config.type === 'stdio' ? config.command : config.url}): ${msg}`);
168
+ console.warn(`[connectors] Failed to connect to "${config.name}" (${config.url}): ${msg}`);
118
169
  }
119
170
  }
120
171
  }
121
172
  return tools;
122
173
  }
123
174
  // ── private helpers ───────────────────────────────────────────────────────
124
- static _resolveType(config) {
125
- if (config.type)
126
- return config;
127
- // Infer type from fields present
128
- if (config.command)
129
- return { ...config, type: 'stdio' };
130
- return { ...config, type: 'http' };
131
- }
132
- static _validate(config, filename) {
133
- if (config.type === 'stdio') {
134
- if (!config.command) {
135
- console.warn(`[connectors] stdio connector "${config.name}" missing "command" — skipping`);
136
- return false;
137
- }
175
+ /** Read all valid connector configs from a directory. */
176
+ static _readDir(dir) {
177
+ if (!existsSync(dir))
178
+ return [];
179
+ let entries;
180
+ try {
181
+ entries = readdirSync(dir);
182
+ }
183
+ catch {
184
+ return [];
138
185
  }
139
- else if (config.type === 'oauth') {
140
- if (!config.url) {
141
- console.warn(`[connectors] oauth connector "${config.name}" missing "url" — skipping`);
142
- return false;
186
+ const configs = [];
187
+ for (const entry of entries) {
188
+ if (!entry.endsWith('.json'))
189
+ continue;
190
+ try {
191
+ const raw = JSON.parse(readFileSync(join(dir, entry), 'utf-8'));
192
+ if (typeof raw.name !== 'string' || !raw.name) {
193
+ console.warn(`[connectors] Skipping malformed config (missing name): ${entry}`);
194
+ continue;
195
+ }
196
+ const resolved = (raw);
197
+ if (!ConnectorManager._validate(resolved, entry))
198
+ continue;
199
+ configs.push(resolved);
200
+ }
201
+ catch {
202
+ console.warn(`[connectors] Could not parse ${entry} — skipping`);
143
203
  }
144
204
  }
145
- else {
146
- if (!config.url) {
147
- console.warn(`[connectors] http connector "${config.name}" missing "url"skipping`);
148
- return false;
205
+ return configs;
206
+ }
207
+ /** Merge two configs for the same connector overlay fields win over base. */
208
+ static _merge(base, overlay) {
209
+ const merged = { ...base };
210
+ for (const [key, value] of Object.entries(overlay)) {
211
+ if (value !== undefined && value !== null) {
212
+ if (key === 'headers' && merged.headers) {
213
+ merged.headers = { ...merged.headers, ...value };
214
+ }
215
+ else {
216
+ merged[key] = value;
217
+ }
149
218
  }
150
219
  }
220
+ return merged;
221
+ }
222
+ static _validate(config, filename) {
223
+ if (!config.url) {
224
+ console.warn(`[connectors] connector "${config.name}" missing "url" — skipping`);
225
+ return false;
226
+ }
151
227
  return true;
152
228
  }
153
229
  static async _buildConnectorTools(config) {
154
- let transport;
155
- if (config.type === 'stdio') {
156
- transport = new StdioClientTransport({
157
- command: config.command,
158
- args: config.args,
159
- env: config.env,
160
- stderr: 'ignore',
161
- });
162
- }
163
- else if (config.type === 'oauth') {
164
- // Pre-authorize before connecting.
165
- // The SDK only auto-triggers OAuth on 401, but some servers (Figma) return 403
166
- // for unauthenticated requests. We drive the flow manually to handle both.
167
- const authProvider = new ConnectorOAuthProvider(config.name);
168
- const result = await auth(authProvider, {
169
- serverUrl: config.url,
170
- });
171
- if (result === 'REDIRECT') {
172
- // Browser was opened — wait for the user to authorize
173
- console.log(`[connectors] ${config.name} requires authorization — waiting for browser...`);
174
- const code = await waitForOAuthCallback();
175
- // Exchange the authorization code for tokens
176
- await auth(authProvider, {
177
- serverUrl: config.url,
178
- authorizationCode: code,
179
- });
230
+ // Resolve any $ENV_VAR references in headers
231
+ const headers = {};
232
+ if (config.headers) {
233
+ for (const [key, value] of Object.entries(config.headers)) {
234
+ headers[key] = ConnectorManager.resolveEnvVar(value);
180
235
  }
181
- transport = new StreamableHTTPClientTransport(new URL(config.url), {
182
- authProvider,
183
- });
184
- }
185
- else {
186
- const requestInit = config.token
187
- ? { headers: { Authorization: `Bearer ${ConnectorManager.resolveToken(config.token)}` } }
188
- : {};
189
- transport = new StreamableHTTPClientTransport(new URL(config.url), { requestInit });
190
236
  }
237
+ const requestInit = Object.keys(headers).length > 0 ? { headers } : {};
238
+ const transport = new StreamableHTTPClientTransport(new URL(config.url), { requestInit });
191
239
  const client = new Client({ name: 'studiograph', version: '1.0.0' });
192
240
  await client.connect(transport);
193
241
  const { tools: remoteTools } = await client.listTools();
@@ -1 +1 @@
1
- {"version":3,"file":"connector-manager.js","sourceRoot":"","sources":["../../src/mcp/connector-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connector-manager.js","sourceRoot":"","sources":["../../src/mcp/connector-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Server-Side OAuth Provider for MCP Connectors
3
+ *
4
+ * Implements OAuthClientProvider backed by SQLite (per-user tokens)
5
+ * instead of local files. Used by the web UI OAuth flow:
6
+ *
7
+ * 1. User clicks "Connect" → POST /api/connectors/:name/oauth/authorize
8
+ * 2. Server calls auth(provider, { serverUrl }) → SDK discovers metadata,
9
+ * registers client, generates PKCE, calls redirectToAuthorization(url)
10
+ * 3. Provider stores the auth URL (doesn't open a browser)
11
+ * 4. Route returns { authorizationUrl } → frontend opens in new tab
12
+ * 5. User authorizes → callback to GET /api/oauth/callback/:name?code=...
13
+ * 6. Server calls auth(provider, { serverUrl, authorizationCode: code })
14
+ * 7. SDK exchanges code for tokens → provider.saveTokens() → SQLite
15
+ *
16
+ * Unlike ConnectorOAuthProvider (file-backed, opens browser), this works
17
+ * on remote deployments (Railway) and stores tokens per-user.
18
+ */
19
+ import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
20
+ import type { OAuthClientMetadata, OAuthClientInformationMixed, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
21
+ import type { AuthService } from '../services/auth-service.js';
22
+ import type { OAuthAppConfig } from '../integrations/types.js';
23
+ /** Encode userId + connectorName + origin into the OAuth state parameter.
24
+ * The origin is included so the auth proxy can redirect back to the correct instance. */
25
+ export declare function encodeOAuthState(userId: number, connectorName: string, origin?: string): string;
26
+ /** Decode the OAuth state parameter. */
27
+ export declare function decodeOAuthState(state: string): {
28
+ userId: number;
29
+ connectorName: string;
30
+ origin?: string;
31
+ } | null;
32
+ export declare class ServerOAuthProvider implements OAuthClientProvider {
33
+ private connectorName;
34
+ private userId;
35
+ private authService;
36
+ /** Set by redirectToAuthorization() — read by the route handler after auth() returns. */
37
+ authorizationUrl: string | null;
38
+ private redirectUri;
39
+ private serverUrl;
40
+ /** Pre-registered OAuth app config (client_id + optional secret). */
41
+ private oauthApp?;
42
+ constructor(connectorName: string, userId: number, authService: AuthService, serverUrl: string, oauthApp?: OAuthAppConfig);
43
+ get redirectUrl(): URL;
44
+ get clientMetadata(): OAuthClientMetadata;
45
+ state(): Promise<string>;
46
+ clientInformation(): Promise<OAuthClientInformationMixed | undefined>;
47
+ saveClientInformation(info: OAuthClientInformationMixed): Promise<void>;
48
+ tokens(): Promise<OAuthTokens | undefined>;
49
+ saveTokens(tokens: OAuthTokens): Promise<void>;
50
+ redirectToAuthorization(authorizationUrl: URL): Promise<void>;
51
+ saveCodeVerifier(codeVerifier: string): Promise<void>;
52
+ codeVerifier(): Promise<string>;
53
+ invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier'): Promise<void>;
54
+ private _load;
55
+ private _save;
56
+ }
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Server-Side OAuth Provider for MCP Connectors
3
+ *
4
+ * Implements OAuthClientProvider backed by SQLite (per-user tokens)
5
+ * instead of local files. Used by the web UI OAuth flow:
6
+ *
7
+ * 1. User clicks "Connect" → POST /api/connectors/:name/oauth/authorize
8
+ * 2. Server calls auth(provider, { serverUrl }) → SDK discovers metadata,
9
+ * registers client, generates PKCE, calls redirectToAuthorization(url)
10
+ * 3. Provider stores the auth URL (doesn't open a browser)
11
+ * 4. Route returns { authorizationUrl } → frontend opens in new tab
12
+ * 5. User authorizes → callback to GET /api/oauth/callback/:name?code=...
13
+ * 6. Server calls auth(provider, { serverUrl, authorizationCode: code })
14
+ * 7. SDK exchanges code for tokens → provider.saveTokens() → SQLite
15
+ *
16
+ * Unlike ConnectorOAuthProvider (file-backed, opens browser), this works
17
+ * on remote deployments (Railway) and stores tokens per-user.
18
+ */
19
+ /** Encode userId + connectorName + origin into the OAuth state parameter.
20
+ * The origin is included so the auth proxy can redirect back to the correct instance. */
21
+ export function encodeOAuthState(userId, connectorName, origin) {
22
+ const payload = { u: userId, c: connectorName };
23
+ if (origin)
24
+ payload.o = origin;
25
+ return Buffer.from(JSON.stringify(payload)).toString('base64url');
26
+ }
27
+ /** Decode the OAuth state parameter. */
28
+ export function decodeOAuthState(state) {
29
+ try {
30
+ const parsed = JSON.parse(Buffer.from(state, 'base64url').toString('utf-8'));
31
+ if (typeof parsed.u === 'number' && typeof parsed.c === 'string') {
32
+ return { userId: parsed.u, connectorName: parsed.c, origin: parsed.o };
33
+ }
34
+ return null;
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /** Auth proxy URL for pre-registered OAuth apps (single callback URL per provider). */
41
+ const AUTH_PROXY_URL = process.env.STUDIOGRAPH_AUTH_PROXY_URL ?? 'https://auth.studiograph.com';
42
+ export class ServerOAuthProvider {
43
+ connectorName;
44
+ userId;
45
+ authService;
46
+ /** Set by redirectToAuthorization() — read by the route handler after auth() returns. */
47
+ authorizationUrl = null;
48
+ redirectUri;
49
+ serverUrl;
50
+ /** Pre-registered OAuth app config (client_id + optional secret). */
51
+ oauthApp;
52
+ constructor(connectorName, userId, authService, serverUrl, oauthApp) {
53
+ this.connectorName = connectorName;
54
+ this.userId = userId;
55
+ this.authService = authService;
56
+ this.serverUrl = serverUrl.replace(/\/+$/, '');
57
+ this.oauthApp = oauthApp;
58
+ if (oauthApp) {
59
+ // Pre-registered app: callback goes through the auth proxy
60
+ this.redirectUri = `${AUTH_PROXY_URL}/callback/${encodeURIComponent(connectorName)}`;
61
+ }
62
+ else {
63
+ // Dynamic registration: callback goes directly to this instance
64
+ this.redirectUri = `${this.serverUrl}/api/oauth/callback/${encodeURIComponent(connectorName)}`;
65
+ }
66
+ }
67
+ get redirectUrl() {
68
+ return new URL(this.redirectUri);
69
+ }
70
+ get clientMetadata() {
71
+ return {
72
+ redirect_uris: [this.redirectUri],
73
+ client_name: 'Studiograph',
74
+ grant_types: ['authorization_code', 'refresh_token'],
75
+ response_types: ['code'],
76
+ token_endpoint_auth_method: this.oauthApp?.client_secret_env ? 'client_secret_post' : 'none',
77
+ };
78
+ }
79
+ async state() {
80
+ // Include origin URL so the auth proxy can redirect back to this instance
81
+ return encodeOAuthState(this.userId, this.connectorName, this.oauthApp ? this.serverUrl : undefined);
82
+ }
83
+ async clientInformation() {
84
+ // Pre-registered client info takes priority — skips dynamic registration
85
+ if (this.oauthApp) {
86
+ const info = { client_id: this.oauthApp.client_id };
87
+ if (this.oauthApp.client_secret_env) {
88
+ info.client_secret = process.env[this.oauthApp.client_secret_env] ?? '';
89
+ }
90
+ return info;
91
+ }
92
+ // Fall back to dynamically registered client info from storage
93
+ return this._load().clientInfo;
94
+ }
95
+ async saveClientInformation(info) {
96
+ const data = this._load();
97
+ data.clientInfo = info;
98
+ this._save(data);
99
+ }
100
+ async tokens() {
101
+ return this._load().tokens;
102
+ }
103
+ async saveTokens(tokens) {
104
+ const data = this._load();
105
+ data.tokens = tokens;
106
+ this._save(data);
107
+ }
108
+ async redirectToAuthorization(authorizationUrl) {
109
+ // Don't open a browser — store the URL for the route handler to return
110
+ this.authorizationUrl = authorizationUrl.toString();
111
+ }
112
+ async saveCodeVerifier(codeVerifier) {
113
+ const data = this._load();
114
+ data.codeVerifier = codeVerifier;
115
+ this._save(data);
116
+ }
117
+ async codeVerifier() {
118
+ return this._load().codeVerifier ?? '';
119
+ }
120
+ async invalidateCredentials(scope) {
121
+ const data = this._load();
122
+ if (scope === 'all' || scope === 'tokens')
123
+ data.tokens = undefined;
124
+ if (scope === 'all' || scope === 'client')
125
+ data.clientInfo = undefined;
126
+ if (scope === 'all' || scope === 'verifier')
127
+ data.codeVerifier = undefined;
128
+ this._save(data);
129
+ }
130
+ // ── storage helpers ──────────────────────────────────────────────────────
131
+ _load() {
132
+ return this.authService.getOAuthData(this.userId, this.connectorName) ?? {};
133
+ }
134
+ _save(data) {
135
+ this.authService.saveOAuthData(this.userId, this.connectorName, data);
136
+ }
137
+ }
138
+ //# sourceMappingURL=server-oauth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-oauth-provider.js","sourceRoot":"","sources":["../../src/mcp/server-oauth-provider.ts"],"names":[],"mappings":"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"}