@squadbase/vite-server 0.1.3-dev.15 → 0.1.3-dev.16

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 (59) hide show
  1. package/dist/cli/index.js +2105 -2700
  2. package/dist/connectors/airtable-oauth.js +16 -5
  3. package/dist/connectors/airtable.js +16 -5
  4. package/dist/connectors/amplitude.js +16 -5
  5. package/dist/connectors/anthropic.js +16 -5
  6. package/dist/connectors/asana.js +16 -5
  7. package/dist/connectors/attio.js +16 -5
  8. package/dist/connectors/backlog-api-key.js +16 -5
  9. package/dist/connectors/customerio.js +16 -5
  10. package/dist/connectors/dbt.js +16 -5
  11. package/dist/connectors/gamma.js +16 -5
  12. package/dist/connectors/gemini.js +16 -5
  13. package/dist/connectors/gmail-oauth.js +16 -5
  14. package/dist/connectors/gmail.js +68 -34
  15. package/dist/connectors/google-ads.js +16 -5
  16. package/dist/connectors/google-analytics-oauth.js +16 -5
  17. package/dist/connectors/google-analytics.js +16 -5
  18. package/dist/connectors/google-calendar-oauth.js +16 -5
  19. package/dist/connectors/google-calendar.js +71 -48
  20. package/dist/connectors/{google-drive-oauth.d.ts → google-docs.d.ts} +1 -1
  21. package/dist/connectors/google-docs.js +585 -0
  22. package/dist/connectors/google-drive.d.ts +1 -1
  23. package/dist/connectors/google-drive.js +391 -327
  24. package/dist/connectors/google-sheets.d.ts +1 -1
  25. package/dist/connectors/google-sheets.js +210 -280
  26. package/dist/connectors/google-slides.d.ts +1 -1
  27. package/dist/connectors/google-slides.js +198 -335
  28. package/dist/connectors/grafana.js +16 -5
  29. package/dist/connectors/hubspot-oauth.js +16 -5
  30. package/dist/connectors/hubspot.js +16 -5
  31. package/dist/connectors/intercom-oauth.js +16 -5
  32. package/dist/connectors/intercom.js +16 -5
  33. package/dist/connectors/jira-api-key.js +16 -5
  34. package/dist/connectors/kintone-api-token.js +133 -59
  35. package/dist/connectors/kintone.js +16 -5
  36. package/dist/connectors/linkedin-ads.js +16 -5
  37. package/dist/connectors/mailchimp-oauth.js +16 -5
  38. package/dist/connectors/mailchimp.js +16 -5
  39. package/dist/connectors/mixpanel.js +16 -5
  40. package/dist/connectors/notion-oauth.js +16 -5
  41. package/dist/connectors/notion.js +16 -5
  42. package/dist/connectors/openai.js +16 -5
  43. package/dist/connectors/sentry.js +16 -5
  44. package/dist/connectors/shopify-oauth.js +16 -5
  45. package/dist/connectors/shopify.js +16 -5
  46. package/dist/connectors/stripe-api-key.js +16 -5
  47. package/dist/connectors/stripe-oauth.js +16 -5
  48. package/dist/connectors/wix-store.js +16 -5
  49. package/dist/connectors/zendesk-oauth.js +16 -5
  50. package/dist/connectors/zendesk.js +16 -5
  51. package/dist/index.js +2100 -2695
  52. package/dist/main.js +2100 -2695
  53. package/dist/vite-plugin.js +2100 -2695
  54. package/package.json +7 -15
  55. package/dist/connectors/google-drive-oauth.js +0 -879
  56. package/dist/connectors/google-sheets-oauth.d.ts +0 -5
  57. package/dist/connectors/google-sheets-oauth.js +0 -821
  58. package/dist/connectors/google-slides-oauth.d.ts +0 -5
  59. package/dist/connectors/google-slides-oauth.js +0 -742
@@ -245,16 +245,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
245
245
  * Filters connections by connectorKey internally.
246
246
  * Returns tools keyed as `${connectorKey}_${toolName}`.
247
247
  */
248
- createTools(connections, config) {
248
+ createTools(connections, config, opts) {
249
249
  const myConnections = connections.filter(
250
250
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
251
251
  );
252
252
  const result = {};
253
253
  for (const t of Object.values(this.tools)) {
254
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
255
- myConnections,
256
- config
257
- );
254
+ const tool = t.createTool(myConnections, config);
255
+ const originalToModelOutput = tool.toModelOutput;
256
+ result[`${this.connectorKey}_${t.name}`] = {
257
+ ...tool,
258
+ toModelOutput: async (options) => {
259
+ if (!originalToModelOutput) {
260
+ return opts.truncateOutput(options.output);
261
+ }
262
+ const modelOutput = await originalToModelOutput(options);
263
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
264
+ return opts.truncateOutput(modelOutput.value);
265
+ }
266
+ return modelOutput;
267
+ }
268
+ };
258
269
  }
259
270
  return result;
260
271
  }
@@ -90,16 +90,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
90
90
  * Filters connections by connectorKey internally.
91
91
  * Returns tools keyed as `${connectorKey}_${toolName}`.
92
92
  */
93
- createTools(connections, config) {
93
+ createTools(connections, config, opts) {
94
94
  const myConnections = connections.filter(
95
95
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
96
96
  );
97
97
  const result = {};
98
98
  for (const t of Object.values(this.tools)) {
99
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
100
- myConnections,
101
- config
102
- );
99
+ const tool = t.createTool(myConnections, config);
100
+ const originalToModelOutput = tool.toModelOutput;
101
+ result[`${this.connectorKey}_${t.name}`] = {
102
+ ...tool,
103
+ toModelOutput: async (options) => {
104
+ if (!originalToModelOutput) {
105
+ return opts.truncateOutput(options.output);
106
+ }
107
+ const modelOutput = await originalToModelOutput(options);
108
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
109
+ return opts.truncateOutput(modelOutput.value);
110
+ }
111
+ return modelOutput;
112
+ }
113
+ };
103
114
  }
104
115
  return result;
105
116
  }
@@ -219,16 +219,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
219
219
  * Filters connections by connectorKey internally.
220
220
  * Returns tools keyed as `${connectorKey}_${toolName}`.
221
221
  */
222
- createTools(connections, config) {
222
+ createTools(connections, config, opts) {
223
223
  const myConnections = connections.filter(
224
224
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
225
225
  );
226
226
  const result = {};
227
227
  for (const t of Object.values(this.tools)) {
228
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
229
- myConnections,
230
- config
231
- );
228
+ const tool = t.createTool(myConnections, config);
229
+ const originalToModelOutput = tool.toModelOutput;
230
+ result[`${this.connectorKey}_${t.name}`] = {
231
+ ...tool,
232
+ toModelOutput: async (options) => {
233
+ if (!originalToModelOutput) {
234
+ return opts.truncateOutput(options.output);
235
+ }
236
+ const modelOutput = await originalToModelOutput(options);
237
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
238
+ return opts.truncateOutput(modelOutput.value);
239
+ }
240
+ return modelOutput;
241
+ }
242
+ };
232
243
  }
233
244
  return result;
234
245
  }
@@ -90,16 +90,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
90
90
  * Filters connections by connectorKey internally.
91
91
  * Returns tools keyed as `${connectorKey}_${toolName}`.
92
92
  */
93
- createTools(connections, config) {
93
+ createTools(connections, config, opts) {
94
94
  const myConnections = connections.filter(
95
95
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
96
96
  );
97
97
  const result = {};
98
98
  for (const t of Object.values(this.tools)) {
99
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
100
- myConnections,
101
- config
102
- );
99
+ const tool = t.createTool(myConnections, config);
100
+ const originalToModelOutput = tool.toModelOutput;
101
+ result[`${this.connectorKey}_${t.name}`] = {
102
+ ...tool,
103
+ toModelOutput: async (options) => {
104
+ if (!originalToModelOutput) {
105
+ return opts.truncateOutput(options.output);
106
+ }
107
+ const modelOutput = await originalToModelOutput(options);
108
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
109
+ return opts.truncateOutput(modelOutput.value);
110
+ }
111
+ return modelOutput;
112
+ }
113
+ };
103
114
  }
104
115
  return result;
105
116
  }
@@ -237,16 +237,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
237
237
  * Filters connections by connectorKey internally.
238
238
  * Returns tools keyed as `${connectorKey}_${toolName}`.
239
239
  */
240
- createTools(connections, config) {
240
+ createTools(connections, config, opts) {
241
241
  const myConnections = connections.filter(
242
242
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
243
243
  );
244
244
  const result = {};
245
245
  for (const t of Object.values(this.tools)) {
246
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
247
- myConnections,
248
- config
249
- );
246
+ const tool = t.createTool(myConnections, config);
247
+ const originalToModelOutput = tool.toModelOutput;
248
+ result[`${this.connectorKey}_${t.name}`] = {
249
+ ...tool,
250
+ toModelOutput: async (options) => {
251
+ if (!originalToModelOutput) {
252
+ return opts.truncateOutput(options.output);
253
+ }
254
+ const modelOutput = await originalToModelOutput(options);
255
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
256
+ return opts.truncateOutput(modelOutput.value);
257
+ }
258
+ return modelOutput;
259
+ }
260
+ };
250
261
  }
251
262
  return result;
252
263
  }
@@ -186,16 +186,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
186
186
  * Filters connections by connectorKey internally.
187
187
  * Returns tools keyed as `${connectorKey}_${toolName}`.
188
188
  */
189
- createTools(connections, config) {
189
+ createTools(connections, config, opts) {
190
190
  const myConnections = connections.filter(
191
191
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
192
192
  );
193
193
  const result = {};
194
194
  for (const t of Object.values(this.tools)) {
195
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
196
- myConnections,
197
- config
198
- );
195
+ const tool = t.createTool(myConnections, config);
196
+ const originalToModelOutput = tool.toModelOutput;
197
+ result[`${this.connectorKey}_${t.name}`] = {
198
+ ...tool,
199
+ toModelOutput: async (options) => {
200
+ if (!originalToModelOutput) {
201
+ return opts.truncateOutput(options.output);
202
+ }
203
+ const modelOutput = await originalToModelOutput(options);
204
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
205
+ return opts.truncateOutput(modelOutput.value);
206
+ }
207
+ return modelOutput;
208
+ }
209
+ };
199
210
  }
200
211
  return result;
201
212
  }
@@ -61,6 +61,15 @@ var parameters = {
61
61
  type: "text",
62
62
  secret: true,
63
63
  required: true
64
+ }),
65
+ appId: new ParameterDefinition({
66
+ slug: "app-id",
67
+ name: "kintone App ID",
68
+ description: "The numeric ID of the kintone app this token is scoped to (visible in the app URL: https://{subdomain}.cybozu.com/k/{appId}/). API tokens are always scoped to a single app.",
69
+ envVarBaseKey: "KINTONE_APP_ID",
70
+ type: "text",
71
+ secret: false,
72
+ required: true
64
73
  })
65
74
  };
66
75
 
@@ -68,9 +77,14 @@ var parameters = {
68
77
  function createClient(params) {
69
78
  const baseUrl = params[parameters.baseUrl.slug];
70
79
  const apiToken = params[parameters.apiToken.slug];
71
- if (!baseUrl || !apiToken) {
72
- const required = [parameters.baseUrl.slug, parameters.apiToken.slug];
73
- const missing = required.filter((s) => !params[s]);
80
+ const appId = params[parameters.appId.slug];
81
+ const required = [
82
+ parameters.baseUrl.slug,
83
+ parameters.apiToken.slug,
84
+ parameters.appId.slug
85
+ ];
86
+ const missing = required.filter((s) => !params[s]);
87
+ if (missing.length > 0) {
74
88
  throw new Error(
75
89
  `kintone: missing required parameters: ${missing.join(", ")}`
76
90
  );
@@ -87,16 +101,17 @@ function createClient(params) {
87
101
  return _restClient;
88
102
  }
89
103
  return {
104
+ appId,
90
105
  request(path2, init) {
91
106
  const url = `${baseUrl.replace(/\/+$/, "")}${path2}`;
92
107
  const headers = new Headers(init?.headers);
93
108
  headers.set("X-Cybozu-API-Token", apiToken);
94
109
  return fetch(url, { ...init, headers });
95
110
  },
96
- async getRecords(appId, options) {
111
+ async getRecords(targetAppId, options) {
97
112
  const client = await getRestClient();
98
113
  const result = await client.record.getRecords({
99
- app: appId,
114
+ app: targetAppId ?? appId,
100
115
  query: options?.query,
101
116
  fields: options?.fields,
102
117
  totalCount: options?.totalCount
@@ -106,11 +121,12 @@ function createClient(params) {
106
121
  totalCount: result.totalCount ? Number(result.totalCount) : null
107
122
  };
108
123
  },
109
- async getRecord(appId, recordId) {
124
+ async getRecord(appIdOrRecordId, recordId) {
110
125
  const client = await getRestClient();
126
+ const [targetAppId, targetRecordId] = recordId === void 0 ? [appId, appIdOrRecordId] : [appIdOrRecordId, recordId];
111
127
  const result = await client.record.getRecord({
112
- app: appId,
113
- id: recordId
128
+ app: targetAppId,
129
+ id: targetRecordId
114
130
  });
115
131
  return { record: result.record };
116
132
  }
@@ -199,16 +215,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
199
215
  * Filters connections by connectorKey internally.
200
216
  * Returns tools keyed as `${connectorKey}_${toolName}`.
201
217
  */
202
- createTools(connections, config) {
218
+ createTools(connections, config, opts) {
203
219
  const myConnections = connections.filter(
204
220
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
205
221
  );
206
222
  const result = {};
207
223
  for (const t of Object.values(this.tools)) {
208
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
209
- myConnections,
210
- config
211
- );
224
+ const tool = t.createTool(myConnections, config);
225
+ const originalToModelOutput = tool.toModelOutput;
226
+ result[`${this.connectorKey}_${t.name}`] = {
227
+ ...tool,
228
+ toModelOutput: async (options) => {
229
+ if (!originalToModelOutput) {
230
+ return opts.truncateOutput(options.output);
231
+ }
232
+ const modelOutput = await originalToModelOutput(options);
233
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
234
+ return opts.truncateOutput(modelOutput.value);
235
+ }
236
+ return modelOutput;
237
+ }
238
+ };
212
239
  }
213
240
  return result;
214
241
  }
@@ -230,23 +257,49 @@ var AUTH_TYPES = {
230
257
  // ../connectors/src/connectors/kintone-api-token/setup.ts
231
258
  var kintoneApiTokenOnboarding = new ConnectorOnboarding({
232
259
  dataOverviewInstructions: {
233
- en: `1. Call kintone-api-token_request with GET apps.json to list available apps
234
- 2. For key apps, call kintone-api-token_request with GET app/form/fields.json?app={appId} to get field definitions
235
- 3. Call kintone-api-token_request with GET records.json?app={appId}&query=limit 5 to sample records`,
236
- ja: `1. kintone-api-token_request \u3067 GET apps.json \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30A2\u30D7\u30EA\u4E00\u89A7\u3092\u53D6\u5F97
237
- 2. \u4E3B\u8981\u30A2\u30D7\u30EA\u306B\u3064\u3044\u3066 kintone-api-token_request \u3067 GET app/form/fields.json?app={appId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u3092\u53D6\u5F97
238
- 3. kintone-api-token_request \u3067 GET records.json?app={appId}&query=limit 5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
260
+ en: `Each connection is scoped to a single kintone app (configured via the "app-id" parameter). The request tool auto-injects the configured app id, so you do NOT need to specify "app=" in paths or "app" in bodies. apps.json is NOT available with API Token auth.
261
+
262
+ 1. Call kintone-api-token_request with GET app.json to fetch the scoped app's metadata (name, description, creator)
263
+ 2. Call kintone-api-token_request with GET app/form/fields.json to get field definitions
264
+ 3. Call kintone-api-token_request with GET records.json with query=limit 5 to sample records`,
265
+ ja: `\u5404\u63A5\u7D9A\u306F1\u3064\u306Ekintone\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\uFF08"app-id" \u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u8A2D\u5B9A\uFF09\u3002request \u30C4\u30FC\u30EB\u306F\u8A2D\u5B9A\u3055\u308C\u305F\u30A2\u30D7\u30EAID\u3092\u81EA\u52D5\u6CE8\u5165\u3059\u308B\u305F\u3081\u3001\u30D1\u30B9\u306B "app=" \u3084 body \u306B "app" \u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u3002API Token \u8A8D\u8A3C\u3067\u306F apps.json \u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
266
+
267
+ 1. kintone-api-token_request \u3067 GET app.json \u3092\u547C\u3073\u51FA\u3057\u3001\u30B9\u30B3\u30FC\u30D7\u5BFE\u8C61\u30A2\u30D7\u30EA\u306E\u30E1\u30BF\u60C5\u5831\uFF08\u30A2\u30D7\u30EA\u540D\u3001\u8AAC\u660E\u3001\u4F5C\u6210\u8005\uFF09\u3092\u53D6\u5F97
268
+ 2. kintone-api-token_request \u3067 GET app/form/fields.json \u3092\u547C\u3073\u51FA\u3057\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u3092\u53D6\u5F97
269
+ 3. kintone-api-token_request \u3067 GET records.json \u3092 query=limit 5 \u3067\u547C\u3073\u51FA\u3057\u3001\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
239
270
  }
240
271
  });
241
272
 
242
273
  // ../connectors/src/connectors/kintone-api-token/tools/request.ts
243
274
  import { z } from "zod";
244
275
  var REQUEST_TIMEOUT_MS = 6e4;
276
+ var APP_PARAM_KEY_BY_ENDPOINT = {
277
+ "app.json": "id"
278
+ };
279
+ var DEFAULT_APP_PARAM_KEY = "app";
280
+ function injectAppIntoPath(path2, appId) {
281
+ const [head, query = ""] = path2.split("?", 2);
282
+ const endpoint = head.toLowerCase();
283
+ const paramKey = APP_PARAM_KEY_BY_ENDPOINT[endpoint] ?? DEFAULT_APP_PARAM_KEY;
284
+ const params = new URLSearchParams(query);
285
+ if (!params.has(paramKey)) {
286
+ params.set(paramKey, appId);
287
+ }
288
+ const serialized = params.toString();
289
+ return serialized ? `${head}?${serialized}` : head;
290
+ }
291
+ function injectAppIntoBody(body, appId) {
292
+ if (!body) return body;
293
+ if ("app" in body) return body;
294
+ return { app: appId, ...body };
295
+ }
245
296
  var inputSchema = z.object({
246
297
  toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
247
298
  connectionId: z.string().describe("ID of the kintone connection to use"),
248
299
  method: z.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method"),
249
- path: z.string().describe("API path (e.g., 'apps.json', 'records.json?app=1&query=...')"),
300
+ path: z.string().describe(
301
+ "API path (e.g., 'app.json', 'app/form/fields.json', 'records.json?query=limit 5'). The connection's app id is auto-injected; you do not need to include 'app=' in the query string. 'apps.json' is not supported with API Token auth."
302
+ ),
250
303
  body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON)")
251
304
  });
252
305
  var outputSchema = z.discriminatedUnion("success", [
@@ -275,20 +328,31 @@ Authentication is handled automatically using the API token.`,
275
328
  try {
276
329
  const baseUrl = parameters.baseUrl.getValue(connection2);
277
330
  const apiToken = parameters.apiToken.getValue(connection2);
278
- const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${path2}`;
331
+ const appId = parameters.appId.getValue(connection2);
332
+ const normalizedPath = path2.replace(/^\/+/, "");
333
+ const pathHead = normalizedPath.split("?")[0] ?? "";
334
+ if (/^apps\.json$/i.test(pathHead)) {
335
+ return {
336
+ success: false,
337
+ error: `kintone API tokens are scoped to a single app and cannot list apps. This connection is scoped to app ${appId}. Use app-specific endpoints (e.g., app.json, app/form/fields.json, records.json).`
338
+ };
339
+ }
340
+ const injectedPath = injectAppIntoPath(normalizedPath, appId);
341
+ const injectedBody = injectAppIntoBody(body, appId);
342
+ const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${injectedPath}`;
279
343
  const controller = new AbortController();
280
344
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
281
345
  try {
282
346
  const headers = {
283
347
  "X-Cybozu-API-Token": apiToken
284
348
  };
285
- if (body) {
349
+ if (injectedBody) {
286
350
  headers["Content-Type"] = "application/json";
287
351
  }
288
352
  const response = await fetch(url, {
289
353
  method,
290
354
  headers,
291
- body: body ? JSON.stringify(body) : void 0,
355
+ body: injectedBody ? JSON.stringify(injectedBody) : void 0,
292
356
  signal: controller.signal
293
357
  });
294
358
  const data = await response.json();
@@ -323,18 +387,26 @@ var kintoneApiTokenConnector = new ConnectorPlugin({
323
387
  systemPrompt: {
324
388
  en: `### Tools
325
389
 
326
- - \`kintone-api-key_request\`: The only way to call the kintone REST API. Use it to list apps, fetch field definitions, and read/write records. Authentication (API Token) and the base URL are configured automatically. API tokens are scoped per app \u2014 combine multiple tokens with commas to access multiple apps. See the kintone REST API Reference below for endpoints and the kintone query syntax.
390
+ - \`kintone-api-token_request\`: The only way to call the kintone REST API. Use it to fetch app metadata/field definitions and read/write records. Authentication (API Token), base URL, and the connection's app id are configured automatically. Each connection is scoped to exactly one app (kintone API tokens are per-app).
391
+
392
+ ### App scoping (important)
393
+
394
+ - Each connection is scoped to one app, configured via the "app-id" parameter.
395
+ - The request tool auto-injects the configured app id:
396
+ - Query string: adds \`app=<appId>\` to paths like \`records.json\`, \`app/form/fields.json\`, etc. when missing. For \`app.json\` (app metadata), adds \`id=<appId>\` instead.
397
+ - Request body: adds \`"app": <appId>\` to POST/PUT bodies when missing.
398
+ - You do NOT need to include "app=" in paths or "app" in bodies \u2014 it is handled for you.
399
+ - \`apps.json\` (list all apps) is NOT callable with API Token auth.
327
400
 
328
401
  ### Business Logic
329
402
 
330
403
  The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
331
404
 
332
- SDK methods (client created via \`connection(connectionId)\`):
333
- - \`client.request(path, init?)\` \u2014 low-level authenticated fetch
334
- - \`client.getRecords(appId, options?)\` \u2014 fetch records with query/fields/totalCount (uses @kintone/rest-api-client)
335
- - \`client.getRecord(appId, recordId)\` \u2014 fetch a single record
336
-
337
- Note: app listing (\`/k/v1/apps.json\`) requires user-level auth and is not available via API token.
405
+ SDK surface (client created via \`connection(connectionId)\`):
406
+ - \`client.appId\` \u2014 the numeric app id this connection is scoped to
407
+ - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (pass \`?app=\${client.appId}\` yourself)
408
+ - \`client.getRecords(appId?, options?)\` \u2014 fetch records; if \`appId\` is omitted, the connection's app id is used
409
+ - \`client.getRecord(appIdOrRecordId, recordId?)\` \u2014 fetch a single record; if called with one argument it is treated as the record id and the connection's app id is used
338
410
 
339
411
  \`\`\`ts
340
412
  import type { Context } from "hono";
@@ -343,12 +415,9 @@ import { connection } from "@squadbase/vite-server/connectors/kintone-api-token"
343
415
  const kintone = connection("<connectionId>");
344
416
 
345
417
  export default async function handler(c: Context) {
346
- const { appId, status = "Active" } = await c.req.json<{
347
- appId: number;
348
- status?: string;
349
- }>();
418
+ const { status = "Active" } = await c.req.json<{ status?: string }>();
350
419
 
351
- const { records, totalCount } = await kintone.getRecords(appId, {
420
+ const { records, totalCount } = await kintone.getRecords(undefined, {
352
421
  query: \`status = "\${status}" order by updatedTime desc limit 100\`,
353
422
  fields: ["$id", "name", "email", "status", "updatedTime"],
354
423
  totalCount: true,
@@ -369,19 +438,19 @@ export default async function handler(c: Context) {
369
438
 
370
439
  ### kintone REST API Reference
371
440
 
372
- #### List Apps
373
- - \`GET apps.json\`
441
+ #### Get App Metadata
442
+ - \`GET app.json\` \u2192 returns { appId, name, description, createdAt, modifiedAt, creator, ... }
374
443
 
375
444
  #### Get Field Definitions
376
- - \`GET app/form/fields.json?app={appId}\`
445
+ - \`GET app/form/fields.json\`
377
446
 
378
447
  #### Get Records
379
- - \`GET records.json?app={appId}&query={query}\`
380
- - Query example: \`records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100\`
448
+ - \`GET records.json?query={query}\`
449
+ - Query example: \`records.json?query=updatedTime > "2024-01-01" order by recordNumber asc limit 100\`
381
450
 
382
451
  #### Add Record
383
452
  - \`POST record.json\`
384
- - Body: \`{ "app": 1, "record": { "fieldName": { "value": "value" } } }\`
453
+ - Body: \`{ "record": { "fieldName": { "value": "value" } } }\`
385
454
 
386
455
  #### kintone Query Syntax
387
456
  - Comparison: \`fieldName = "value"\`, \`fieldName > 100\`
@@ -391,18 +460,26 @@ export default async function handler(c: Context) {
391
460
  - String: \`like "partial match"\``,
392
461
  ja: `### \u30C4\u30FC\u30EB
393
462
 
394
- - \`kintone-api-key_request\`: kintone REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A2\u30D7\u30EA\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u8AAD\u307F\u66F8\u304D\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API\u30C8\u30FC\u30AF\u30F3\uFF09\u3068\u30D9\u30FC\u30B9URL\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002API\u30C8\u30FC\u30AF\u30F3\u306F\u30A2\u30D7\u30EA\u3054\u3068\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059 \u2014 \u8907\u6570\u306E\u30A2\u30D7\u30EA\u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u5834\u5408\u306F\u30AB\u30F3\u30DE\u533A\u5207\u308A\u3067\u30C8\u30FC\u30AF\u30F3\u3092\u7D44\u307F\u5408\u308F\u305B\u3066\u304F\u3060\u3055\u3044\u3002\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u304A\u3088\u3073kintone\u30AF\u30A8\u30EA\u69CB\u6587\u306F\u4E0B\u90E8\u306E\u300Ckintone REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
463
+ - \`kintone-api-token_request\`: kintone REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A2\u30D7\u30EA\u306E\u30E1\u30BF\u60C5\u5831\u30FB\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u8AAD\u307F\u66F8\u304D\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API\u30C8\u30FC\u30AF\u30F3\uFF09\u3001\u30D9\u30FC\u30B9URL\u3001\u304A\u3088\u3073\u63A5\u7D9A\u306E\u30A2\u30D7\u30EAID\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u5404\u63A5\u7D9A\u306F\u3061\u3087\u3046\u30691\u3064\u306E\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\uFF08kintone API\u30C8\u30FC\u30AF\u30F3\u306F\u30A2\u30D7\u30EA\u5358\u4F4D\u306E\u305F\u3081\uFF09\u3002
464
+
465
+ ### \u30A2\u30D7\u30EA\u30B9\u30B3\u30FC\u30D7\uFF08\u91CD\u8981\uFF09
466
+
467
+ - \u5404\u63A5\u7D9A\u306F1\u3064\u306E\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\uFF08"app-id" \u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u8A2D\u5B9A\uFF09\u3002
468
+ - request \u30C4\u30FC\u30EB\u306F\u8A2D\u5B9A\u3055\u308C\u305F\u30A2\u30D7\u30EAID\u3092\u81EA\u52D5\u6CE8\u5165\u3057\u307E\u3059:
469
+ - \u30AF\u30A8\u30EA\u6587\u5B57\u5217: \`records.json\` \u3084 \`app/form/fields.json\` \u7B49\u306E\u30D1\u30B9\u306B \`app=\` \u304C\u7121\u3051\u308C\u3070 \`app=<appId>\` \u3092\u4ED8\u4E0E\u3057\u307E\u3059\u3002\`app.json\`\uFF08\u30A2\u30D7\u30EA\u30E1\u30BF\u60C5\u5831\uFF09\u306E\u5834\u5408\u306F\u4EE3\u308F\u308A\u306B \`id=<appId>\` \u3092\u4ED8\u4E0E\u3057\u307E\u3059\u3002
470
+ - \u30EA\u30AF\u30A8\u30B9\u30C8\u30DC\u30C7\u30A3: POST/PUT \u306E\u30DC\u30C7\u30A3\u306B \`"app"\` \u304C\u7121\u3051\u308C\u3070\u81EA\u52D5\u7684\u306B\u8FFD\u52A0\u3057\u307E\u3059\u3002
471
+ - \u30D1\u30B9\u306B "app=" \u3084\u30DC\u30C7\u30A3\u306B "app" \u3092\u660E\u793A\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093 \u2014 \u81EA\u52D5\u3067\u51E6\u7406\u3055\u308C\u307E\u3059\u3002
472
+ - \`apps.json\`\uFF08\u5168\u30A2\u30D7\u30EA\u4E00\u89A7\uFF09\u306F API Token \u8A8D\u8A3C\u3067\u306F\u547C\u3073\u51FA\u305B\u307E\u305B\u3093\u3002
395
473
 
396
474
  ### Business Logic
397
475
 
398
476
  \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u8A8D\u8A3C\u60C5\u5831\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
399
477
 
400
- SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
401
- - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
402
- - \`client.getRecords(appId, options?)\` \u2014 query/fields/totalCount\u4ED8\u304D\u3067\u30EC\u30B3\u30FC\u30C9\u53D6\u5F97 (@kintone/rest-api-client \u4F7F\u7528)
403
- - \`client.getRecord(appId, recordId)\` \u2014 \u5358\u4E00\u30EC\u30B3\u30FC\u30C9\u3092\u53D6\u5F97
404
-
405
- \u6CE8: \u30A2\u30D7\u30EA\u4E00\u89A7 (\`/k/v1/apps.json\`) \u306F\u30E6\u30FC\u30B6\u30FC\u8A8D\u8A3C\u304C\u5FC5\u8981\u306A\u305F\u3081\u3001API \u30C8\u30FC\u30AF\u30F3\u8A8D\u8A3C\u3067\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
478
+ SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\uFF09:
479
+ - \`client.appId\` \u2014 \u3053\u306E\u63A5\u7D9A\u304C\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u308B\u30A2\u30D7\u30EAID
480
+ - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch\uFF08\`?app=\${client.appId}\` \u306F\u81EA\u5206\u3067\u4ED8\u3051\u308B\uFF09
481
+ - \`client.getRecords(appId?, options?)\` \u2014 \`appId\` \u3092\u7701\u7565\u3059\u308B\u3068\u63A5\u7D9A\u306E\u30A2\u30D7\u30EAID\u304C\u4F7F\u308F\u308C\u307E\u3059
482
+ - \`client.getRecord(appIdOrRecordId, recordId?)\` \u2014 \u5F15\u65701\u3064\u3067\u547C\u3076\u3068\u305D\u308C\u3092\u30EC\u30B3\u30FC\u30C9ID\u3068\u3057\u3066\u6271\u3044\u3001\u63A5\u7D9A\u306E\u30A2\u30D7\u30EAID\u3092\u4F7F\u3044\u307E\u3059
406
483
 
407
484
  \`\`\`ts
408
485
  import type { Context } from "hono";
@@ -411,12 +488,9 @@ import { connection } from "@squadbase/vite-server/connectors/kintone-api-token"
411
488
  const kintone = connection("<connectionId>");
412
489
 
413
490
  export default async function handler(c: Context) {
414
- const { appId, status = "Active" } = await c.req.json<{
415
- appId: number;
416
- status?: string;
417
- }>();
491
+ const { status = "Active" } = await c.req.json<{ status?: string }>();
418
492
 
419
- const { records, totalCount } = await kintone.getRecords(appId, {
493
+ const { records, totalCount } = await kintone.getRecords(undefined, {
420
494
  query: \`status = "\${status}" order by updatedTime desc limit 100\`,
421
495
  fields: ["$id", "name", "email", "status", "updatedTime"],
422
496
  totalCount: true,
@@ -437,19 +511,19 @@ export default async function handler(c: Context) {
437
511
 
438
512
  ### kintone REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
439
513
 
440
- #### \u30A2\u30D7\u30EA\u4E00\u89A7\u306E\u53D6\u5F97
441
- - \`GET apps.json\`
514
+ #### \u30A2\u30D7\u30EA\u30E1\u30BF\u60C5\u5831\u306E\u53D6\u5F97
515
+ - \`GET app.json\` \u2192 { appId, name, description, createdAt, modifiedAt, creator, ... } \u3092\u8FD4\u3059
442
516
 
443
517
  #### \u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97
444
- - \`GET app/form/fields.json?app={appId}\`
518
+ - \`GET app/form/fields.json\`
445
519
 
446
520
  #### \u30EC\u30B3\u30FC\u30C9\u306E\u53D6\u5F97
447
- - \`GET records.json?app={appId}&query={query}\`
448
- - \u30AF\u30A8\u30EA\u4F8B: \`records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100\`
521
+ - \`GET records.json?query={query}\`
522
+ - \u30AF\u30A8\u30EA\u4F8B: \`records.json?query=updatedTime > "2024-01-01" order by recordNumber asc limit 100\`
449
523
 
450
524
  #### \u30EC\u30B3\u30FC\u30C9\u306E\u8FFD\u52A0
451
525
  - \`POST record.json\`
452
- - Body: \`{ "app": 1, "record": { "fieldName": { "value": "value" } } }\`
526
+ - Body: \`{ "record": { "fieldName": { "value": "value" } } }\`
453
527
 
454
528
  #### kintone \u30AF\u30A8\u30EA\u69CB\u6587
455
529
  - \u6BD4\u8F03: \`fieldName = "value"\`, \`fieldName > 100\`
@@ -224,16 +224,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
224
224
  * Filters connections by connectorKey internally.
225
225
  * Returns tools keyed as `${connectorKey}_${toolName}`.
226
226
  */
227
- createTools(connections, config) {
227
+ createTools(connections, config, opts) {
228
228
  const myConnections = connections.filter(
229
229
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
230
230
  );
231
231
  const result = {};
232
232
  for (const t of Object.values(this.tools)) {
233
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
234
- myConnections,
235
- config
236
- );
233
+ const tool = t.createTool(myConnections, config);
234
+ const originalToModelOutput = tool.toModelOutput;
235
+ result[`${this.connectorKey}_${t.name}`] = {
236
+ ...tool,
237
+ toModelOutput: async (options) => {
238
+ if (!originalToModelOutput) {
239
+ return opts.truncateOutput(options.output);
240
+ }
241
+ const modelOutput = await originalToModelOutput(options);
242
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
243
+ return opts.truncateOutput(modelOutput.value);
244
+ }
245
+ return modelOutput;
246
+ }
247
+ };
237
248
  }
238
249
  return result;
239
250
  }
@@ -134,16 +134,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
134
134
  * Filters connections by connectorKey internally.
135
135
  * Returns tools keyed as `${connectorKey}_${toolName}`.
136
136
  */
137
- createTools(connections, config) {
137
+ createTools(connections, config, opts) {
138
138
  const myConnections = connections.filter(
139
139
  (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
140
140
  );
141
141
  const result = {};
142
142
  for (const t of Object.values(this.tools)) {
143
- result[`${this.connectorKey}_${t.name}`] = t.createTool(
144
- myConnections,
145
- config
146
- );
143
+ const tool = t.createTool(myConnections, config);
144
+ const originalToModelOutput = tool.toModelOutput;
145
+ result[`${this.connectorKey}_${t.name}`] = {
146
+ ...tool,
147
+ toModelOutput: async (options) => {
148
+ if (!originalToModelOutput) {
149
+ return opts.truncateOutput(options.output);
150
+ }
151
+ const modelOutput = await originalToModelOutput(options);
152
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
153
+ return opts.truncateOutput(modelOutput.value);
154
+ }
155
+ return modelOutput;
156
+ }
157
+ };
147
158
  }
148
159
  return result;
149
160
  }