Skip to main content
Glama

Share a local app, file or folder

share

Expose a local file, directory, or HTTP port over Tailscale for access from other devices; optionally publish publicly through Funnel with explicit acknowledgement and time limits.

Instructions

Setting funnel true on this tool publishes the target to the entire public internet, so ask the user before doing that; with funnel false (the default) it exposes a local directory, one file, or an HTTP port only on the user's private Tailscale network. A directory target serves every file under it and is browsable; a regular-file target serves only that file and answers 404 for its siblings. New gateway apps admit the owner/admins and explicit grants; existing installations retain their mode. Human allow recipients use membership verification and necessary device invitations; incomplete setup returns an error with saved progress. A recipient allowed here has no expiry unless for or until limits it (people_add defaults to 24h); a binding that expires gets a 24h default, never a permanent grant. Use this after creating a local page or report that the user wants to open on another tailnet device. If status is needs_login, open auth_url in a browser and retry after authorization.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "target": "<target>"
    },
    "name": "share"
  }
}

Input Schema

NameRequiredDescriptionDefault
forNoLimit human allow recipients to this lifetime (descending unique units w,d,h,m,s,ms,us,ns) or until <RFC3339|YYYY-MM-DD|YYYY-MM-DDTHH:MM>. Local unless offset given; DST gaps/folds require an offset. Minimum 1h. Presets: 1h, 8h, 24h, 3d, 7d. Omitted: a recipient this call newly allows has no expiry and an existing grant keeps its deadline; a binding that expires or cannot create permanent grants gets 24h. Explicit never requires ack_never for members and device-invited guests; finite guest grants retain the configured maximum.
nameNoOptional requested DNS-label service name. A matching target is reused only if it already has this name; unrelated name collisions receive a numeric suffix.
tagsNoACL tags applied to the tailnet node, each prefixed tag:. Defaults to the configured default tag.
allowNoHuman recipients use the common access action: membership verification, app grants and necessary invitations. A recipient named here keeps access without an expiry unless for or until limits it (people_add defaults to 24h); an explicit never requires ack_never, and a binding that cannot create permanent grants gets the 24h default instead. tag: entries remain machine ACLs. New installations use the gateway; existing installs preserve their mode. Refused for TCP and public Funnel.
untilNoLimit human allow recipients to this deadline; conflicts with for.
funnelNoPublish to the public internet through Tailscale Funnel. Requires public_ack true, an HTTP port target, and no allow entries.
targetYesExisting file or directory path, bare port from 1 to 65535, or host:port HTTP target. A file path shares that one file; a directory path shares everything under it. The daemon will proxy to any address it can reach on its own network; link-local and cloud-metadata addresses are refused only as literal IP addresses (unspecified addresses too) or the metadata.google.internal hostname: hostnames are not resolved and nothing is checked at connect time, so a name that resolves to one of those addresses is accepted.
ack_neverNo
ephemeralNoKeep true for temporary shares; set false only when the user wants durable tailnet node state.
funnel_ttlNoRelative lifetime (descending unique units w,d,h,m,s,ms,us,ns) or until <RFC3339|YYYY-MM-DD|YYYY-MM-DDTHH:MM>. Local unless offset given; DST gaps/folds require an offset. Minimum 1h. Presets: 1h, 8h, 24h, 3d, 7d. Default 24h; guest/public maximum defaults to 7d, configurable in durations.public_max. Never refused. Omission on add preserves an existing deadline.
public_ackNoExplicit acknowledgement that funnel exposes the target publicly. funnel true without it is rejected.
print_linksNo
preserve_hostNoProxy only: forward this node's trusted canonical external name in Host and X-Forwarded-Host; fail closed if unavailable. Default false keeps upstream Host rewriting.
request_limitsNo
no_daemon_installNoRequire an already running TSLink service; do not automatically install its background service.

Output Schema

NameRequiredDescriptionDefault
urlNo
nameYesActually registered service name, always present on success, including needs_login. Use this name for url and unshare; never guess or fall back to the requested name.
accessNo
statusYes
auth_urlNo
exposureYes
warningsNo
preserve_hostNoProxy only: forward this node's trusted canonical external name in Host and X-Forwarded-Host; fail closed if unavailable. Default false keeps upstream Host rewriting.
funnel_rearmedNoTrue when the reused share's Funnel deadline had already passed and this call re-armed it with the requested funnel_ttl.
request_limitsNo
daemon_installedNoPresent only when this call installed TSLink's background service, a persistent OS autostart entry; absent when the service already ran or no_daemon_install was true.
funnel_expires_atNoWhen the public Funnel of this share stops. Absent when exposure.kind is not public_funnel, and absent for a public_funnel share that never expires. A reused share keeps its own deadline, which can be sooner than the funnel_ttl this call asked for.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.3.0
    • addedInput schema / properties / ack_never
      Added value: +{
      +  "type": "boolean"
      +}
    • changedInput schema / properties / allow / description
      Previous value: -"Principals allowed to reach the share over HTTP: email addresses, or tag:<name> ACL tags. Omitting it leaves the share readable by every member of the user's tailnet. Rejected together with funnel."New value: +"Human recipients use the common access action: membership verification, app grants and necessary invitations. A recipient named here keeps access without an expiry unless for or until limits it (people_add defaults to 24h); an explicit never requires ack_never, and a binding that cannot create permanent grants gets the 24h default instead. tag: entries remain machine ACLs. New installations use the gateway; existing installs preserve their mode. Refused for TCP and public Funnel."
    • addedInput schema / properties / for
      Added value: +{
      +  "description": "Limit human allow recipients to this lifetime (descending unique units w,d,h,m,s,ms,us,ns) or until <RFC3339|YYYY-MM-DD|YYYY-MM-DDTHH:MM>. Local unless offset given; DST gaps/folds require an offset. Minimum 1h. Presets: 1h, 8h, 24h, 3d, 7d. Omitted: a recipient this call newly allows has no expiry and an existing grant keeps its deadline; a binding that expires or cannot create permanent grants gets 24h. Explicit never requires ack_never for members and device-invited guests; finite guest grants retain the configured maximum.",
      +  "examples": [
      +    "1h",
      +    "8h",
      +    "24h",
      +    "3d",
      +    "7d",
      +    "90m",
      +    "1w",
      +    "1d12h",
      +    "until 2030-06-01T18:00:00Z"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / print_links
      Added value: +{
      +  "type": "boolean"
      +}
    • addedInput schema / properties / until
      Added value: +{
      +  "description": "Limit human allow recipients to this deadline; conflicts with for.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / access
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "access": {
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "access_state": {
      +              "type": "string"
      +            },
      +            "app": {
      +              "type": "string"
      +            },
      +            "message": {
      +              "type": "string"
      +            },
      +            "url": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "app",
      +            "access_state",
      +            "message"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "complete": {
      +        "type": "boolean"
      +      },
      +      "guide": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "guide_zh": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "invite_requirement": {
      +        "type": "string"
      +      },
      +      "invites": {
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "app": {
      +              "type": "string"
      +            },
      +            "code": {
      +              "type": "string"
      +            },
      +            "id": {
      +              "type": "string"
      +            },
      +            "invite_url": {
      +              "type": "string"
      +            },
      +            "reconcile_ids": {
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            },
      +            "remote_side_effect_plan": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "boundaries": {
      +                  "items": {
      +                    "type": "string"
      +                  },
      +                  "type": "array"
      +                },
      +                "default": {
      +                  "type": "string"
      +                },
      +                "disable_flag": {
      +                  "type": "string"
      +                },
      +                "id": {
      +                  "type": "string"
      +                },
      +                "mutates": {
      +                  "type": "boolean"
      +                },
      +                "operation": {
      +                  "type": "string"
      +                },
      +                "opt_in_flag": {
      +                  "type": "string"
      +                },
      +                "remote_system": {
      +                  "type": "string"
      +                },
      +                "resources": {
      +                  "items": {
      +                    "type": "string"
      +                  },
      +                  "type": "array"
      +                },
      +                "schema_version": {
      +                  "type": "integer"
      +                }
      +              },
      +              "required": [
      +                "schema_version",
      +                "id",
      +                "operation",
      +                "remote_system",
      +                "mutates",
      +                "default",
      +                "resources",
      +                "boundaries"
      +              ],
      +              "type": "object"
      +            },
      +            "state": {
      +              "type": "string"
      +            },
      +            "target_kind": {
      +              "enum": [
      +                "app",
      +                "gateway"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "app"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "membership": {
      +        "enum": [
      +          "member",
      +          "non_member"
      +        ],
      +        "type": "string"
      +      },
      +      "message": {
      +        "type": "string"
      +      },
      +      "person": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "grants": {
      +            "items": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "active": {
      +                  "type": "boolean"
      +                },
      +                "app": {
      +                  "type": "string"
      +                },
      +                "expired": {
      +                  "type": "boolean"
      +                },
      +                "expires_at": {
      +                  "format": "date-time",
      +                  "type": "string"
      +                },
      +                "url": {
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "app",
      +                "active"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "invites": {
      +            "items": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "app": {
      +                  "type": "string"
      +                },
      +                "attempt": {
      +                  "minimum": 0,
      +                  "type": "integer"
      +                },
      +                "hostname": {
      +                  "type": "string"
      +                },
      +                "id": {
      +                  "type": "string"
      +                },
      +                "node_id": {
      +                  "type": "string"
      +                },
      +                "state": {
      +                  "type": "string"
      +                },
      +                "target_kind": {
      +                  "enum": [
      +                    "app",
      +                    "gateway"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "app",
      +                "hostname",
      +                "node_id",
      +                "state"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "login": {
      +            "type": "string"
      +          },
      +          "revoked": {
      +            "type": "boolean"
      +          }
      +        },
      +        "required": [
      +          "login",
      +          "revoked",
      +          "grants"
      +        ],
      +        "type": "object"
      +      },
      +      "portal": {
      +        "description": "Independent home portal configuration and exact runtime address when available.",
      +        "type": "object"
      +      },
      +      "qr_payload": {
      +        "type": "string"
      +      },
      +      "qr_warning": {
      +        "type": "string"
      +      },
      +      "warnings": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "person",
      +      "complete",
      +      "message",
      +      "invite_requirement",
      +      "invites"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  2. First observedv0.1.0

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses what an agent genuinely could not infer: funnel=true publishes to the open internet and needs user consent, funnel=false stays private, directories are browsable while file targets 404 for siblings, incomplete setup returns an error with saved progress, and needs_login requires opening auth_url and retrying. Expiry defaults (no expiry unless for/until, 24h fallback, never permanent) are also spelled out. This is substantive disclosure consistent with openWorldHint=true and destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries real information, but the description leads with funnel policy rather than the tool's core action and strings together long semicolon-chained clauses about gateway mode and recipient expiry. It is dense to the point of being hard to scan, and the policy detail on allow/expiry partially duplicates the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter mutation tool with a nested request_limits object and an output schema, the description covers the decisions an agent must get right: target kind, public-exposure consent, recipient expiry, and the needs_login recovery path. The output schema carries return values, so the main remaining gap is a handful of undocumented booleans like print_links and ack_never.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 80% schema coverage the baseline is 3, and the description earns above that by explaining cross-parameter behavior the schema states only piecemeal: allow interacts with `for`/`until`/`ack_never`, and funnel requires public_ack plus an HTTP port target with no allow entries. It does not cover `print_links` or `ack_never`, which remain undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The title and opening sentences make clear this exposes a local target (directory, single file, or HTTP port) on the tailnet or, with funnel, publicly. The verb+resource is unambiguous and an agent can tell it apart from `unshare` or `url` by implication. It stops short of explicitly naming the sibling it is not, so it lands at 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use this after creating a local page or report that the user wants to open on another tailnet device" gives a concrete triggering scenario, and "ask the user before" setting funnel true is an explicit precondition. It never names an alternative tool (e.g., `url`, `list`, `unshare`) or states a when-not, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.