gogcli-mcp-slides 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "Extended Google Slides for Claude via gogcli — auth + full Slides support (create, edit, export, templates, markdown)",
10
- "version": "4.7.0"
10
+ "version": "4.8.0"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "gogcli (Slides)",
16
16
  "source": "./",
17
17
  "description": "Extended Google Slides for Claude via gogcli — auth + full Slides support (create, edit, export, templates, markdown)",
18
- "version": "4.7.0",
18
+ "version": "4.8.0",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gogcli-mcp-slides",
3
3
  "displayName": "gogcli (Slides)",
4
- "version": "4.7.0",
4
+ "version": "4.8.0",
5
5
  "description": "Extended Google Slides for Claude via gogcli — auth + full Slides support (create, edit, export, templates, markdown)",
6
6
  "author": {
7
7
  "name": "Chris Hall",
@@ -21,6 +21,6 @@
21
21
  "pdf",
22
22
  "pptx"
23
23
  ],
24
- "skills": "./SKILL.md",
25
- "mcp": "./.mcp.json"
24
+ "skills": ".",
25
+ "mcpServers": "./.mcp.json"
26
26
  }
package/dist/index.js CHANGED
@@ -19763,7 +19763,7 @@ function date4(params) {
19763
19763
  return _coercedDate(ZodDate, params);
19764
19764
  }
19765
19765
 
19766
- // ../../node_modules/@modelcontextprotocol/core/dist/auth-BNDyLTqp.mjs
19766
+ // ../../node_modules/@modelcontextprotocol/server/node_modules/@modelcontextprotocol/core/dist/auth-BNDyLTqp.mjs
19767
19767
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
19768
19768
  var SUPPORTED_PROTOCOL_VERSIONS = [
19769
19769
  LATEST_PROTOCOL_VERSION,
@@ -34479,11 +34479,19 @@ var DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024 * 1024;
34479
34479
  var McpToolError = class extends Error {
34480
34480
  /** Actionable remediation text, when one applies. */
34481
34481
  hint;
34482
+ /** The upstream HTTP status this failure came from, when known. */
34483
+ status;
34484
+ /** What kind of failure this is, when the thrower knows. */
34485
+ kind;
34482
34486
  constructor(message, opts) {
34483
34487
  super(message, opts?.cause !== void 0 ? { cause: opts.cause } : void 0);
34484
34488
  this.name = "McpToolError";
34485
34489
  if (opts?.hint !== void 0)
34486
34490
  this.hint = opts.hint;
34491
+ if (opts?.status !== void 0)
34492
+ this.status = opts.status;
34493
+ if (opts?.kind !== void 0)
34494
+ this.kind = opts.kind;
34487
34495
  Object.setPrototypeOf(this, new.target.prototype);
34488
34496
  }
34489
34497
  };
@@ -34508,7 +34516,7 @@ var API_KEY_RE = new RegExp([
34508
34516
  // webhook signing secret (Stripe-style)
34509
34517
  ].map((p) => `\\b${p}`).join("|"), "g");
34510
34518
  var GOOGLE_OAUTH_TOKEN_RE = /(?<![A-Za-z0-9+/])(?:ya29\.|1\/\/)[A-Za-z0-9._-]{8,}/g;
34511
- var QUERY_SECRET_RE = new RegExp(`([?&](?:(?:access|refresh|id|auth|session|csrf|xsrf)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|token|key|sig|(?:php|j)?sess(?:ion)?[_-]?id|sid|x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN})=)[^&#\\s"'<>\`]+`, "gi");
34519
+ var QUERY_SECRET_RE = new RegExp(`([?&](?:(?:access|refresh|id|auth|session|csrf|xsrf)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|token|key|sig|(?:code[_-]?)?verifier|(?:php|j)?sess(?:ion)?[_-]?id|sid|x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN})=)[^&#\\s"'<>\`]+`, "gi");
34512
34520
  var OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
34513
34521
  var FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
34514
34522
  var HEADER_SECRET_RE = new RegExp(`(\\b(?:x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN}|api[-_]?key)\\s*:\\s*)[^\\s,;"'<>\`]+`, "gi");
@@ -34519,6 +34527,8 @@ var JSON_SECRET_KEYS = [
34519
34527
  "api[_-]?secret",
34520
34528
  "(?:x[_-])?api[_-]?key",
34521
34529
  "private[_-]?key",
34530
+ "code[_-]?verifier",
34531
+ // PKCE; a bare `verifier` key is too generic for JSON
34522
34532
  `x[_-]${HEADER_NAME_RUN}?(?:api[_-]?key|token|secret|auth)${HEADER_NAME_RUN}`,
34523
34533
  // bounded like HEADER_SECRET_RE
34524
34534
  "(?:proxy-)?authorization",
@@ -34549,6 +34559,11 @@ function redactSecrets(text) {
34549
34559
  return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(GOOGLE_OAUTH_TOKEN_RE, "[REDACTED]").replace(HEADER_SECRET_RE, "$1[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(OAUTH_CODE_RE, "$1[REDACTED]").replace(FORM_PASSWORD_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_COOKIE_DQ_RE, redactJsonCookie('"')).replace(JSON_COOKIE_SQ_RE, redactJsonCookie("'")).replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_NUM_RE, "$1[REDACTED]").replace(JWT_RE, "[REDACTED]");
34550
34560
  }
34551
34561
  var ERROR_REDACTION_INPUT_MAX = 64 * 1024;
34562
+ function messageOf(err) {
34563
+ if (err instanceof Error)
34564
+ return err.message;
34565
+ return String(err);
34566
+ }
34552
34567
 
34553
34568
  // ../../node_modules/@chrischall/mcp-utils/dist/response/view.js
34554
34569
  function minifiedResult(data) {
@@ -34651,7 +34666,7 @@ function readEnvVar(key, opts = {}) {
34651
34666
  if (typeof raw === "string") {
34652
34667
  const trimmed = raw.trim();
34653
34668
  if (trimmed.length > 0 && trimmed !== "undefined" && trimmed !== "null" && !PLACEHOLDER_RE.test(trimmed)) {
34654
- return trimmed;
34669
+ return opts.trim === false ? raw : trimmed;
34655
34670
  }
34656
34671
  }
34657
34672
  return opts.default;
@@ -34689,12 +34704,14 @@ var SERVER_PROTOCOL_VERSIONS = Object.freeze([
34689
34704
  ...SUPPORTED_PROTOCOL_VERSIONS
34690
34705
  ]);
34691
34706
  function hintResultOrRethrow(err) {
34707
+ if (err instanceof ProtocolError && err.code === ProtocolErrorCode.UrlElicitationRequired)
34708
+ throw err;
34692
34709
  if (err instanceof McpToolError && err.hint) {
34693
34710
  return errorResult(`${err.message}
34694
34711
 
34695
34712
  Hint: ${err.hint}`);
34696
34713
  }
34697
- throw err;
34714
+ return errorResult(messageOf(err));
34698
34715
  }
34699
34716
  function mcpRequestFrom(args) {
34700
34717
  const ctx = args.at(-1);
@@ -34928,7 +34945,7 @@ var PositiveInt = external_exports.number().int().positive();
34928
34945
  var NonNegInt = external_exports.number().int().nonnegative();
34929
34946
  var NonEmptyString = external_exports.string().min(1);
34930
34947
  var IsoDate = external_exports.iso.date();
34931
- var IsoTime = external_exports.string().regex(/^([01]?\d|2[0-3]):[0-5]\d$/, "must be HH:MM (24h), e.g. 19:30");
34948
+ var IsoTime = external_exports.string().regex(/^([01]?\d|2[0-3]):[0-5]\d$/, "must be HH:MM (24h), e.g. 19:30").overwrite((v) => v.padStart(5, "0"));
34932
34949
  var NumericIdString = external_exports.string().regex(/^\d+$/, "must be a numeric id (digits only)").describe("A numeric id string (digits only), safe to interpolate into a URL path.");
34933
34950
  var SafePathSegment = external_exports.string().min(1).regex(/^[^/?#\s]+$/, 'must not contain "/", "?", "#", or whitespace').refine((v) => !v.includes(".."), 'must not contain ".."').describe('A single URL path segment, safe to interpolate: no "/", "..", "?", "#", or whitespace.');
34934
34951
  var schemaOrigin = external_exports.string().optional().describe("Portal origin (e.g. https://<vendor>.example.co) selecting which active session to use. Optional when only one session is active.");
@@ -35619,7 +35636,7 @@ function registerRunTool(server, options) {
35619
35636
  }
35620
35637
  server.registerTool(`gog_${service}_run`, {
35621
35638
  description,
35622
- annotations: { destructiveHint: true },
35639
+ annotations: { destructiveHint: true, openWorldHint: true },
35623
35640
  inputSchema: external_exports.object(inputSchema)
35624
35641
  }, async (rawArgs) => {
35625
35642
  const { subcommand, args, account } = rawArgs;
@@ -35765,13 +35782,13 @@ function formatAuthHealth(raw, now) {
35765
35782
  var spent = createSpentTokenStore();
35766
35783
 
35767
35784
  // ../gogcli-mcp/src/tools/auth.ts
35768
- var AUTH_RUN_SUBCOMMANDS = ["list", "status", "services", "remove", "alias"];
35785
+ var AUTH_RUN_SUBCOMMANDS = ["list", "status", "services", "alias"];
35769
35786
  function registerAuthToolsWith(server, defaultServices) {
35770
35787
  const servicesDescribe = `Services to authorize: "all" or comma-separated list (e.g. "sheets,gmail,calendar"). Default: "${defaultServices}". Prefer the narrowest set you need \u2014 requesting a service whose Google API is not enabled on the OAuth client's project makes Google reject the WHOLE request with invalid_scope.`;
35771
35788
  const extraScopesDescribe = "Additional raw OAuth scope URIs to request, comma-separated, on top of the ones `services` implies. Use for scopes no service covers \u2014 e.g. https://www.googleapis.com/auth/bigquery.readonly, required before gog_sheets_datasource_* can read BigQuery-backed Connected Sheets. Leave unset otherwise: an extra scope whose API is not enabled on the OAuth client project makes Google reject the WHOLE authorization with invalid_scope.";
35772
35789
  server.registerTool("gog_auth_list", {
35773
35790
  description: "List the Google accounts stored in gogcli, with their scopes. This reads local configuration only \u2014 it does not contact Google and does NOT tell you whether an account still works: a signed-out account whose refresh token expired or was revoked is listed here exactly like a healthy one, scopes and all. Use gog_auth_health to check whether an account can actually authenticate.",
35774
- annotations: { readOnlyHint: true },
35791
+ annotations: { readOnlyHint: true, openWorldHint: false },
35775
35792
  inputSchema: external_exports.object({})
35776
35793
  }, async () => {
35777
35794
  try {
@@ -35782,7 +35799,7 @@ function registerAuthToolsWith(server, defaultServices) {
35782
35799
  });
35783
35800
  server.registerTool("gog_auth_status", {
35784
35801
  description: "Show gogcli auth CONFIGURATION: keyring backend, credential files, and auth setup. Despite the name this is not a health check \u2014 it reads local setup and does not contact Google, so it says nothing about whether an account can still authenticate. Use gog_auth_health for that.",
35785
- annotations: { readOnlyHint: true },
35802
+ annotations: { readOnlyHint: true, openWorldHint: false },
35786
35803
  inputSchema: external_exports.object({})
35787
35804
  }, async () => {
35788
35805
  try {
@@ -35793,7 +35810,7 @@ function registerAuthToolsWith(server, defaultServices) {
35793
35810
  });
35794
35811
  server.registerTool("gog_auth_health", {
35795
35812
  description: `Check the LIVE health of each stored Google account. Unlike gog_auth_status (which only reports keyring/config setup), this performs a real token refresh against Google, so it detects expired or revoked (invalid_grant) refresh tokens \u2014 the account-wide sign-out that blocks every service. Reports per account: whether the token is currently valid, the mapped cause when it is not, how long ago it was authorized, and a warning as it approaches the 7-day refresh-token limit that applies to OAuth apps whose consent screen is still in "Testing" mode. Run it proactively to re-authorize on your own schedule instead of mid-task. On a hosted deployment this is the ONLY check that measures Google: a connector showing "connected" or "refreshed" has verified the client's connection to the MCP host, and nothing else \u2014 the Google credential lives in gog's keyring on that host and can be dead while the connection looks perfectly healthy.`,
35796
- annotations: { readOnlyHint: true },
35813
+ annotations: { readOnlyHint: true, openWorldHint: true },
35797
35814
  inputSchema: external_exports.object({})
35798
35815
  }, async () => {
35799
35816
  try {
@@ -35804,7 +35821,7 @@ function registerAuthToolsWith(server, defaultServices) {
35804
35821
  });
35805
35822
  server.registerTool("gog_auth_services", {
35806
35823
  description: "List all Google services supported by gogcli and the OAuth scopes each requires.",
35807
- annotations: { readOnlyHint: true },
35824
+ annotations: { readOnlyHint: true, openWorldHint: false },
35808
35825
  inputSchema: external_exports.object({})
35809
35826
  }, async () => {
35810
35827
  try {
@@ -35815,7 +35832,7 @@ function registerAuthToolsWith(server, defaultServices) {
35815
35832
  });
35816
35833
  server.registerTool("gog_auth_add", {
35817
35834
  description: "Authorize a Google account via browser-based OAuth. Opens a browser window where the user must sign in and grant access. Blocks for up to 5 minutes waiting for the user to complete authorization. If the browser does not open automatically, a fallback URL is included in the response. Use gog_auth_list to check which accounts are already configured.",
35818
- annotations: { destructiveHint: true },
35835
+ annotations: { destructiveHint: true, openWorldHint: true },
35819
35836
  inputSchema: external_exports.object({
35820
35837
  email: external_exports.string().describe("Google account email to authorize"),
35821
35838
  services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe),
@@ -35835,7 +35852,7 @@ function registerAuthToolsWith(server, defaultServices) {
35835
35852
  });
35836
35853
  server.registerTool("gog_auth_add_url", {
35837
35854
  description: "Begin REMOTE/headless Google authorization (step 1 of 2). Returns a sign-in URL to open in any browser \u2014 no local server or terminal on the gogcli host is needed, so this works on a hosted deployment where the interactive gog_auth_add cannot. Hand the URL to the user; after they sign in, the browser is redirected to a localhost URL that fails to load \u2014 that is expected. They copy that full redirected URL (from the address bar) and you pass it to gog_auth_add_complete. The link is valid for 10 minutes. If you pass a custom `services` here, pass the SAME value to gog_auth_add_complete or the second step will not match this one.",
35838
- annotations: { readOnlyHint: true },
35855
+ annotations: { readOnlyHint: true, openWorldHint: false },
35839
35856
  inputSchema: external_exports.object({
35840
35857
  email: external_exports.string().describe("Google account email to authorize"),
35841
35858
  services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe),
@@ -35852,7 +35869,7 @@ function registerAuthToolsWith(server, defaultServices) {
35852
35869
  });
35853
35870
  server.registerTool("gog_auth_add_complete", {
35854
35871
  description: "Complete REMOTE/headless Google authorization (step 2 of 2). Takes the full redirected localhost URL the user copied after finishing gog_auth_add_url, exchanges it for a refresh token, and stores it. Use the SAME `services` value you passed to gog_auth_add_url. Must run within 10 minutes of step 1 and against the same gogcli host.",
35855
- annotations: { destructiveHint: true },
35872
+ annotations: { destructiveHint: true, openWorldHint: true },
35856
35873
  inputSchema: external_exports.object({
35857
35874
  email: external_exports.string().describe("Google account email being authorized (same as step 1)"),
35858
35875
  redirectUrl: external_exports.string().describe(
@@ -35888,7 +35905,7 @@ function registerAuthToolsWith(server, defaultServices) {
35888
35905
  });
35889
35906
  registerRunTool(server, {
35890
35907
  service: "auth",
35891
- examples: '"remove", "alias", "list"',
35908
+ examples: '"alias", "list", "status"',
35892
35909
  omitAccount: true,
35893
35910
  allowedSubcommands: AUTH_RUN_SUBCOMMANDS,
35894
35911
  note: "For browser-based authorization, use gog_auth_add instead."
@@ -35950,6 +35967,11 @@ var attachInlineParam = external_exports.array(inlineAttachmentSchema).optional(
35950
35967
  );
35951
35968
 
35952
35969
  // ../gogcli-mcp/src/tools/gmail.ts
35970
+ var signatureSchema = {
35971
+ signature: external_exports.boolean().optional().describe("Append the Gmail signature from the active send-as address"),
35972
+ signatureFrom: external_exports.string().optional().describe("Append the Gmail signature from this send-as email address"),
35973
+ signatureFile: external_exports.string().optional().describe("Append a local signature file (plain text or HTML), read on the gog server. Must be inside GOG_FILE_ROOTS. Cannot be combined with signature/signatureFrom.")
35974
+ };
35953
35975
  var replySchema = {
35954
35976
  messageId: external_exports.string().describe("Gmail message ID to reply to \u2014 the short hex `id` from gog_gmail_get / _search (or gog_gmail_messages_search, gogcli-mcp-gmail only). NOT the threadId, NOT the RFC822 `<\u2026@host>` Message-Id header."),
35955
35977
  body: external_exports.string().optional().describe("Reply body (plain text; required unless bodyHtml or bodyHtmlFile is set). Any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Note gog strips trailing newlines from a file-delivered body."),
@@ -35965,9 +35987,7 @@ var replySchema = {
35965
35987
  attachInline: attachInlineParam,
35966
35988
  from: external_exports.string().optional().describe("Send from this email address (must be a verified send-as alias)"),
35967
35989
  autoFromAddressedAlias: external_exports.boolean().optional().describe("When from is omitted, send from the verified send-as alias the original message was addressed TO, instead of the account's primary address \u2014 so a reply to mail sent to an alias goes back out from that alias. Ignored when from is set."),
35968
- signature: external_exports.boolean().optional().describe("Append the Gmail signature from the active send-as address"),
35969
- signatureFrom: external_exports.string().optional().describe("Append the Gmail signature from this send-as email address"),
35970
- signatureFile: external_exports.string().optional().describe("Append a local signature file (plain text or HTML), read on the gog server"),
35990
+ ...signatureSchema,
35971
35991
  account: accountParam
35972
35992
  };
35973
35993
  var sendReplySchema = external_exports.object({ ...replySchema, confirmToken: confirmTokenParam });
@@ -35986,7 +36006,7 @@ function registerSlidesTools(server) {
35986
36006
  server.registerTool("gog_slides_export", {
35987
36007
  description: "Export a Google Slides presentation to a local file (pdf or pptx). The out path must be inside the server's GOG_FILE_ROOTS directories.",
35988
36008
  // Writes a file on the gog host and can overwrite one: not read-only.
35989
- annotations: { readOnlyHint: false, destructiveHint: true },
36009
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
35990
36010
  inputSchema: external_exports.object({
35991
36011
  presentationId: external_exports.string().describe("Presentation ID"),
35992
36012
  out: external_exports.string().optional().describe("Output file path"),
@@ -36004,7 +36024,7 @@ function registerSlidesTools(server) {
36004
36024
  });
36005
36025
  server.registerTool("gog_slides_info", {
36006
36026
  description: "Get metadata for a Google Slides presentation (title, ID, slide count, etc.).",
36007
- annotations: { readOnlyHint: true },
36027
+ annotations: { readOnlyHint: true, openWorldHint: true },
36008
36028
  inputSchema: external_exports.object({
36009
36029
  presentationId: external_exports.string().describe("Presentation ID"),
36010
36030
  account: accountParam
@@ -36014,7 +36034,7 @@ function registerSlidesTools(server) {
36014
36034
  });
36015
36035
  server.registerTool("gog_slides_create", {
36016
36036
  description: "Create a new Google Slides presentation, optionally in a folder or copying from a template.",
36017
- annotations: { destructiveHint: true },
36037
+ annotations: { destructiveHint: true, openWorldHint: true },
36018
36038
  inputSchema: external_exports.object({
36019
36039
  title: external_exports.string().describe("Presentation title"),
36020
36040
  parent: external_exports.string().optional().describe("Destination folder ID"),
@@ -36029,7 +36049,7 @@ function registerSlidesTools(server) {
36029
36049
  });
36030
36050
  server.registerTool("gog_slides_copy", {
36031
36051
  description: "Copy a Google Slides presentation to a new presentation with the given title.",
36032
- annotations: { destructiveHint: true },
36052
+ annotations: { destructiveHint: true, openWorldHint: true },
36033
36053
  inputSchema: external_exports.object({
36034
36054
  presentationId: external_exports.string().describe("Presentation ID to copy"),
36035
36055
  title: external_exports.string().describe("Title for the new copy"),
@@ -36043,7 +36063,7 @@ function registerSlidesTools(server) {
36043
36063
  });
36044
36064
  server.registerTool("gog_slides_list_slides", {
36045
36065
  description: "List slides in a Google Slides presentation.",
36046
- annotations: { readOnlyHint: true },
36066
+ annotations: { readOnlyHint: true, openWorldHint: true },
36047
36067
  inputSchema: external_exports.object({
36048
36068
  presentationId: external_exports.string().describe("Presentation ID"),
36049
36069
  account: accountParam
@@ -36053,7 +36073,7 @@ function registerSlidesTools(server) {
36053
36073
  });
36054
36074
  server.registerTool("gog_slides_read_slide", {
36055
36075
  description: "Read the content of a slide (text, shapes, speaker notes). Set detail=true to also include normalized element geometry, styled text runs, paragraphs, table-cell content, and image source URLs.",
36056
- annotations: { readOnlyHint: true },
36076
+ annotations: { readOnlyHint: true, openWorldHint: true },
36057
36077
  inputSchema: external_exports.object({
36058
36078
  presentationId: external_exports.string().describe("Presentation ID"),
36059
36079
  slideId: external_exports.string().describe("Slide ID to read"),
@@ -36069,7 +36089,7 @@ function registerSlidesTools(server) {
36069
36089
  }
36070
36090
 
36071
36091
  // ../gogcli-mcp/src/server.ts
36072
- var VERSION = true ? "4.7.0" : "0.0.0";
36092
+ var VERSION = true ? "4.8.0" : "0.0.0";
36073
36093
 
36074
36094
  // ../gogcli-mcp/src/bootstrap-auth.ts
36075
36095
  import { join as join5 } from "node:path";
@@ -36147,7 +36167,7 @@ var MAX_BLOB_UPLOAD_BYTES = 100 * 1024 * 1024;
36147
36167
  function registerExtraSlidesTools(server) {
36148
36168
  server.registerTool("gog_slides_create_from_markdown", {
36149
36169
  description: "Create a new Google Slides presentation from markdown content (inline or from a file).",
36150
- annotations: { destructiveHint: true },
36170
+ annotations: { destructiveHint: true, openWorldHint: true },
36151
36171
  inputSchema: external_exports.object({
36152
36172
  title: external_exports.string().describe("Presentation title"),
36153
36173
  content: external_exports.string().optional().describe("Inline markdown content"),
@@ -36167,7 +36187,7 @@ function registerExtraSlidesTools(server) {
36167
36187
  });
36168
36188
  server.registerTool("gog_slides_create_from_template", {
36169
36189
  description: "Create a new Google Slides presentation from a template, with optional placeholder replacements.",
36170
- annotations: { destructiveHint: true },
36190
+ annotations: { destructiveHint: true, openWorldHint: true },
36171
36191
  inputSchema: external_exports.object({
36172
36192
  templateId: external_exports.string().describe("Template presentation ID"),
36173
36193
  title: external_exports.string().describe("New presentation title"),
@@ -36192,7 +36212,7 @@ function registerExtraSlidesTools(server) {
36192
36212
  });
36193
36213
  server.registerTool("gog_slides_add_slide", {
36194
36214
  description: "Add a new slide to a presentation from a local image, with optional speaker notes.",
36195
- annotations: { destructiveHint: true },
36215
+ annotations: { destructiveHint: true, openWorldHint: true },
36196
36216
  inputSchema: external_exports.object({
36197
36217
  presentationId: external_exports.string().describe("Presentation ID"),
36198
36218
  image: external_exports.string().describe("Path to the local image file"),
@@ -36212,7 +36232,7 @@ function registerExtraSlidesTools(server) {
36212
36232
  });
36213
36233
  server.registerTool("gog_slides_insert_image", {
36214
36234
  description: "Place an image on an existing slide at a given size and position, from a local file (image) or a public HTTPS URL (url \u2014 no Drive upload or sharing required). Unlike gog_slides_add_slide (which creates a new full-bleed image slide), this inserts onto a slide you already have. width is required; omit height to keep aspect ratio when using a local file (gog requires both width and height when using url).",
36215
- annotations: { destructiveHint: false },
36235
+ annotations: { destructiveHint: false, openWorldHint: true },
36216
36236
  inputSchema: external_exports.object({
36217
36237
  presentationId: external_exports.string().describe("Presentation ID"),
36218
36238
  slideId: external_exports.string().describe("Slide ID (object ID of the target slide)"),
@@ -36239,7 +36259,7 @@ function registerExtraSlidesTools(server) {
36239
36259
  });
36240
36260
  server.registerTool("gog_slides_delete_slide", {
36241
36261
  description: "Delete a slide from a Google Slides presentation.",
36242
- annotations: { destructiveHint: true },
36262
+ annotations: { destructiveHint: true, openWorldHint: true },
36243
36263
  inputSchema: external_exports.object({
36244
36264
  presentationId: external_exports.string().describe("Presentation ID"),
36245
36265
  slideId: external_exports.string().describe("Slide ID to delete"),
@@ -36250,7 +36270,7 @@ function registerExtraSlidesTools(server) {
36250
36270
  });
36251
36271
  server.registerTool("gog_slides_skip_slide", {
36252
36272
  description: "Skip a slide during presentation \u2014 it stays in the deck at its current position but is not shown when presenting (and is left out of a PDF export). Use this instead of gog_slides_delete_slide when a slide should be omitted from a talk without losing it. Reverse with gog_slides_unskip_slide; gog_slides_list_slides reports which slides are skipped.",
36253
- annotations: { destructiveHint: false },
36273
+ annotations: { destructiveHint: false, openWorldHint: true },
36254
36274
  inputSchema: external_exports.object({
36255
36275
  presentationId: external_exports.string().describe("Presentation ID"),
36256
36276
  slideId: external_exports.string().describe("Slide ID to skip (from gog_slides_list_slides)"),
@@ -36261,7 +36281,7 @@ function registerExtraSlidesTools(server) {
36261
36281
  });
36262
36282
  server.registerTool("gog_slides_unskip_slide", {
36263
36283
  description: "Include a previously skipped slide again when the deck is presented. Safe to call on a slide that was never skipped.",
36264
- annotations: { destructiveHint: false },
36284
+ annotations: { destructiveHint: false, openWorldHint: true },
36265
36285
  inputSchema: external_exports.object({
36266
36286
  presentationId: external_exports.string().describe("Presentation ID"),
36267
36287
  slideId: external_exports.string().describe("Slide ID to unskip (from gog_slides_list_slides)"),
@@ -36272,7 +36292,7 @@ function registerExtraSlidesTools(server) {
36272
36292
  });
36273
36293
  server.registerTool("gog_slides_update_notes", {
36274
36294
  description: "Update the speaker notes on a slide (inline text or from a file).",
36275
- annotations: { destructiveHint: true },
36295
+ annotations: { destructiveHint: true, openWorldHint: true },
36276
36296
  inputSchema: external_exports.object({
36277
36297
  presentationId: external_exports.string().describe("Presentation ID"),
36278
36298
  slideId: external_exports.string().describe("Slide ID"),
@@ -36289,7 +36309,7 @@ function registerExtraSlidesTools(server) {
36289
36309
  });
36290
36310
  server.registerTool("gog_slides_replace_slide", {
36291
36311
  description: "Replace the image content of an existing slide, from a local file (image) or a public HTTPS URL (url \u2014 no Drive upload or sharing required), with optional speaker notes.",
36292
- annotations: { destructiveHint: true },
36312
+ annotations: { destructiveHint: true, openWorldHint: true },
36293
36313
  inputSchema: external_exports.object({
36294
36314
  presentationId: external_exports.string().describe("Presentation ID"),
36295
36315
  slideId: external_exports.string().describe("Slide ID to replace"),
@@ -36311,7 +36331,7 @@ function registerExtraSlidesTools(server) {
36311
36331
  });
36312
36332
  server.registerTool("gog_slides_raw", {
36313
36333
  description: "Dump the raw Google Slides API response (Presentations.Get) as JSON \u2014 lossless presentation metadata including every page, element, and style. Use gog_slides_read_slide for a friendlier per-slide view.",
36314
- annotations: { readOnlyHint: true },
36334
+ annotations: { readOnlyHint: true, openWorldHint: true },
36315
36335
  inputSchema: external_exports.object({
36316
36336
  presentationId: external_exports.string().describe("Presentation ID"),
36317
36337
  pretty: external_exports.boolean().optional().describe("Pretty-print the JSON (default: compact single line)"),
@@ -36324,7 +36344,7 @@ function registerExtraSlidesTools(server) {
36324
36344
  });
36325
36345
  server.registerTool("gog_slides_locate", {
36326
36346
  description: "Locate literal text in a presentation's shapes and table cells, returning the containing element object IDs and UTF-16 ranges needed for gog_slides_style_text / gog_slides_link / gog_slides_bullets / gog_slides_insert_text. Read-only.",
36327
- annotations: { readOnlyHint: true },
36347
+ annotations: { readOnlyHint: true, openWorldHint: true },
36328
36348
  inputSchema: external_exports.object({
36329
36349
  presentationId: external_exports.string().describe("Presentation ID"),
36330
36350
  text: external_exports.string().describe("Literal text to locate"),
@@ -36347,7 +36367,7 @@ function registerExtraSlidesTools(server) {
36347
36367
  server.registerTool("gog_slides_thumbnail", {
36348
36368
  description: "Get or download a rendered thumbnail image for a single slide.",
36349
36369
  // Writes a file on the gog host and can overwrite one: not read-only (audit SEC-4).
36350
- annotations: { readOnlyHint: false, destructiveHint: true },
36370
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
36351
36371
  inputSchema: external_exports.object({
36352
36372
  presentationId: external_exports.string().describe("Presentation ID"),
36353
36373
  slideId: external_exports.string().describe("Slide object ID"),
@@ -36368,7 +36388,7 @@ function registerExtraSlidesTools(server) {
36368
36388
  });
36369
36389
  server.registerTool("gog_slides_new_slide", {
36370
36390
  description: "Create a new native themed slide with a predefined layout (default BLANK) or an exact presentation layout object ID, at a zero-based insertion index.",
36371
- annotations: { destructiveHint: false },
36391
+ annotations: { destructiveHint: false, openWorldHint: true },
36372
36392
  inputSchema: external_exports.object({
36373
36393
  presentationId: external_exports.string().describe("Presentation ID"),
36374
36394
  layout: external_exports.enum(["BIG_NUMBER", "BLANK", "CAPTION_ONLY", "MAIN_POINT", "ONE_COLUMN_TEXT", "SECTION_HEADER", "SECTION_TITLE_AND_DESCRIPTION", "TITLE", "TITLE_AND_BODY", "TITLE_AND_TWO_COLUMNS", "TITLE_ONLY"]).optional().describe("Predefined slide layout (default: BLANK). Mutually exclusive with layoutId."),
@@ -36385,7 +36405,7 @@ function registerExtraSlidesTools(server) {
36385
36405
  });
36386
36406
  server.registerTool("gog_slides_duplicate_slide", {
36387
36407
  description: "Duplicate a slide by object ID, optionally placing the copy at a zero-based insertion index.",
36388
- annotations: { destructiveHint: false },
36408
+ annotations: { destructiveHint: false, openWorldHint: true },
36389
36409
  inputSchema: external_exports.object({
36390
36410
  presentationId: external_exports.string().describe("Presentation ID"),
36391
36411
  slideId: external_exports.string().describe("Slide object ID to duplicate"),
@@ -36399,7 +36419,7 @@ function registerExtraSlidesTools(server) {
36399
36419
  });
36400
36420
  server.registerTool("gog_slides_move_slide", {
36401
36421
  description: "Move a slide to a zero-based insertion index within the presentation.",
36402
- annotations: { destructiveHint: false },
36422
+ annotations: { destructiveHint: false, openWorldHint: true },
36403
36423
  inputSchema: external_exports.object({
36404
36424
  presentationId: external_exports.string().describe("Presentation ID"),
36405
36425
  slideId: external_exports.string().describe("Slide object ID to move"),
@@ -36411,7 +36431,7 @@ function registerExtraSlidesTools(server) {
36411
36431
  });
36412
36432
  server.registerTool("gog_slides_insert_text", {
36413
36433
  description: "Insert text into an existing page element (shape or table cell) by object ID. Target a table cell with zero-based row + col. Use replace=true to clear the element's existing text first.",
36414
- annotations: { destructiveHint: true },
36434
+ annotations: { destructiveHint: true, openWorldHint: true },
36415
36435
  inputSchema: external_exports.object({
36416
36436
  presentationId: external_exports.string().describe("Presentation ID"),
36417
36437
  objectId: external_exports.string().describe("Object ID of the target shape or table"),
@@ -36432,7 +36452,7 @@ function registerExtraSlidesTools(server) {
36432
36452
  });
36433
36453
  server.registerTool("gog_slides_style_text", {
36434
36454
  description: "Apply range-scoped text styling to one page element. range is a UTF-16 start:end span (use gog_slides_locate to find it). Boolean flags set the attribute; the no* flags clear it.",
36435
- annotations: { destructiveHint: false },
36455
+ annotations: { destructiveHint: false, openWorldHint: true },
36436
36456
  inputSchema: external_exports.object({
36437
36457
  presentationId: external_exports.string().describe("Presentation ID"),
36438
36458
  objectId: external_exports.string().describe("Object ID of the shape or table cell containing the text"),
@@ -36463,7 +36483,7 @@ function registerExtraSlidesTools(server) {
36463
36483
  });
36464
36484
  server.registerTool("gog_slides_link", {
36465
36485
  description: "Apply or clear a hyperlink on a UTF-16 text range in one page element. Provide url to set the link, or clear=true to remove it.",
36466
- annotations: { destructiveHint: false },
36486
+ annotations: { destructiveHint: false, openWorldHint: true },
36467
36487
  inputSchema: external_exports.object({
36468
36488
  presentationId: external_exports.string().describe("Presentation ID"),
36469
36489
  objectId: external_exports.string().describe("Object ID of the shape or table cell containing the text"),
@@ -36480,7 +36500,7 @@ function registerExtraSlidesTools(server) {
36480
36500
  });
36481
36501
  server.registerTool("gog_slides_bullets", {
36482
36502
  description: "Turn paragraph bullets on or off for a UTF-16 paragraph range in one page element. Use on (optionally with a preset glyph) or off.",
36483
- annotations: { destructiveHint: false },
36503
+ annotations: { destructiveHint: false, openWorldHint: true },
36484
36504
  inputSchema: external_exports.object({
36485
36505
  presentationId: external_exports.string().describe("Presentation ID"),
36486
36506
  objectId: external_exports.string().describe("Object ID of the shape or table cell containing the paragraphs"),
@@ -36499,7 +36519,7 @@ function registerExtraSlidesTools(server) {
36499
36519
  });
36500
36520
  server.registerTool("gog_slides_replace_text", {
36501
36521
  description: "Find-and-replace text within an explicit scope. You MUST choose a scope \u2014 restrict to a single shape (object), one or more slides (pages), or the entire presentation (all=true). There is no whole-deck default; gog rejects the call if no scope is given.",
36502
- annotations: { destructiveHint: true },
36522
+ annotations: { destructiveHint: true, openWorldHint: true },
36503
36523
  inputSchema: external_exports.object({
36504
36524
  presentationId: external_exports.string().describe("Presentation ID"),
36505
36525
  find: external_exports.string().describe("Text to find"),
@@ -36520,7 +36540,7 @@ function registerExtraSlidesTools(server) {
36520
36540
  });
36521
36541
  server.registerTool("gog_slides_element_create_shape", {
36522
36542
  description: "Create a native shape on a slide. type is a Slides shape type (e.g. RECTANGLE, TEXT_BOX, ELLIPSE, ROUND_RECTANGLE). Position/size are in unit (default PT).",
36523
- annotations: { destructiveHint: false },
36543
+ annotations: { destructiveHint: false, openWorldHint: true },
36524
36544
  inputSchema: external_exports.object({
36525
36545
  presentationId: external_exports.string().describe("Presentation ID"),
36526
36546
  slideId: external_exports.string().describe("Slide object ID to create the shape on"),
@@ -36546,7 +36566,7 @@ function registerExtraSlidesTools(server) {
36546
36566
  });
36547
36567
  server.registerTool("gog_slides_element_create_line", {
36548
36568
  description: "Create a native line on a slide. category is the connector routing (STRAIGHT, BENT, CURVED). Start position and extent are in unit (default PT).",
36549
- annotations: { destructiveHint: false },
36569
+ annotations: { destructiveHint: false, openWorldHint: true },
36550
36570
  inputSchema: external_exports.object({
36551
36571
  presentationId: external_exports.string().describe("Presentation ID"),
36552
36572
  slideId: external_exports.string().describe("Slide object ID to create the line on"),
@@ -36572,7 +36592,7 @@ function registerExtraSlidesTools(server) {
36572
36592
  });
36573
36593
  server.registerTool("gog_slides_element_style", {
36574
36594
  description: "Style a shape fill/outline or a line. Set kind to shape or line. Colors are #RGB or #RRGGBB.",
36575
- annotations: { destructiveHint: false },
36595
+ annotations: { destructiveHint: false, openWorldHint: true },
36576
36596
  inputSchema: external_exports.object({
36577
36597
  presentationId: external_exports.string().describe("Presentation ID"),
36578
36598
  objectId: external_exports.string().describe("Object ID of the shape or line"),
@@ -36598,7 +36618,7 @@ function registerExtraSlidesTools(server) {
36598
36618
  });
36599
36619
  server.registerTool("gog_slides_element_transform", {
36600
36620
  description: "Move, resize, rotate, or shear a page element. apply-mode RELATIVE (default) composes with the existing transform; ABSOLUTE replaces it. Translation is in unit (default PT).",
36601
- annotations: { destructiveHint: false },
36621
+ annotations: { destructiveHint: false, openWorldHint: true },
36602
36622
  inputSchema: external_exports.object({
36603
36623
  presentationId: external_exports.string().describe("Presentation ID"),
36604
36624
  objectId: external_exports.string().describe("Object ID of the element to transform"),
@@ -36628,7 +36648,7 @@ function registerExtraSlidesTools(server) {
36628
36648
  });
36629
36649
  server.registerTool("gog_slides_element_z_order", {
36630
36650
  description: "Change a page element's stacking order.",
36631
- annotations: { destructiveHint: false },
36651
+ annotations: { destructiveHint: false, openWorldHint: true },
36632
36652
  inputSchema: external_exports.object({
36633
36653
  presentationId: external_exports.string().describe("Presentation ID"),
36634
36654
  objectId: external_exports.string().describe("Object ID of the element to restack"),
@@ -36640,7 +36660,7 @@ function registerExtraSlidesTools(server) {
36640
36660
  });
36641
36661
  server.registerTool("gog_slides_element_group", {
36642
36662
  description: "Group two or more page elements into a single group.",
36643
- annotations: { destructiveHint: false },
36663
+ annotations: { destructiveHint: false, openWorldHint: true },
36644
36664
  inputSchema: external_exports.object({
36645
36665
  presentationId: external_exports.string().describe("Presentation ID"),
36646
36666
  objectIds: external_exports.array(external_exports.string()).min(2).describe("Two or more element object IDs to group"),
@@ -36654,7 +36674,7 @@ function registerExtraSlidesTools(server) {
36654
36674
  });
36655
36675
  server.registerTool("gog_slides_element_ungroup", {
36656
36676
  description: "Ungroup one or more element groups back into their constituent elements.",
36657
- annotations: { destructiveHint: false },
36677
+ annotations: { destructiveHint: false, openWorldHint: true },
36658
36678
  inputSchema: external_exports.object({
36659
36679
  presentationId: external_exports.string().describe("Presentation ID"),
36660
36680
  groupIds: external_exports.array(external_exports.string()).min(1).describe("One or more group object IDs to ungroup"),
@@ -36665,7 +36685,7 @@ function registerExtraSlidesTools(server) {
36665
36685
  });
36666
36686
  server.registerTool("gog_slides_element_alt_text", {
36667
36687
  description: "Set or clear a page element's accessibility title and/or description. Pass an empty string to clear a field.",
36668
- annotations: { destructiveHint: false },
36688
+ annotations: { destructiveHint: false, openWorldHint: true },
36669
36689
  inputSchema: external_exports.object({
36670
36690
  presentationId: external_exports.string().describe("Presentation ID"),
36671
36691
  objectId: external_exports.string().describe("Object ID of the element"),
@@ -36681,7 +36701,7 @@ function registerExtraSlidesTools(server) {
36681
36701
  });
36682
36702
  server.registerTool("gog_slides_element_delete", {
36683
36703
  description: "Delete one page element by object ID.",
36684
- annotations: { destructiveHint: true },
36704
+ annotations: { destructiveHint: true, openWorldHint: true },
36685
36705
  inputSchema: external_exports.object({
36686
36706
  presentationId: external_exports.string().describe("Presentation ID"),
36687
36707
  objectId: external_exports.string().describe("Object ID of the element to delete"),
@@ -36692,7 +36712,7 @@ function registerExtraSlidesTools(server) {
36692
36712
  });
36693
36713
  server.registerTool("gog_slides_table_create", {
36694
36714
  description: "Create an auto-sized native table on a slide with the given row and column counts.",
36695
- annotations: { destructiveHint: false },
36715
+ annotations: { destructiveHint: false, openWorldHint: true },
36696
36716
  inputSchema: external_exports.object({
36697
36717
  presentationId: external_exports.string().describe("Presentation ID"),
36698
36718
  slideId: external_exports.string().describe("Slide object ID to create the table on"),
@@ -36708,7 +36728,7 @@ function registerExtraSlidesTools(server) {
36708
36728
  });
36709
36729
  server.registerTool("gog_slides_table_cell_style", {
36710
36730
  description: "Style one zero-based table cell: background fill, vertical content alignment, and inline text styling (optionally scoped to a UTF-16 range within the cell). Boolean flags set the attribute; the no* flags clear it.",
36711
- annotations: { destructiveHint: false },
36731
+ annotations: { destructiveHint: false, openWorldHint: true },
36712
36732
  inputSchema: external_exports.object({
36713
36733
  presentationId: external_exports.string().describe("Presentation ID"),
36714
36734
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36748,7 +36768,7 @@ function registerExtraSlidesTools(server) {
36748
36768
  });
36749
36769
  server.registerTool("gog_slides_table_border_style", {
36750
36770
  description: "Style borders around or within a zero-based table cell range. position selects which borders are affected; dash sets the line style.",
36751
- annotations: { destructiveHint: false },
36771
+ annotations: { destructiveHint: false, openWorldHint: true },
36752
36772
  inputSchema: external_exports.object({
36753
36773
  presentationId: external_exports.string().describe("Presentation ID"),
36754
36774
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36776,7 +36796,7 @@ function registerExtraSlidesTools(server) {
36776
36796
  });
36777
36797
  server.registerTool("gog_slides_table_column_insert", {
36778
36798
  description: "Insert one or more columns relative to a zero-based table column. Inserts to the left by default, or to the right with right=true.",
36779
- annotations: { destructiveHint: false },
36799
+ annotations: { destructiveHint: false, openWorldHint: true },
36780
36800
  inputSchema: external_exports.object({
36781
36801
  presentationId: external_exports.string().describe("Presentation ID"),
36782
36802
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36793,7 +36813,7 @@ function registerExtraSlidesTools(server) {
36793
36813
  });
36794
36814
  server.registerTool("gog_slides_table_column_delete", {
36795
36815
  description: "Delete the column containing a zero-based table cell.",
36796
- annotations: { destructiveHint: true },
36816
+ annotations: { destructiveHint: true, openWorldHint: true },
36797
36817
  inputSchema: external_exports.object({
36798
36818
  presentationId: external_exports.string().describe("Presentation ID"),
36799
36819
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36805,7 +36825,7 @@ function registerExtraSlidesTools(server) {
36805
36825
  });
36806
36826
  server.registerTool("gog_slides_table_column_size", {
36807
36827
  description: "Set the width of a zero-based table column.",
36808
- annotations: { destructiveHint: false },
36828
+ annotations: { destructiveHint: false, openWorldHint: true },
36809
36829
  inputSchema: external_exports.object({
36810
36830
  presentationId: external_exports.string().describe("Presentation ID"),
36811
36831
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36818,7 +36838,7 @@ function registerExtraSlidesTools(server) {
36818
36838
  });
36819
36839
  server.registerTool("gog_slides_table_row_insert", {
36820
36840
  description: "Insert one or more rows relative to a zero-based table row. Inserts above by default, or below with below=true.",
36821
- annotations: { destructiveHint: false },
36841
+ annotations: { destructiveHint: false, openWorldHint: true },
36822
36842
  inputSchema: external_exports.object({
36823
36843
  presentationId: external_exports.string().describe("Presentation ID"),
36824
36844
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36835,7 +36855,7 @@ function registerExtraSlidesTools(server) {
36835
36855
  });
36836
36856
  server.registerTool("gog_slides_table_row_delete", {
36837
36857
  description: "Delete the row containing a zero-based table cell.",
36838
- annotations: { destructiveHint: true },
36858
+ annotations: { destructiveHint: true, openWorldHint: true },
36839
36859
  inputSchema: external_exports.object({
36840
36860
  presentationId: external_exports.string().describe("Presentation ID"),
36841
36861
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36847,7 +36867,7 @@ function registerExtraSlidesTools(server) {
36847
36867
  });
36848
36868
  server.registerTool("gog_slides_table_row_size", {
36849
36869
  description: "Set the minimum height of a zero-based table row.",
36850
- annotations: { destructiveHint: false },
36870
+ annotations: { destructiveHint: false, openWorldHint: true },
36851
36871
  inputSchema: external_exports.object({
36852
36872
  presentationId: external_exports.string().describe("Presentation ID"),
36853
36873
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36860,7 +36880,7 @@ function registerExtraSlidesTools(server) {
36860
36880
  });
36861
36881
  server.registerTool("gog_slides_table_merge", {
36862
36882
  description: "Merge a rectangular table cell range starting at a zero-based cell. Content of non-anchor cells is absorbed by the merge; use gog_slides_table_unmerge to split back.",
36863
- annotations: { destructiveHint: true },
36883
+ annotations: { destructiveHint: true, openWorldHint: true },
36864
36884
  inputSchema: external_exports.object({
36865
36885
  presentationId: external_exports.string().describe("Presentation ID"),
36866
36886
  tableObjectId: external_exports.string().describe("Table object ID"),
@@ -36878,7 +36898,7 @@ function registerExtraSlidesTools(server) {
36878
36898
  });
36879
36899
  server.registerTool("gog_slides_table_unmerge", {
36880
36900
  description: "Unmerge (split) a rectangular range of previously merged cells, starting at a zero-based cell.",
36881
- annotations: { destructiveHint: false },
36901
+ annotations: { destructiveHint: false, openWorldHint: true },
36882
36902
  inputSchema: external_exports.object({
36883
36903
  presentationId: external_exports.string().describe("Presentation ID"),
36884
36904
  tableObjectId: external_exports.string().describe("Table object ID"),
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-slides",
5
5
  "display_name": "gogcli (Slides)",
6
- "version": "4.7.0",
6
+ "version": "4.8.0",
7
7
  "description": "Extended Google Slides for Claude via gogcli — auth + full Slides support (create, edit, export, templates, markdown)",
8
8
  "author": {
9
9
  "name": "Chris Hall",
@@ -39,7 +39,10 @@
39
39
  "env": {
40
40
  "GOG_ACCOUNT": "${user_config.gog_account}",
41
41
  "GOG_PATH": "${user_config.gog_path}",
42
- "GOG_FILE_ROOTS": "${user_config.gog_file_roots}"
42
+ "GOG_FILE_ROOTS": "${user_config.gog_file_roots}",
43
+ "DISPLAY_TZ": "${user_config.display_tz}",
44
+ "GOG_READONLY": "${user_config.gog_readonly}",
45
+ "GOG_TIMEZONE": "${user_config.gog_timezone}"
43
46
  }
44
47
  }
45
48
  },
@@ -61,6 +64,24 @@
61
64
  "title": "Allowed file directories",
62
65
  "description": "Directories tools may read files from (attachments, uploads) or write files to (exports, downloads), separated by ':' (';' on Windows). Optional — defaults to ~/gogcli-mcp-files",
63
66
  "required": false
67
+ },
68
+ "display_tz": {
69
+ "type": "string",
70
+ "title": "Display time zone",
71
+ "description": "zone for *Display fields and for interpreting naive gog values; defaults to America/New_York",
72
+ "required": false
73
+ },
74
+ "gog_readonly": {
75
+ "type": "string",
76
+ "title": "Read-only mode",
77
+ "description": "block all mutating gog API requests (injects gog's --readonly); set to 0/false/no/off (or unset) to allow writes",
78
+ "required": false
79
+ },
80
+ "gog_timezone": {
81
+ "type": "string",
82
+ "title": "gog time zone",
83
+ "description": "zone gog formats naive dates in; unset, runner.ts hands gog DISPLAY_TZ so the two cannot diverge",
84
+ "required": false
64
85
  }
65
86
  },
66
87
  "tools": [
package/mint.yaml CHANGED
@@ -91,7 +91,7 @@ dependencies:
91
91
  # bumping these nine pins, and the pin stored on each mcp-host registration.
92
92
  - kind: github-release
93
93
  repo: openclaw/gogcli
94
- tag: v0.43.0
94
+ tag: v0.44.0
95
95
  asset: "gogcli_*_linux_amd64.tar.gz"
96
96
  bin: [gog]
97
97
  state:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-slides",
3
- "version": "4.7.0",
3
+ "version": "4.8.0",
4
4
  "mcpName": "io.github.chrischall/gogcli-mcp-slides",
5
5
  "description": "Extended Google Slides MCP server via gogcli — auth + full Slides support",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -24,8 +24,8 @@
24
24
  "test:coverage": "vitest run --coverage"
25
25
  },
26
26
  "dependencies": {
27
- "@chrischall/mcp-utils": "^2.15.0",
28
- "@modelcontextprotocol/server": "^2.3.0",
27
+ "@chrischall/mcp-utils": "^3.0.0",
28
+ "@modelcontextprotocol/server": "^2.3.1",
29
29
  "zod": "^4.6.1"
30
30
  },
31
31
  "license": "MIT",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "source": "github",
8
8
  "subfolder": "packages/gogcli-mcp-slides"
9
9
  },
10
- "version": "4.7.0",
10
+ "version": "4.8.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-slides",
15
- "version": "4.7.0",
15
+ "version": "4.8.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },
@@ -28,6 +28,24 @@
28
28
  "description": "Override path to the gogcli binary (auto-discovered otherwise)",
29
29
  "isRequired": false,
30
30
  "format": "string"
31
+ },
32
+ {
33
+ "name": "DISPLAY_TZ",
34
+ "description": "zone for *Display fields and for interpreting naive gog values; defaults to America/New_York",
35
+ "isRequired": false,
36
+ "format": "string"
37
+ },
38
+ {
39
+ "name": "GOG_READONLY",
40
+ "description": "block all mutating gog API requests (injects gog's --readonly); set to 0/false/no/off (or unset) to allow writes",
41
+ "isRequired": false,
42
+ "format": "string"
43
+ },
44
+ {
45
+ "name": "GOG_TIMEZONE",
46
+ "description": "zone gog formats naive dates in; unset, runner.ts hands gog DISPLAY_TZ so the two cannot diverge",
47
+ "isRequired": false,
48
+ "format": "string"
31
49
  }
32
50
  ]
33
51
  }
@@ -27,7 +27,7 @@ import type { GogArg } from '../../../gogcli-mcp/src/lib.js';
27
27
  export function registerExtraSlidesTools(server: McpServer): void {
28
28
  server.registerTool('gog_slides_create_from_markdown', {
29
29
  description: 'Create a new Google Slides presentation from markdown content (inline or from a file).',
30
- annotations: { destructiveHint: true },
30
+ annotations: { destructiveHint: true, openWorldHint: true },
31
31
  inputSchema: z.object({
32
32
  title: z.string().describe('Presentation title'),
33
33
  content: z.string().optional().describe('Inline markdown content'),
@@ -48,7 +48,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
48
48
 
49
49
  server.registerTool('gog_slides_create_from_template', {
50
50
  description: 'Create a new Google Slides presentation from a template, with optional placeholder replacements.',
51
- annotations: { destructiveHint: true },
51
+ annotations: { destructiveHint: true, openWorldHint: true },
52
52
  inputSchema: z.object({
53
53
  templateId: z.string().describe('Template presentation ID'),
54
54
  title: z.string().describe('New presentation title'),
@@ -74,7 +74,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
74
74
 
75
75
  server.registerTool('gog_slides_add_slide', {
76
76
  description: 'Add a new slide to a presentation from a local image, with optional speaker notes.',
77
- annotations: { destructiveHint: true },
77
+ annotations: { destructiveHint: true, openWorldHint: true },
78
78
  inputSchema: z.object({
79
79
  presentationId: z.string().describe('Presentation ID'),
80
80
  image: z.string().describe('Path to the local image file'),
@@ -95,7 +95,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
95
95
 
96
96
  server.registerTool('gog_slides_insert_image', {
97
97
  description: 'Place an image on an existing slide at a given size and position, from a local file (image) or a public HTTPS URL (url — no Drive upload or sharing required). Unlike gog_slides_add_slide (which creates a new full-bleed image slide), this inserts onto a slide you already have. width is required; omit height to keep aspect ratio when using a local file (gog requires both width and height when using url).',
98
- annotations: { destructiveHint: false },
98
+ annotations: { destructiveHint: false, openWorldHint: true },
99
99
  inputSchema: z.object({
100
100
  presentationId: z.string().describe('Presentation ID'),
101
101
  slideId: z.string().describe('Slide ID (object ID of the target slide)'),
@@ -123,7 +123,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
123
123
 
124
124
  server.registerTool('gog_slides_delete_slide', {
125
125
  description: 'Delete a slide from a Google Slides presentation.',
126
- annotations: { destructiveHint: true },
126
+ annotations: { destructiveHint: true, openWorldHint: true },
127
127
  inputSchema: z.object({
128
128
  presentationId: z.string().describe('Presentation ID'),
129
129
  slideId: z.string().describe('Slide ID to delete'),
@@ -147,7 +147,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
147
147
  'Skip a slide during presentation — it stays in the deck at its current position but is not shown when presenting '
148
148
  + '(and is left out of a PDF export). Use this instead of gog_slides_delete_slide when a slide should be omitted from '
149
149
  + 'a talk without losing it. Reverse with gog_slides_unskip_slide; gog_slides_list_slides reports which slides are skipped.',
150
- annotations: { destructiveHint: false },
150
+ annotations: { destructiveHint: false, openWorldHint: true },
151
151
  inputSchema: z.object({
152
152
  presentationId: z.string().describe('Presentation ID'),
153
153
  slideId: z.string().describe('Slide ID to skip (from gog_slides_list_slides)'),
@@ -160,7 +160,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
160
160
  server.registerTool('gog_slides_unskip_slide', {
161
161
  description:
162
162
  'Include a previously skipped slide again when the deck is presented. Safe to call on a slide that was never skipped.',
163
- annotations: { destructiveHint: false },
163
+ annotations: { destructiveHint: false, openWorldHint: true },
164
164
  inputSchema: z.object({
165
165
  presentationId: z.string().describe('Presentation ID'),
166
166
  slideId: z.string().describe('Slide ID to unskip (from gog_slides_list_slides)'),
@@ -172,7 +172,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
172
172
 
173
173
  server.registerTool('gog_slides_update_notes', {
174
174
  description: 'Update the speaker notes on a slide (inline text or from a file).',
175
- annotations: { destructiveHint: true },
175
+ annotations: { destructiveHint: true, openWorldHint: true },
176
176
  inputSchema: z.object({
177
177
  presentationId: z.string().describe('Presentation ID'),
178
178
  slideId: z.string().describe('Slide ID'),
@@ -190,7 +190,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
190
190
 
191
191
  server.registerTool('gog_slides_replace_slide', {
192
192
  description: 'Replace the image content of an existing slide, from a local file (image) or a public HTTPS URL (url — no Drive upload or sharing required), with optional speaker notes.',
193
- annotations: { destructiveHint: true },
193
+ annotations: { destructiveHint: true, openWorldHint: true },
194
194
  inputSchema: z.object({
195
195
  presentationId: z.string().describe('Presentation ID'),
196
196
  slideId: z.string().describe('Slide ID to replace'),
@@ -215,7 +215,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
215
215
 
216
216
  server.registerTool('gog_slides_raw', {
217
217
  description: 'Dump the raw Google Slides API response (Presentations.Get) as JSON — lossless presentation metadata including every page, element, and style. Use gog_slides_read_slide for a friendlier per-slide view.',
218
- annotations: { readOnlyHint: true },
218
+ annotations: { readOnlyHint: true, openWorldHint: true },
219
219
  inputSchema: z.object({
220
220
  presentationId: z.string().describe('Presentation ID'),
221
221
  pretty: z.boolean().optional().describe('Pretty-print the JSON (default: compact single line)'),
@@ -230,7 +230,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
230
230
 
231
231
  server.registerTool('gog_slides_locate', {
232
232
  description: 'Locate literal text in a presentation\'s shapes and table cells, returning the containing element object IDs and UTF-16 ranges needed for gog_slides_style_text / gog_slides_link / gog_slides_bullets / gog_slides_insert_text. Read-only.',
233
- annotations: { readOnlyHint: true },
233
+ annotations: { readOnlyHint: true, openWorldHint: true },
234
234
  inputSchema: z.object({
235
235
  presentationId: z.string().describe('Presentation ID'),
236
236
  text: z.string().describe('Literal text to locate'),
@@ -254,7 +254,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
254
254
  server.registerTool('gog_slides_thumbnail', {
255
255
  description: 'Get or download a rendered thumbnail image for a single slide.',
256
256
  // Writes a file on the gog host and can overwrite one: not read-only (audit SEC-4).
257
- annotations: { readOnlyHint: false, destructiveHint: true },
257
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
258
258
  inputSchema: z.object({
259
259
  presentationId: z.string().describe('Presentation ID'),
260
260
  slideId: z.string().describe('Slide object ID'),
@@ -278,7 +278,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
278
278
 
279
279
  server.registerTool('gog_slides_new_slide', {
280
280
  description: 'Create a new native themed slide with a predefined layout (default BLANK) or an exact presentation layout object ID, at a zero-based insertion index.',
281
- annotations: { destructiveHint: false },
281
+ annotations: { destructiveHint: false, openWorldHint: true },
282
282
  inputSchema: z.object({
283
283
  presentationId: z.string().describe('Presentation ID'),
284
284
  layout: z.enum(['BIG_NUMBER', 'BLANK', 'CAPTION_ONLY', 'MAIN_POINT', 'ONE_COLUMN_TEXT', 'SECTION_HEADER', 'SECTION_TITLE_AND_DESCRIPTION', 'TITLE', 'TITLE_AND_BODY', 'TITLE_AND_TWO_COLUMNS', 'TITLE_ONLY']).optional().describe('Predefined slide layout (default: BLANK). Mutually exclusive with layoutId.'),
@@ -296,7 +296,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
296
296
 
297
297
  server.registerTool('gog_slides_duplicate_slide', {
298
298
  description: 'Duplicate a slide by object ID, optionally placing the copy at a zero-based insertion index.',
299
- annotations: { destructiveHint: false },
299
+ annotations: { destructiveHint: false, openWorldHint: true },
300
300
  inputSchema: z.object({
301
301
  presentationId: z.string().describe('Presentation ID'),
302
302
  slideId: z.string().describe('Slide object ID to duplicate'),
@@ -311,7 +311,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
311
311
 
312
312
  server.registerTool('gog_slides_move_slide', {
313
313
  description: 'Move a slide to a zero-based insertion index within the presentation.',
314
- annotations: { destructiveHint: false },
314
+ annotations: { destructiveHint: false, openWorldHint: true },
315
315
  inputSchema: z.object({
316
316
  presentationId: z.string().describe('Presentation ID'),
317
317
  slideId: z.string().describe('Slide object ID to move'),
@@ -326,7 +326,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
326
326
 
327
327
  server.registerTool('gog_slides_insert_text', {
328
328
  description: 'Insert text into an existing page element (shape or table cell) by object ID. Target a table cell with zero-based row + col. Use replace=true to clear the element\'s existing text first.',
329
- annotations: { destructiveHint: true },
329
+ annotations: { destructiveHint: true, openWorldHint: true },
330
330
  inputSchema: z.object({
331
331
  presentationId: z.string().describe('Presentation ID'),
332
332
  objectId: z.string().describe('Object ID of the target shape or table'),
@@ -348,7 +348,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
348
348
 
349
349
  server.registerTool('gog_slides_style_text', {
350
350
  description: 'Apply range-scoped text styling to one page element. range is a UTF-16 start:end span (use gog_slides_locate to find it). Boolean flags set the attribute; the no* flags clear it.',
351
- annotations: { destructiveHint: false },
351
+ annotations: { destructiveHint: false, openWorldHint: true },
352
352
  inputSchema: z.object({
353
353
  presentationId: z.string().describe('Presentation ID'),
354
354
  objectId: z.string().describe('Object ID of the shape or table cell containing the text'),
@@ -380,7 +380,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
380
380
 
381
381
  server.registerTool('gog_slides_link', {
382
382
  description: 'Apply or clear a hyperlink on a UTF-16 text range in one page element. Provide url to set the link, or clear=true to remove it.',
383
- annotations: { destructiveHint: false },
383
+ annotations: { destructiveHint: false, openWorldHint: true },
384
384
  inputSchema: z.object({
385
385
  presentationId: z.string().describe('Presentation ID'),
386
386
  objectId: z.string().describe('Object ID of the shape or table cell containing the text'),
@@ -398,7 +398,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
398
398
 
399
399
  server.registerTool('gog_slides_bullets', {
400
400
  description: 'Turn paragraph bullets on or off for a UTF-16 paragraph range in one page element. Use on (optionally with a preset glyph) or off.',
401
- annotations: { destructiveHint: false },
401
+ annotations: { destructiveHint: false, openWorldHint: true },
402
402
  inputSchema: z.object({
403
403
  presentationId: z.string().describe('Presentation ID'),
404
404
  objectId: z.string().describe('Object ID of the shape or table cell containing the paragraphs'),
@@ -418,7 +418,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
418
418
 
419
419
  server.registerTool('gog_slides_replace_text', {
420
420
  description: 'Find-and-replace text within an explicit scope. You MUST choose a scope — restrict to a single shape (object), one or more slides (pages), or the entire presentation (all=true). There is no whole-deck default; gog rejects the call if no scope is given.',
421
- annotations: { destructiveHint: true },
421
+ annotations: { destructiveHint: true, openWorldHint: true },
422
422
  inputSchema: z.object({
423
423
  presentationId: z.string().describe('Presentation ID'),
424
424
  find: z.string().describe('Text to find'),
@@ -442,7 +442,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
442
442
 
443
443
  server.registerTool('gog_slides_element_create_shape', {
444
444
  description: 'Create a native shape on a slide. type is a Slides shape type (e.g. RECTANGLE, TEXT_BOX, ELLIPSE, ROUND_RECTANGLE). Position/size are in unit (default PT).',
445
- annotations: { destructiveHint: false },
445
+ annotations: { destructiveHint: false, openWorldHint: true },
446
446
  inputSchema: z.object({
447
447
  presentationId: z.string().describe('Presentation ID'),
448
448
  slideId: z.string().describe('Slide object ID to create the shape on'),
@@ -469,7 +469,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
469
469
 
470
470
  server.registerTool('gog_slides_element_create_line', {
471
471
  description: 'Create a native line on a slide. category is the connector routing (STRAIGHT, BENT, CURVED). Start position and extent are in unit (default PT).',
472
- annotations: { destructiveHint: false },
472
+ annotations: { destructiveHint: false, openWorldHint: true },
473
473
  inputSchema: z.object({
474
474
  presentationId: z.string().describe('Presentation ID'),
475
475
  slideId: z.string().describe('Slide object ID to create the line on'),
@@ -496,7 +496,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
496
496
 
497
497
  server.registerTool('gog_slides_element_style', {
498
498
  description: 'Style a shape fill/outline or a line. Set kind to shape or line. Colors are #RGB or #RRGGBB.',
499
- annotations: { destructiveHint: false },
499
+ annotations: { destructiveHint: false, openWorldHint: true },
500
500
  inputSchema: z.object({
501
501
  presentationId: z.string().describe('Presentation ID'),
502
502
  objectId: z.string().describe('Object ID of the shape or line'),
@@ -523,7 +523,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
523
523
 
524
524
  server.registerTool('gog_slides_element_transform', {
525
525
  description: 'Move, resize, rotate, or shear a page element. apply-mode RELATIVE (default) composes with the existing transform; ABSOLUTE replaces it. Translation is in unit (default PT).',
526
- annotations: { destructiveHint: false },
526
+ annotations: { destructiveHint: false, openWorldHint: true },
527
527
  inputSchema: z.object({
528
528
  presentationId: z.string().describe('Presentation ID'),
529
529
  objectId: z.string().describe('Object ID of the element to transform'),
@@ -554,7 +554,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
554
554
 
555
555
  server.registerTool('gog_slides_element_z_order', {
556
556
  description: 'Change a page element\'s stacking order.',
557
- annotations: { destructiveHint: false },
557
+ annotations: { destructiveHint: false, openWorldHint: true },
558
558
  inputSchema: z.object({
559
559
  presentationId: z.string().describe('Presentation ID'),
560
560
  objectId: z.string().describe('Object ID of the element to restack'),
@@ -567,7 +567,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
567
567
 
568
568
  server.registerTool('gog_slides_element_group', {
569
569
  description: 'Group two or more page elements into a single group.',
570
- annotations: { destructiveHint: false },
570
+ annotations: { destructiveHint: false, openWorldHint: true },
571
571
  inputSchema: z.object({
572
572
  presentationId: z.string().describe('Presentation ID'),
573
573
  objectIds: z.array(z.string()).min(2).describe('Two or more element object IDs to group'),
@@ -582,7 +582,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
582
582
 
583
583
  server.registerTool('gog_slides_element_ungroup', {
584
584
  description: 'Ungroup one or more element groups back into their constituent elements.',
585
- annotations: { destructiveHint: false },
585
+ annotations: { destructiveHint: false, openWorldHint: true },
586
586
  inputSchema: z.object({
587
587
  presentationId: z.string().describe('Presentation ID'),
588
588
  groupIds: z.array(z.string()).min(1).describe('One or more group object IDs to ungroup'),
@@ -594,7 +594,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
594
594
 
595
595
  server.registerTool('gog_slides_element_alt_text', {
596
596
  description: 'Set or clear a page element\'s accessibility title and/or description. Pass an empty string to clear a field.',
597
- annotations: { destructiveHint: false },
597
+ annotations: { destructiveHint: false, openWorldHint: true },
598
598
  inputSchema: z.object({
599
599
  presentationId: z.string().describe('Presentation ID'),
600
600
  objectId: z.string().describe('Object ID of the element'),
@@ -611,7 +611,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
611
611
 
612
612
  server.registerTool('gog_slides_element_delete', {
613
613
  description: 'Delete one page element by object ID.',
614
- annotations: { destructiveHint: true },
614
+ annotations: { destructiveHint: true, openWorldHint: true },
615
615
  inputSchema: z.object({
616
616
  presentationId: z.string().describe('Presentation ID'),
617
617
  objectId: z.string().describe('Object ID of the element to delete'),
@@ -626,7 +626,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
626
626
 
627
627
  server.registerTool('gog_slides_table_create', {
628
628
  description: 'Create an auto-sized native table on a slide with the given row and column counts.',
629
- annotations: { destructiveHint: false },
629
+ annotations: { destructiveHint: false, openWorldHint: true },
630
630
  inputSchema: z.object({
631
631
  presentationId: z.string().describe('Presentation ID'),
632
632
  slideId: z.string().describe('Slide object ID to create the table on'),
@@ -643,7 +643,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
643
643
 
644
644
  server.registerTool('gog_slides_table_cell_style', {
645
645
  description: 'Style one zero-based table cell: background fill, vertical content alignment, and inline text styling (optionally scoped to a UTF-16 range within the cell). Boolean flags set the attribute; the no* flags clear it.',
646
- annotations: { destructiveHint: false },
646
+ annotations: { destructiveHint: false, openWorldHint: true },
647
647
  inputSchema: z.object({
648
648
  presentationId: z.string().describe('Presentation ID'),
649
649
  tableObjectId: z.string().describe('Table object ID'),
@@ -684,7 +684,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
684
684
 
685
685
  server.registerTool('gog_slides_table_border_style', {
686
686
  description: 'Style borders around or within a zero-based table cell range. position selects which borders are affected; dash sets the line style.',
687
- annotations: { destructiveHint: false },
687
+ annotations: { destructiveHint: false, openWorldHint: true },
688
688
  inputSchema: z.object({
689
689
  presentationId: z.string().describe('Presentation ID'),
690
690
  tableObjectId: z.string().describe('Table object ID'),
@@ -713,7 +713,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
713
713
 
714
714
  server.registerTool('gog_slides_table_column_insert', {
715
715
  description: 'Insert one or more columns relative to a zero-based table column. Inserts to the left by default, or to the right with right=true.',
716
- annotations: { destructiveHint: false },
716
+ annotations: { destructiveHint: false, openWorldHint: true },
717
717
  inputSchema: z.object({
718
718
  presentationId: z.string().describe('Presentation ID'),
719
719
  tableObjectId: z.string().describe('Table object ID'),
@@ -731,7 +731,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
731
731
 
732
732
  server.registerTool('gog_slides_table_column_delete', {
733
733
  description: 'Delete the column containing a zero-based table cell.',
734
- annotations: { destructiveHint: true },
734
+ annotations: { destructiveHint: true, openWorldHint: true },
735
735
  inputSchema: z.object({
736
736
  presentationId: z.string().describe('Presentation ID'),
737
737
  tableObjectId: z.string().describe('Table object ID'),
@@ -744,7 +744,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
744
744
 
745
745
  server.registerTool('gog_slides_table_column_size', {
746
746
  description: 'Set the width of a zero-based table column.',
747
- annotations: { destructiveHint: false },
747
+ annotations: { destructiveHint: false, openWorldHint: true },
748
748
  inputSchema: z.object({
749
749
  presentationId: z.string().describe('Presentation ID'),
750
750
  tableObjectId: z.string().describe('Table object ID'),
@@ -758,7 +758,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
758
758
 
759
759
  server.registerTool('gog_slides_table_row_insert', {
760
760
  description: 'Insert one or more rows relative to a zero-based table row. Inserts above by default, or below with below=true.',
761
- annotations: { destructiveHint: false },
761
+ annotations: { destructiveHint: false, openWorldHint: true },
762
762
  inputSchema: z.object({
763
763
  presentationId: z.string().describe('Presentation ID'),
764
764
  tableObjectId: z.string().describe('Table object ID'),
@@ -776,7 +776,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
776
776
 
777
777
  server.registerTool('gog_slides_table_row_delete', {
778
778
  description: 'Delete the row containing a zero-based table cell.',
779
- annotations: { destructiveHint: true },
779
+ annotations: { destructiveHint: true, openWorldHint: true },
780
780
  inputSchema: z.object({
781
781
  presentationId: z.string().describe('Presentation ID'),
782
782
  tableObjectId: z.string().describe('Table object ID'),
@@ -789,7 +789,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
789
789
 
790
790
  server.registerTool('gog_slides_table_row_size', {
791
791
  description: 'Set the minimum height of a zero-based table row.',
792
- annotations: { destructiveHint: false },
792
+ annotations: { destructiveHint: false, openWorldHint: true },
793
793
  inputSchema: z.object({
794
794
  presentationId: z.string().describe('Presentation ID'),
795
795
  tableObjectId: z.string().describe('Table object ID'),
@@ -803,7 +803,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
803
803
 
804
804
  server.registerTool('gog_slides_table_merge', {
805
805
  description: 'Merge a rectangular table cell range starting at a zero-based cell. Content of non-anchor cells is absorbed by the merge; use gog_slides_table_unmerge to split back.',
806
- annotations: { destructiveHint: true },
806
+ annotations: { destructiveHint: true, openWorldHint: true },
807
807
  inputSchema: z.object({
808
808
  presentationId: z.string().describe('Presentation ID'),
809
809
  tableObjectId: z.string().describe('Table object ID'),
@@ -822,7 +822,7 @@ export function registerExtraSlidesTools(server: McpServer): void {
822
822
 
823
823
  server.registerTool('gog_slides_table_unmerge', {
824
824
  description: 'Unmerge (split) a rectangular range of previously merged cells, starting at a zero-based cell.',
825
- annotations: { destructiveHint: false },
825
+ annotations: { destructiveHint: false, openWorldHint: true },
826
826
  inputSchema: z.object({
827
827
  presentationId: z.string().describe('Presentation ID'),
828
828
  tableObjectId: z.string().describe('Table object ID'),
@@ -0,0 +1,10 @@
1
+ import { authToolsFor, registerSlidesTools } from '../../gogcli-mcp/src/lib.js';
2
+ import { registerExtraSlidesTools } from '../src/tools/slides-extra.js';
3
+ import { describeToolAnnotations, LOCAL_AUTH_TOOLS } from '../../gogcli-mcp/tests/support/tool-annotations.js';
4
+
5
+ // The same registrar list src/index.ts hands to runMcp.
6
+ describeToolAnnotations([authToolsFor('slides'), registerSlidesTools, registerExtraSlidesTools] as never, {
7
+ tools: 55,
8
+ destructive: 20,
9
+ local: [...LOCAL_AUTH_TOOLS],
10
+ });