@s2-dev/streamstore 0.3.14 → 0.4.2

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 (224) hide show
  1. package/README.md +115 -2
  2. package/bin/mcp-server.js +50283 -0
  3. package/bin/mcp-server.js.map +347 -0
  4. package/funcs/accountCreateBasin.d.ts +2 -1
  5. package/funcs/accountCreateBasin.d.ts.map +1 -1
  6. package/funcs/accountCreateBasin.js +11 -6
  7. package/funcs/accountCreateBasin.js.map +1 -1
  8. package/funcs/accountDeleteBasin.d.ts +2 -1
  9. package/funcs/accountDeleteBasin.d.ts.map +1 -1
  10. package/funcs/accountDeleteBasin.js +11 -6
  11. package/funcs/accountDeleteBasin.js.map +1 -1
  12. package/funcs/accountGetBasinConfig.d.ts +2 -1
  13. package/funcs/accountGetBasinConfig.d.ts.map +1 -1
  14. package/funcs/accountGetBasinConfig.js +11 -6
  15. package/funcs/accountGetBasinConfig.js.map +1 -1
  16. package/funcs/accountListBasins.d.ts +2 -1
  17. package/funcs/accountListBasins.d.ts.map +1 -1
  18. package/funcs/accountListBasins.js +19 -6
  19. package/funcs/accountListBasins.js.map +1 -1
  20. package/funcs/accountReconfigureBasin.d.ts +2 -1
  21. package/funcs/accountReconfigureBasin.d.ts.map +1 -1
  22. package/funcs/accountReconfigureBasin.js +11 -6
  23. package/funcs/accountReconfigureBasin.js.map +1 -1
  24. package/funcs/basinCreateStream.d.ts +2 -1
  25. package/funcs/basinCreateStream.d.ts.map +1 -1
  26. package/funcs/basinCreateStream.js +11 -6
  27. package/funcs/basinCreateStream.js.map +1 -1
  28. package/funcs/basinDeleteStream.d.ts +2 -1
  29. package/funcs/basinDeleteStream.d.ts.map +1 -1
  30. package/funcs/basinDeleteStream.js +11 -6
  31. package/funcs/basinDeleteStream.js.map +1 -1
  32. package/funcs/basinGetStreamConfig.d.ts +2 -1
  33. package/funcs/basinGetStreamConfig.d.ts.map +1 -1
  34. package/funcs/basinGetStreamConfig.js +11 -6
  35. package/funcs/basinGetStreamConfig.js.map +1 -1
  36. package/funcs/basinListStreams.d.ts +2 -1
  37. package/funcs/basinListStreams.d.ts.map +1 -1
  38. package/funcs/basinListStreams.js +19 -6
  39. package/funcs/basinListStreams.js.map +1 -1
  40. package/funcs/basinReconfigureStream.d.ts +2 -1
  41. package/funcs/basinReconfigureStream.d.ts.map +1 -1
  42. package/funcs/basinReconfigureStream.js +11 -6
  43. package/funcs/basinReconfigureStream.js.map +1 -1
  44. package/funcs/streamAppend.d.ts +2 -1
  45. package/funcs/streamAppend.d.ts.map +1 -1
  46. package/funcs/streamAppend.js +11 -6
  47. package/funcs/streamAppend.js.map +1 -1
  48. package/funcs/streamCheckTail.d.ts +2 -1
  49. package/funcs/streamCheckTail.d.ts.map +1 -1
  50. package/funcs/streamCheckTail.js +11 -6
  51. package/funcs/streamCheckTail.js.map +1 -1
  52. package/funcs/streamRead.d.ts +2 -1
  53. package/funcs/streamRead.d.ts.map +1 -1
  54. package/funcs/streamRead.js +11 -6
  55. package/funcs/streamRead.js.map +1 -1
  56. package/hooks/types.d.ts +1 -0
  57. package/hooks/types.d.ts.map +1 -1
  58. package/index.extras.d.ts +38 -15
  59. package/index.extras.d.ts.map +1 -1
  60. package/index.extras.js +91 -46
  61. package/index.extras.js.map +1 -1
  62. package/jsr.json +1 -1
  63. package/lib/config.d.ts +6 -6
  64. package/lib/config.d.ts.map +1 -1
  65. package/lib/config.js +3 -3
  66. package/lib/config.js.map +1 -1
  67. package/lib/files.js.map +1 -1
  68. package/lib/primitives.d.ts +3 -0
  69. package/lib/primitives.d.ts.map +1 -1
  70. package/lib/primitives.js +7 -0
  71. package/lib/primitives.js.map +1 -1
  72. package/lib/sdks.d.ts +1 -1
  73. package/lib/sdks.d.ts.map +1 -1
  74. package/lib/security.d.ts.map +1 -1
  75. package/lib/security.js.map +1 -1
  76. package/mcp-server/build.d.mts.map +1 -0
  77. package/mcp-server/build.mjs +14 -0
  78. package/mcp-server/build.mjs.map +1 -0
  79. package/mcp-server/cli/start/command.d.ts +2 -0
  80. package/mcp-server/cli/start/command.d.ts.map +1 -0
  81. package/mcp-server/cli/start/command.js +129 -0
  82. package/mcp-server/cli/start/command.js.map +1 -0
  83. package/mcp-server/cli/start/impl.d.ts +17 -0
  84. package/mcp-server/cli/start/impl.d.ts.map +1 -0
  85. package/mcp-server/cli/start/impl.js +102 -0
  86. package/mcp-server/cli/start/impl.js.map +1 -0
  87. package/mcp-server/cli.d.ts +6 -0
  88. package/mcp-server/cli.d.ts.map +1 -0
  89. package/mcp-server/cli.js +10 -0
  90. package/mcp-server/cli.js.map +1 -0
  91. package/mcp-server/console-logger.d.ts +7 -0
  92. package/mcp-server/console-logger.d.ts.map +1 -0
  93. package/mcp-server/console-logger.js +59 -0
  94. package/mcp-server/console-logger.js.map +1 -0
  95. package/mcp-server/mcp-server.d.ts +2 -0
  96. package/mcp-server/mcp-server.d.ts.map +1 -0
  97. package/mcp-server/mcp-server.js +29 -0
  98. package/mcp-server/mcp-server.js.map +1 -0
  99. package/mcp-server/resources.d.ts +27 -0
  100. package/mcp-server/resources.d.ts.map +1 -0
  101. package/mcp-server/resources.js +51 -0
  102. package/mcp-server/resources.js.map +1 -0
  103. package/mcp-server/scopes.d.ts +3 -0
  104. package/mcp-server/scopes.d.ts.map +1 -0
  105. package/mcp-server/scopes.js +11 -0
  106. package/mcp-server/scopes.js.map +1 -0
  107. package/mcp-server/server.d.ts +12 -0
  108. package/mcp-server/server.d.ts.map +1 -0
  109. package/mcp-server/server.js +51 -0
  110. package/mcp-server/server.js.map +1 -0
  111. package/mcp-server/shared.d.ts +7 -0
  112. package/mcp-server/shared.d.ts.map +1 -0
  113. package/mcp-server/shared.js +98 -0
  114. package/mcp-server/shared.js.map +1 -0
  115. package/mcp-server/tools/accountCreateBasin.d.ts +8 -0
  116. package/mcp-server/tools/accountCreateBasin.d.ts.map +1 -0
  117. package/mcp-server/tools/accountCreateBasin.js +63 -0
  118. package/mcp-server/tools/accountCreateBasin.js.map +1 -0
  119. package/mcp-server/tools/accountDeleteBasin.d.ts +8 -0
  120. package/mcp-server/tools/accountDeleteBasin.d.ts.map +1 -0
  121. package/mcp-server/tools/accountDeleteBasin.js +62 -0
  122. package/mcp-server/tools/accountDeleteBasin.js.map +1 -0
  123. package/mcp-server/tools/accountGetBasinConfig.d.ts +8 -0
  124. package/mcp-server/tools/accountGetBasinConfig.d.ts.map +1 -0
  125. package/mcp-server/tools/accountGetBasinConfig.js +63 -0
  126. package/mcp-server/tools/accountGetBasinConfig.js.map +1 -0
  127. package/mcp-server/tools/accountListBasins.d.ts +8 -0
  128. package/mcp-server/tools/accountListBasins.d.ts.map +1 -0
  129. package/mcp-server/tools/accountListBasins.js +63 -0
  130. package/mcp-server/tools/accountListBasins.js.map +1 -0
  131. package/mcp-server/tools/accountReconfigureBasin.d.ts +8 -0
  132. package/mcp-server/tools/accountReconfigureBasin.d.ts.map +1 -0
  133. package/mcp-server/tools/accountReconfigureBasin.js +63 -0
  134. package/mcp-server/tools/accountReconfigureBasin.js.map +1 -0
  135. package/mcp-server/tools/basinCreateStream.d.ts +8 -0
  136. package/mcp-server/tools/basinCreateStream.d.ts.map +1 -0
  137. package/mcp-server/tools/basinCreateStream.js +63 -0
  138. package/mcp-server/tools/basinCreateStream.js.map +1 -0
  139. package/mcp-server/tools/basinDeleteStream.d.ts +8 -0
  140. package/mcp-server/tools/basinDeleteStream.d.ts.map +1 -0
  141. package/mcp-server/tools/basinDeleteStream.js +62 -0
  142. package/mcp-server/tools/basinDeleteStream.js.map +1 -0
  143. package/mcp-server/tools/basinGetStreamConfig.d.ts +8 -0
  144. package/mcp-server/tools/basinGetStreamConfig.d.ts.map +1 -0
  145. package/mcp-server/tools/basinGetStreamConfig.js +63 -0
  146. package/mcp-server/tools/basinGetStreamConfig.js.map +1 -0
  147. package/mcp-server/tools/basinListStreams.d.ts +8 -0
  148. package/mcp-server/tools/basinListStreams.d.ts.map +1 -0
  149. package/mcp-server/tools/basinListStreams.js +63 -0
  150. package/mcp-server/tools/basinListStreams.js.map +1 -0
  151. package/mcp-server/tools/basinReconfigureStream.d.ts +8 -0
  152. package/mcp-server/tools/basinReconfigureStream.d.ts.map +1 -0
  153. package/mcp-server/tools/basinReconfigureStream.js +63 -0
  154. package/mcp-server/tools/basinReconfigureStream.js.map +1 -0
  155. package/mcp-server/tools/streamAppend.d.ts +8 -0
  156. package/mcp-server/tools/streamAppend.d.ts.map +1 -0
  157. package/mcp-server/tools/streamAppend.js +65 -0
  158. package/mcp-server/tools/streamAppend.js.map +1 -0
  159. package/mcp-server/tools/streamCheckTail.d.ts +8 -0
  160. package/mcp-server/tools/streamCheckTail.d.ts.map +1 -0
  161. package/mcp-server/tools/streamCheckTail.js +65 -0
  162. package/mcp-server/tools/streamCheckTail.js.map +1 -0
  163. package/mcp-server/tools/streamRead.d.ts +8 -0
  164. package/mcp-server/tools/streamRead.d.ts.map +1 -0
  165. package/mcp-server/tools/streamRead.js +65 -0
  166. package/mcp-server/tools/streamRead.js.map +1 -0
  167. package/mcp-server/tools.d.ts +25 -0
  168. package/mcp-server/tools.d.ts.map +1 -0
  169. package/mcp-server/tools.js +74 -0
  170. package/mcp-server/tools.js.map +1 -0
  171. package/models/components/endpoints.d.ts +67 -0
  172. package/models/components/endpoints.d.ts.map +1 -0
  173. package/models/components/endpoints.js +126 -0
  174. package/models/components/endpoints.js.map +1 -0
  175. package/package.json +16 -2
  176. package/src/funcs/accountCreateBasin.ts +38 -7
  177. package/src/funcs/accountDeleteBasin.ts +39 -7
  178. package/src/funcs/accountGetBasinConfig.ts +38 -7
  179. package/src/funcs/accountListBasins.ts +49 -7
  180. package/src/funcs/accountReconfigureBasin.ts +38 -7
  181. package/src/funcs/basinCreateStream.ts +38 -7
  182. package/src/funcs/basinDeleteStream.ts +39 -7
  183. package/src/funcs/basinGetStreamConfig.ts +38 -7
  184. package/src/funcs/basinListStreams.ts +49 -7
  185. package/src/funcs/basinReconfigureStream.ts +38 -7
  186. package/src/funcs/streamAppend.ts +38 -7
  187. package/src/funcs/streamCheckTail.ts +38 -7
  188. package/src/funcs/streamRead.ts +38 -7
  189. package/src/hooks/types.ts +1 -0
  190. package/src/index.extras.ts +113 -49
  191. package/src/lib/config.ts +6 -7
  192. package/src/lib/files.ts +1 -1
  193. package/src/lib/primitives.ts +14 -0
  194. package/src/lib/sdks.ts +1 -1
  195. package/src/lib/security.ts +0 -1
  196. package/src/mcp-server/cli/start/command.ts +98 -0
  197. package/src/mcp-server/cli/start/impl.ts +131 -0
  198. package/src/mcp-server/cli.ts +13 -0
  199. package/src/mcp-server/console-logger.ts +71 -0
  200. package/src/mcp-server/mcp-server.ts +26 -0
  201. package/src/mcp-server/resources.ts +96 -0
  202. package/src/mcp-server/scopes.ts +10 -0
  203. package/src/mcp-server/server.ts +60 -0
  204. package/src/mcp-server/shared.ts +75 -0
  205. package/src/mcp-server/tools/accountCreateBasin.ts +36 -0
  206. package/src/mcp-server/tools/accountDeleteBasin.ts +34 -0
  207. package/src/mcp-server/tools/accountGetBasinConfig.ts +36 -0
  208. package/src/mcp-server/tools/accountListBasins.ts +36 -0
  209. package/src/mcp-server/tools/accountReconfigureBasin.ts +36 -0
  210. package/src/mcp-server/tools/basinCreateStream.ts +36 -0
  211. package/src/mcp-server/tools/basinDeleteStream.ts +34 -0
  212. package/src/mcp-server/tools/basinGetStreamConfig.ts +36 -0
  213. package/src/mcp-server/tools/basinListStreams.ts +36 -0
  214. package/src/mcp-server/tools/basinReconfigureStream.ts +36 -0
  215. package/src/mcp-server/tools/streamAppend.ts +38 -0
  216. package/src/mcp-server/tools/streamCheckTail.ts +38 -0
  217. package/src/mcp-server/tools/streamRead.ts +38 -0
  218. package/src/mcp-server/tools.ts +116 -0
  219. package/src/models/components/endpoints.ts +159 -0
  220. package/src/types/async.ts +68 -0
  221. package/types/async.d.ts +23 -0
  222. package/types/async.d.ts.map +1 -0
  223. package/types/async.js +44 -0
  224. package/types/async.js.map +1 -0
@@ -75,8 +75,29 @@ export type S2ClientConfig = {
75
75
  httpClient?: HTTPClient;
76
76
  };
77
77
 
78
+ /**
79
+ * Override the client level configuration for a specific operation.
80
+ *
81
+ * @remarks
82
+ * Only `authToken` can be overridden for now.
83
+ */
84
+ export type S2OperationConfig = {
85
+ authToken?: string;
86
+ };
87
+
88
+ /**
89
+ * Retry policy for appends.
90
+ */
78
91
  export enum AppendRetryPolicy {
92
+ /**
93
+ * Retry all eligible failures encountered during an append.
94
+ * This could result in append batches being duplicated on the stream.
95
+ */
79
96
  All,
97
+ /**
98
+ * Retry only failures with no side effects.
99
+ * Will not attempt to retry failures where it cannot be concluded whether an append may become durable, in order to prevent duplicates.
100
+ */
80
101
  NoSideEffects,
81
102
  }
82
103
 
@@ -92,12 +113,9 @@ const defaultS2ClientConfig: S2ClientConfig = {
92
113
 
93
114
  export class S2Client {
94
115
  private config: S2ClientConfig;
95
- private _account?: S2Account;
116
+ private _account?: S2Account;
96
117
 
97
118
  get account(): S2Account {
98
- // this.httpClient.addHook("beforeRequest", (request) => {
99
- // if (this.config.userAgent) request.headers.set("User-Agent", this.config.userAgent);
100
- // });
101
119
  return (this._account ??= new S2Account(this.config));
102
120
  }
103
121
 
@@ -117,12 +135,11 @@ class S2Account {
117
135
  private readonly accountURLSuffx = "/v1alpha";
118
136
 
119
137
  constructor(config: S2ClientConfig) {
120
- if (config.userAgent !== undefined) {
121
- config.httpClient?.addHook("beforeRequest", (request) => {
138
+ config.httpClient?.addHook("beforeRequest", (request) => {
139
+ if (config.userAgent !== undefined) {
122
140
  request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
123
- console.log(request)
124
- });
125
- }
141
+ }
142
+ });
126
143
  this._account = new InnerAccount({
127
144
  ...(config.authToken !== undefined && { bearerAuth: config.authToken }),
128
145
  ...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
@@ -131,57 +148,67 @@ class S2Account {
131
148
  this.config = config;
132
149
  }
133
150
 
134
- get URL(): string | undefined {
135
- if (!this.config.endpoints) return undefined;
136
- return `https://${ClientKind.toAuthority({ kind: "Account" }, this.config.endpoints)}${this.accountURLSuffx}`;
137
- }
151
+ get URL(): string {
152
+ return `https://${ClientKind.toAuthority({ kind: "Account" }, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.accountURLSuffx}`;
153
+ }
138
154
 
139
155
  basin(basinName: string): S2Basin {
140
156
  return new S2Basin(basinName, this.config);
141
157
  }
142
158
 
159
+ private overrideConfig(config?: S2OperationConfig) {
160
+ this.config.httpClient?.addHook("beforeRequest", (request) => {
161
+ if (config?.authToken !== undefined) {
162
+ request.headers.set("Authorization", `Bearer ${config.authToken}`);
163
+ }
164
+ });
165
+ }
166
+
143
167
  async listBasins(
144
- request?: ListBasinsRequest
168
+ request?: ListBasinsRequest,
169
+ opConfig?: S2OperationConfig,
145
170
  ): Promise<PageIterator<ListBasinsResponse, { cursor: string }>> {
146
- const url = this.URL;
171
+ this.overrideConfig(opConfig);
147
172
  return retryWithExponentialBackoff(
148
- () => this._account.listBasins(request ?? {}, url ? { serverURL: url } : {}),
173
+ () => this._account.listBasins(request ?? {}, {
174
+ serverURL: this.URL,
175
+ }),
149
176
  this.config.maxRetries,
150
177
  this.config.initialBackoffMs,
151
178
  this.config.maxBackoffMs
152
179
  );
153
180
  }
154
181
 
155
- async getBasinConfig(basin: string): Promise<BasinConfig | undefined> {
182
+ async getBasinConfig(basin: string, opConfig?: S2OperationConfig): Promise<BasinConfig | undefined> {
183
+ this.overrideConfig(opConfig);
156
184
  const _request: GetBasinConfigRequest = { basin };
157
- const url = this.URL;
158
185
  return retryWithExponentialBackoff(
159
- () => this._account.getBasinConfig(_request, url ? { serverURL: url } : {}),
186
+ () => this._account.getBasinConfig(_request, { serverURL: this.URL }),
160
187
  this.config.maxRetries,
161
188
  this.config.initialBackoffMs,
162
189
  this.config.maxBackoffMs
163
190
  );
164
191
  }
165
192
 
166
- async createBasin(basin: string, request?: CreateBasinRequest): Promise<BasinInfo | undefined> {
193
+ async createBasin(basin: string, request?: CreateBasinRequest, opConfig?: S2OperationConfig): Promise<BasinInfo | undefined> {
194
+ this.overrideConfig(opConfig);
167
195
  const _request: CreateBasinRequestInner = {
168
196
  basin,
169
197
  s2RequestToken: genS2RequestToken(),
170
198
  createBasinRequest: request ?? {},
171
199
  };
172
- const url = this.URL;
173
200
  return retryWithExponentialBackoff(
174
- () => this._account.createBasin(_request, url ? { serverURL: url } : {}),
201
+ () => this._account.createBasin(_request, { serverURL: this.URL }),
175
202
  this.config.maxRetries,
176
203
  this.config.initialBackoffMs,
177
204
  this.config.maxBackoffMs
178
205
  );
179
206
  }
180
207
 
181
- async deleteBasin(basin: string, if_exists?: boolean): Promise<void> {
182
- const url = this.URL;
208
+ async deleteBasin(basin: string, if_exists?: boolean, opConfig?: S2OperationConfig): Promise<void> {
209
+ this.overrideConfig(opConfig);
183
210
  const response = await retryWithExponentialBackoff(
184
- () => accountDeleteBasin(this._account, { basin }, url ? { serverURL: url } : {}),
211
+ () => accountDeleteBasin(this._account, { basin }, { serverURL: this.URL }),
185
212
  this.config.maxRetries,
186
213
  this.config.initialBackoffMs,
187
214
  this.config.maxBackoffMs
@@ -191,11 +218,11 @@ class S2Account {
191
218
  return;
192
219
  }
193
220
 
194
- async reconfigureBasin(basin: string, config: BasinConfig): Promise<BasinConfig | undefined> {
195
- const url = this.URL;
221
+ async reconfigureBasin(basin: string, config: BasinConfig, opConfig?: S2OperationConfig): Promise<BasinConfig | undefined> {
222
+ this.overrideConfig(opConfig);
196
223
  const _request: ReconfigureBasinRequest = { basin, basinConfig: config };
197
224
  return retryWithExponentialBackoff(
198
- () => this._account.reconfigureBasin(_request, url ? { serverURL: url } : {}),
225
+ () => this._account.reconfigureBasin(_request, { serverURL: this.URL }),
199
226
  this.config.maxRetries,
200
227
  this.config.initialBackoffMs,
201
228
  this.config.maxBackoffMs
@@ -209,21 +236,25 @@ class S2Basin {
209
236
  private basinName: string;
210
237
  private config: S2ClientConfig;
211
238
  private clientKind: ClientKind;
212
- private readonly basinURLSuffx = "/v1alpha";
239
+ private readonly basinURLSuffx = "/v1alpha";
213
240
 
214
241
  private get URL(): string {
215
242
  return `https://${ClientKind.toAuthority(this.clientKind, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.basinURLSuffx}`;
216
243
  }
217
244
 
218
245
  constructor(basinName: string, config: S2ClientConfig) {
219
- if (config.userAgent !== undefined) {
220
- config.httpClient?.addHook("beforeRequest", (request) => {
246
+ config.httpClient?.addHook("beforeRequest", (request) => {
247
+ if (config.userAgent !== undefined) {
221
248
  request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
222
- });
223
- }
249
+ }
250
+ if (config.endpoints?.basin?.kind === "Direct") {
251
+ request.headers.set("s2-basin", basinName);
252
+ }
253
+ });
224
254
  this._basin = new InnerBasin({
225
255
  ...(config.authToken !== undefined && { bearerAuth: config.authToken }),
226
- ...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
256
+ ...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
257
+ ...(config.httpClient !== undefined && { httpClient: config.httpClient }),
227
258
  });
228
259
  this.config = config;
229
260
  this.clientKind = { kind: "Basin" as const, basin: basinName };
@@ -234,18 +265,32 @@ class S2Basin {
234
265
  return (this._stream ??= new Stream(this.basinName, streamName, this.config));
235
266
  }
236
267
 
268
+ private overrideConfig(config?: S2OperationConfig) {
269
+ this.config.httpClient?.addHook("beforeRequest", (request) => {
270
+ if (config?.authToken !== undefined) {
271
+ request.headers.set("Authorization", `Bearer ${config.authToken}`);
272
+ }
273
+ });
274
+ }
275
+
237
276
  async listStreams(
238
- request: ListStreamsRequest
277
+ request?: ListStreamsRequest,
278
+ opConfig?: S2OperationConfig,
239
279
  ): Promise<PageIterator<ListStreamsResponse, { cursor: string }>> {
280
+ this.overrideConfig(opConfig);
240
281
  return retryWithExponentialBackoff(
241
- () => this._basin.listStreams(request, { serverURL: this.URL }),
282
+ () => this._basin.listStreams(request ?? {}, { serverURL: this.URL }),
242
283
  this.config.maxRetries,
243
284
  this.config.initialBackoffMs,
244
285
  this.config.maxBackoffMs
245
286
  );
246
287
  }
247
288
 
248
- async getStreamConfig(stream: string): Promise<StreamConfig | undefined> {
289
+ async getStreamConfig(
290
+ stream: string,
291
+ opConfig?: S2OperationConfig
292
+ ): Promise<StreamConfig | undefined> {
293
+ this.overrideConfig(opConfig);
249
294
  return retryWithExponentialBackoff(
250
295
  () => this._basin.getStreamConfig({ stream }, { serverURL: this.URL }),
251
296
  this.config.maxRetries,
@@ -254,7 +299,8 @@ class S2Basin {
254
299
  );
255
300
  }
256
301
 
257
- async createStream(stream: string, request?: CreateStreamRequest): Promise<StreamInfo | undefined> {
302
+ async createStream(stream: string, request?: CreateStreamRequest, opConfig?: S2OperationConfig): Promise<StreamInfo | undefined> {
303
+ this.overrideConfig(opConfig);
258
304
  const _request: CreateStreamRequestInner = {
259
305
  stream,
260
306
  s2RequestToken: genS2RequestToken(),
@@ -268,7 +314,8 @@ class S2Basin {
268
314
  );
269
315
  }
270
316
 
271
- async deleteStream(stream: string, if_exists?: boolean): Promise<void | undefined> {
317
+ async deleteStream(stream: string, if_exists?: boolean, opConfig?: S2OperationConfig): Promise<void | undefined> {
318
+ this.overrideConfig(opConfig);
272
319
  const response = await retryWithExponentialBackoff(
273
320
  () => basinDeleteStream(this._basin, { stream }, { serverURL: this.URL }),
274
321
  this.config.maxRetries,
@@ -280,7 +327,8 @@ class S2Basin {
280
327
  return;
281
328
  }
282
329
 
283
- async reconfigureStream(stream: string, config: StreamConfig): Promise<StreamConfig> {
330
+ async reconfigureStream(stream: string, config: StreamConfig, opConfig?: S2OperationConfig): Promise<StreamConfig> {
331
+ this.overrideConfig(opConfig);
284
332
  return retryWithExponentialBackoff(
285
333
  () => this._basin.reconfigureStream({ stream, streamConfig: config }, { serverURL: this.URL }),
286
334
  this.config.maxRetries,
@@ -301,28 +349,42 @@ class Stream {
301
349
  return `https://${ClientKind.toAuthority(this.clientKind, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.basinURLSuffx}`;
302
350
  }
303
351
 
352
+ private overrideConfig(config?: S2OperationConfig) {
353
+ this.config.httpClient?.addHook("beforeRequest", (request) => {
354
+ if (config?.authToken !== undefined) {
355
+ request.headers.set("Authorization", `Bearer ${config.authToken}`);
356
+ }
357
+ });
358
+ }
359
+
304
360
  constructor(basinName: string, streamName: string, config: S2ClientConfig) {
305
361
  this.config = config;
306
362
  this.clientKind = { kind: "Basin" as const, basin: basinName };
307
363
  this.streamName = streamName;
308
- if (config.userAgent !== undefined) {
309
- config.httpClient?.addHook("beforeRequest", (request) => {
364
+ config.httpClient?.addHook("beforeRequest", (request) => {
365
+ if (config.userAgent !== undefined) {
310
366
  request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
311
- });
312
- }
367
+ }
368
+ if (config.endpoints?.basin?.kind === "Direct") {
369
+ request.headers.set("s2-basin", basinName);
370
+ }
371
+ });
313
372
  this._stream = new InnerStream({
314
373
  ...(config.authToken !== undefined && { bearerAuth: config.authToken }),
315
- ...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
374
+ ...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
375
+ ...(config.httpClient !== undefined && { httpClient: config.httpClient })
316
376
  });
317
377
  }
318
378
 
319
- async checkTail(): Promise<CheckTailResponse> {
379
+ async checkTail(opConfig?: S2OperationConfig): Promise<CheckTailResponse> {
380
+ this.overrideConfig(opConfig);
320
381
  return (
321
382
  await this._stream.checkTail({ stream: this.streamName }, { serverURL: this.basinURL })
322
383
  );
323
384
  }
324
385
 
325
- async append(request: AppendRequest): Promise<AppendOutput> {
386
+ async append(request: AppendRequest, opConfig?: S2OperationConfig): Promise<AppendOutput> {
387
+ this.overrideConfig(opConfig);
326
388
  switch (this.config.appedRetryPolicy) {
327
389
  case AppendRetryPolicy.All:
328
390
  case undefined:
@@ -343,13 +405,15 @@ class Stream {
343
405
  }
344
406
  }
345
407
 
346
- async read(request: ReadRequest): Promise<Output> {
408
+ async read(request: ReadRequest, opConfig?: S2OperationConfig): Promise<Output> {
409
+ this.overrideConfig(opConfig);
347
410
  return (
348
411
  await this._stream.read({ ...request, stream: this.streamName }, { serverURL: this.basinURL }) as Output
349
412
  );
350
413
  }
351
414
 
352
- async *readStream(request: ReadRequest): AsyncGenerator<ReadResponse, void, undefined> {
415
+ async *readStream(request: ReadRequest, opConfig?: S2OperationConfig): AsyncGenerator<ReadResponse, void, undefined> {
416
+ this.overrideConfig(opConfig);
353
417
  let currentRequest: ReadRequest = { ...request };
354
418
  let initialBackoffMs = this.config.initialBackoffMs ?? 100;
355
419
  const maxBackoffMs = 5000;
package/src/lib/config.ts CHANGED
@@ -15,17 +15,17 @@ export const ServerList = [
15
15
  ] as const;
16
16
 
17
17
  export type SDKOptions = {
18
- bearerAuth?: string | (() => Promise<string>);
18
+ bearerAuth?: string | (() => Promise<string>) | undefined;
19
19
 
20
20
  httpClient?: HTTPClient;
21
21
  /**
22
22
  * Allows overriding the default server used by the SDK
23
23
  */
24
- serverIdx?: number;
24
+ serverIdx?: number | undefined;
25
25
  /**
26
26
  * Allows overriding the default server URL used by the SDK
27
27
  */
28
- serverURL?: string;
28
+ serverURL?: string | undefined;
29
29
  /**
30
30
  * Allows overriding the default retry config used by the SDK
31
31
  */
@@ -54,8 +54,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
54
54
  export const SDK_METADATA = {
55
55
  language: "typescript",
56
56
  openapiDocVersion: "1.0.0",
57
- sdkVersion: "0.3.14",
58
- genVersion: "2.506.0",
59
- userAgent:
60
- "speakeasy-sdk/typescript 0.3.14 2.506.0 1.0.0 @s2-dev/streamstore",
57
+ sdkVersion: "0.4.2",
58
+ genVersion: "2.529.2",
59
+ userAgent: "speakeasy-sdk/typescript 0.4.2 2.529.2 1.0.0 @s2-dev/streamstore",
61
60
  } as const;
package/src/lib/files.ts CHANGED
@@ -36,5 +36,5 @@ export async function readableStreamToArrayBuffer(
36
36
  offset += chunk.length;
37
37
  }
38
38
 
39
- return concatenatedChunks.buffer;
39
+ return concatenatedChunks.buffer as ArrayBuffer;
40
40
  }
@@ -134,3 +134,17 @@ export function compactMap<T>(
134
134
 
135
135
  return out;
136
136
  }
137
+
138
+ export function allRequired<V extends Record<string, unknown>>(
139
+ v: V,
140
+ ):
141
+ | {
142
+ [K in keyof V]: NonNullable<V[K]>;
143
+ }
144
+ | undefined {
145
+ if (Object.values(v).every((x) => x == null)) {
146
+ return void 0;
147
+ }
148
+
149
+ return v as ReturnType<typeof allRequired<V>>;
150
+ }
package/src/lib/sdks.ts CHANGED
@@ -79,7 +79,7 @@ export class ClientSDK {
79
79
  readonly #httpClient: HTTPClient;
80
80
  readonly #hooks: SDKHooks;
81
81
  readonly #logger?: Logger | undefined;
82
- protected readonly _baseURL: URL | null;
82
+ public readonly _baseURL: URL | null;
83
83
  public readonly _options: SDKOptions & { hooks?: SDKHooks };
84
84
 
85
85
  constructor(options: SDKOptions = {}) {
@@ -4,7 +4,6 @@
4
4
 
5
5
  import * as components from "../models/components/index.js";
6
6
  import { env } from "./env.js";
7
-
8
7
  type OAuth2PasswordFlow = {
9
8
  username: string;
10
9
  password?: string | undefined;
@@ -0,0 +1,98 @@
1
+ /*
2
+ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
+ */
4
+
5
+ import { buildCommand } from "@stricli/core";
6
+ import { numberParser } from "@stricli/core";
7
+ import * as z from "zod";
8
+ import { consoleLoggerLevels } from "../../console-logger.js";
9
+ import { mcpScopes } from "../../scopes.js";
10
+
11
+ export const startCommand = buildCommand({
12
+ loader: async () => {
13
+ const { main } = await import("./impl.js");
14
+ return main;
15
+ },
16
+ parameters: {
17
+ flags: {
18
+ transport: {
19
+ kind: "enum",
20
+ brief: "The transport to use for communicating with the server",
21
+ default: "stdio",
22
+ values: ["stdio", "sse"],
23
+ },
24
+ port: {
25
+ kind: "parsed",
26
+ brief: "The port to use when the SSE transport is enabled",
27
+ default: "2718",
28
+ parse: (val: string) =>
29
+ z.coerce.number().int().gte(0).lt(65536).parse(val),
30
+ },
31
+ ...(mcpScopes.length
32
+ ? {
33
+ scope: {
34
+ kind: "enum",
35
+ brief:
36
+ "Mount tools/resources that match given scope (repeatable flag)",
37
+ values: mcpScopes,
38
+ variadic: true,
39
+ optional: true,
40
+ },
41
+ }
42
+ : {}),
43
+ "bearer-auth": {
44
+ kind: "parsed",
45
+ brief: "Sets the bearerAuth auth field for the API",
46
+ optional: true,
47
+ parse: (value) => {
48
+ return z.string().parse(value);
49
+ },
50
+ },
51
+ "server-url": {
52
+ kind: "parsed",
53
+ brief: "Overrides the default server URL used by the SDK",
54
+ optional: true,
55
+ parse: (value) => new URL(value).toString(),
56
+ },
57
+ "server-index": {
58
+ kind: "parsed",
59
+ brief: "Selects a predefined server used by the SDK",
60
+ optional: true,
61
+ parse: numberParser,
62
+ },
63
+ "log-level": {
64
+ kind: "enum",
65
+ brief: "The log level to use for the server",
66
+ default: "info",
67
+ values: consoleLoggerLevels,
68
+ },
69
+ env: {
70
+ kind: "parsed",
71
+ brief: "Environment variables made available to the server",
72
+ optional: true,
73
+ variadic: true,
74
+ parse: (val: string) => {
75
+ const sepIdx = val.indexOf("=");
76
+ if (sepIdx === -1) {
77
+ throw new Error("Invalid environment variable format");
78
+ }
79
+
80
+ const key = val.slice(0, sepIdx);
81
+ const value = val.slice(sepIdx + 1);
82
+
83
+ return [
84
+ z.string().nonempty({
85
+ message: "Environment variable key must be a non-empty string",
86
+ }).parse(key),
87
+ z.string().nonempty({
88
+ message: "Environment variable value must be a non-empty string",
89
+ }).parse(value),
90
+ ] satisfies [string, string];
91
+ },
92
+ },
93
+ },
94
+ },
95
+ docs: {
96
+ brief: "Run the Model Context Protocol server",
97
+ },
98
+ });
@@ -0,0 +1,131 @@
1
+ /*
2
+ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
+ */
4
+
5
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import express from "express";
8
+ import { SDKOptions } from "../../../lib/config.js";
9
+ import { LocalContext } from "../../cli.js";
10
+ import {
11
+ ConsoleLoggerLevel,
12
+ createConsoleLogger,
13
+ } from "../../console-logger.js";
14
+ import { MCPScope } from "../../scopes.js";
15
+ import { createMCPServer } from "../../server.js";
16
+
17
+ interface StartCommandFlags {
18
+ readonly transport: "stdio" | "sse";
19
+ readonly port: number;
20
+ readonly scope?: MCPScope[];
21
+ readonly "bearer-auth"?: string | undefined;
22
+ readonly "server-url"?: string;
23
+ readonly "server-index"?: SDKOptions["serverIdx"];
24
+ readonly "log-level": ConsoleLoggerLevel;
25
+ readonly env?: [string, string][];
26
+ }
27
+
28
+ export async function main(this: LocalContext, flags: StartCommandFlags) {
29
+ flags.env?.forEach(([key, value]) => {
30
+ process.env[key] = value;
31
+ });
32
+
33
+ switch (flags.transport) {
34
+ case "stdio":
35
+ await startStdio(flags);
36
+ break;
37
+ case "sse":
38
+ await startSSE(flags);
39
+ break;
40
+ default:
41
+ throw new Error(`Invalid transport: ${flags.transport}`);
42
+ }
43
+ }
44
+
45
+ async function startStdio(flags: StartCommandFlags) {
46
+ const logger = createConsoleLogger(flags["log-level"]);
47
+ const transport = new StdioServerTransport();
48
+ const server = createMCPServer({
49
+ logger,
50
+ scopes: flags.scope,
51
+ ...{ bearerAuth: flags["bearer-auth"] },
52
+ serverURL: flags["server-url"],
53
+ serverIdx: flags["server-index"],
54
+ });
55
+ await server.connect(transport);
56
+
57
+ const abort = async () => {
58
+ await server.close();
59
+ process.exit(0);
60
+ };
61
+ process.on("SIGTERM", abort);
62
+ process.on("SIGINT", abort);
63
+ }
64
+
65
+ async function startSSE(flags: StartCommandFlags) {
66
+ const logger = createConsoleLogger(flags["log-level"]);
67
+ const app = express();
68
+ const mcpServer = createMCPServer({
69
+ logger,
70
+ scopes: flags.scope,
71
+ ...{ bearerAuth: flags["bearer-auth"] },
72
+ serverURL: flags["server-url"],
73
+ serverIdx: flags["server-index"],
74
+ });
75
+ let transport: SSEServerTransport | undefined;
76
+ const controller = new AbortController();
77
+
78
+ app.get("/sse", async (_req, res) => {
79
+ transport = new SSEServerTransport("/message", res);
80
+
81
+ await mcpServer.connect(transport);
82
+
83
+ mcpServer.server.onclose = async () => {
84
+ res.end();
85
+ };
86
+ });
87
+
88
+ app.post("/message", async (req, res) => {
89
+ if (!transport) {
90
+ throw new Error("Server transport not initialized");
91
+ }
92
+
93
+ await transport.handlePostMessage(req, res);
94
+ });
95
+
96
+ const httpServer = app.listen(flags.port, "0.0.0.0", () => {
97
+ const ha = httpServer.address();
98
+ const host = typeof ha === "string" ? ha : `${ha?.address}:${ha?.port}`;
99
+ logger.info("MCP HTTP server started", { host });
100
+ });
101
+
102
+ let closing = false;
103
+ controller.signal.addEventListener("abort", async () => {
104
+ if (closing) {
105
+ logger.info("Received second signal. Forcing shutdown.");
106
+ process.exit(1);
107
+ }
108
+ closing = true;
109
+
110
+ logger.info("Shutting down MCP server");
111
+
112
+ await mcpServer.close();
113
+
114
+ logger.info("Shutting down HTTP server");
115
+
116
+ const timer = setTimeout(() => {
117
+ logger.info("Forcing shutdown");
118
+ process.exit(1);
119
+ }, 5000);
120
+
121
+ httpServer.close(() => {
122
+ clearTimeout(timer);
123
+ logger.info("Graceful shutdown complete");
124
+ process.exit(0);
125
+ });
126
+ });
127
+
128
+ const abort = () => controller.abort();
129
+ process.on("SIGTERM", abort);
130
+ process.on("SIGINT", abort);
131
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
+ */
4
+
5
+ import { CommandContext, StricliProcess } from "@stricli/core";
6
+
7
+ export interface LocalContext extends CommandContext {
8
+ readonly process: StricliProcess;
9
+ }
10
+
11
+ export function buildContext(process: NodeJS.Process): LocalContext {
12
+ return { process: process as StricliProcess };
13
+ }