The docs explain artifacts for agents and tokens: connecting an agent has an Artifacts section on finding, reading, editing and making them, the MCP reference lists the artifact tool's actions with their scopes, the scope tables name artifacts:read, artifacts:write and artifacts:admin, and the artifacts plan records what Phase 3 decided.
4 files+112−50/4 viewed
| 684 | 684 | | Billing | read, read and write | `billing:read`, `billing:write` | | |
| 685 | 685 | | Self-hosted runners | read, admin | `runners:read`, `runners:admin` | | |
| 686 | 686 | | AI Gateway | read, read and write | `models:read`, `models:write` | | |
| 687 | + | | Artifacts | read, read and write, admin | `artifacts:read`, `artifacts:write`, `artifacts:admin` | | |
| 687 | 688 | ||
| 688 | 689 | Account permissions are about you, wherever you are, and only a personal | |
| 689 | 690 | token can hold them: | |
| ⋯ | |||
| 788 | 789 | | `runners:admin` | Register and remove self-hosted runners, change their groups and settings | | |
| 789 | 790 | | `models:read` | See the workspace's [AI Gateway](/guides/ai-gateway/) requests: their models, tokens, cost and status | | |
| 790 | 791 | | `models:write` | Send model requests through the [AI Gateway](/guides/ai-gateway/), which uses the workspace's AI credit. Only a workspace's own token can send them. Not in any preset. | | |
| 792 | + | | `artifacts:read` | List, read and search the [artifacts](/guides/bring-your-own-agent/#artifacts) you can open (docs, and later slides, designs and dashboards), their versions and who can open them. Not workflow runs' artifacts, which are `workflows:read`. | | |
| 793 | + | | `artifacts:write` | Create, rename, move, edit, trash and restore artifacts, and suggest changes to them | | |
| 794 | + | | `artifacts:admin` | Share artifacts, change who can open them, and delete them for good. Not in any preset. | | |
| 791 | 795 | ||
| 792 | 796 | Every operation of the API and the MCP server needs exactly one of these, | |
| 793 | 797 | except `whoami` (`GET /user`), which any token may use. Each endpoint's page | |
| ⋯ | |||
| 904 | 908 | personal token, starting on the CI preset. A workspace token reaches all | |
| 905 | 909 | of that workspace's repositories, or the ones chosen, never another | |
| 906 | 910 | workspace, and cannot manage people, tokens or workspaces. It holds no | |
| 907 | − | account permissions. | |
| 911 | + | account permissions, and cannot use artifacts, which always belong to a | |
| 912 | + | person. | |
| 908 | 913 | ||
| 909 | 914 | It has the Write role on the workspace's repositories, as a member does: | |
| 910 | 915 | it pushes, merges and works on issues and pull requests, within its | |
| 125 | 125 | `number`. [MCP tools](/reference/mcp/) lists every tool and action with its | |
| 126 | 126 | required inputs, its scope and its REST route. | |
| 127 | 127 | ||
| 128 | + | ## Artifacts | |
| 129 | + | ||
| 130 | + | Your agent can read and write a workspace's artifacts: its docs, and later | |
| 131 | + | its slides, designs and dashboards. The `artifact` tool does it as you, | |
| 132 | + | so it opens only what you can open, and changes only what you can change. | |
| 133 | + | Its token needs `artifacts:read` to read them (the Read only and Agent | |
| 134 | + | [presets](/guides/authentication/#presets) have it), `artifacts:write` to | |
| 135 | + | make and change them, and `artifacts:admin` to share them or delete them | |
| 136 | + | for good. A token without one of these sees no `artifact` tool, and a | |
| 137 | + | token sees only the actions its scope allows. | |
| 138 | + | ||
| 139 | + | 1. Find what is there with `list` (narrow with `kind`, `space` or `q`) or | |
| 140 | + | `search`, which matches words and meaning and returns the passage that | |
| 141 | + | matched. | |
| 142 | + | 2. Read one with `read`. A doc comes back as Markdown in `content`, with | |
| 143 | + | its top-level `blocks` and their ids, and `can` says whether you may | |
| 144 | + | edit it or only suggest. | |
| 145 | + | 3. Change it with `edit`: `markdown` and a `target`, which is `append`, | |
| 146 | + | `document` (replace it all), a `section` by its `heading`, or `blocks` | |
| 147 | + | from one block id to another. With the edit role the change is made, as | |
| 148 | + | a new version; with the comment role, or with `suggest_only`, it is | |
| 149 | + | filed as a suggestion that the doc's editors accept or reject. | |
| 150 | + | 4. Make one with `create`. Left out `space` and `parent_id`, it lands in | |
| 151 | + | your Private, where only you can open it until you share it. | |
| 152 | + | ||
| 153 | + | ```json | |
| 154 | + | { "action": "edit", "workspace": "acme", "artifact_id": "fol_01kq7c4e6g8j0m2p4r6t8v0x2z", | |
| 155 | + | "target": { "kind": "section", "heading": "Risks" }, | |
| 156 | + | "markdown": "## Risks\n\nThe migration needs a maintenance window.\n", | |
| 157 | + | "note": "Adds the migration risk" } | |
| 158 | + | ``` | |
| 159 | + | ||
| 160 | + | Name an artifact by its id (`fol_…`) or by its link. Each action is also | |
| 161 | + | a REST route under `/workspaces/{workspace}/artifacts`; see the | |
| 162 | + | [API reference](/reference/api/). These are not workflow runs' artifacts, | |
| 163 | + | which are the `workflow` tool's. Slides, designs and dashboards answer | |
| 164 | + | that they are not here yet. A workspace's own token cannot use artifacts: | |
| 165 | + | they always belong to a person. | |
| 166 | + | ||
| 128 | 167 | ## Staying out of each other's way | |
| 129 | 168 | ||
| 130 | 169 | `pull_request` with `get` returns `overlaps`: other pull requests in progress that |
| 3 | 3 | description: The g1t MCP server's resource tools, each action they take with its required inputs and scope, and how to call them. | |
| 4 | 4 | --- | |
| 5 | 5 | ||
| 6 | − | The MCP server at `https://mcp.g1t.sh` exposes 18 tools, one per kind of | |
| 6 | + | The MCP server at `https://mcp.g1t.sh` exposes 19 tools, one per kind of | |
| 7 | 7 | thing on g1t: `search`, `repository`, `issue`, `pull_request`, `agent`, | |
| 8 | 8 | `plan`, `memory`, `workflow`, `package`, `secret`, `security`, `webhook`, `access`, | |
| 9 | − | `team`, `workspace`, `billing`, `notifications` and `account`. Each tool takes an `action` that says what to do. Every | |
| 9 | + | `team`, `workspace`, `billing`, `notifications`, `account` and `artifact`. Each tool takes an `action` that says what to do. Every | |
| 10 | 10 | action is the same operation as a route of the [REST API](/reference/api/), | |
| 11 | 11 | with the same inputs, permissions and results, so the two always agree. | |
| 12 | 12 | ||
| ⋯ | |||
| 169 | 169 | | --- | --- | | |
| 170 | 170 | | `title` | The tool's name for people, such as `Pull requests`. | | |
| 171 | 171 | | `readOnlyHint` | `true` when every action shown only reads. | | |
| 172 | − | | `destructiveHint` | `true` when the tool is not read-only and an action shown cannot be undone or reaches beyond g1t's own records: deleting a workspace, deleting, purging or transferring a repository, changing its visibility, removing an email address or a collaborator, deleting a team or taking its role on a repository away, disconnecting an integration, deleting a webhook, setting or deleting secrets and variables, replacing model routes, setting a workspace's base permission, removing a member, transferring a workspace's ownership, leaving a workspace, merging a pull request, removing a self-hosted runner, deleting a runner group, and changing runner settings. | | |
| 172 | + | | `destructiveHint` | `true` when the tool is not read-only and an action shown cannot be undone or reaches beyond g1t's own records: deleting a workspace, deleting, purging or transferring a repository, changing its visibility, removing an email address or a collaborator, deleting a team or taking its role on a repository away, disconnecting an integration, deleting a webhook, setting or deleting secrets and variables, replacing model routes, setting a workspace's base permission, removing a member, transferring a workspace's ownership, leaving a workspace, merging a pull request, removing a self-hosted runner, deleting a runner group, changing runner settings, sharing an artifact, and deleting an artifact for good. | | |
| 173 | 173 | | `idempotentHint` | The same as `readOnlyHint`. | | |
| 174 | 174 | | `openWorldHint` | Always `false`. | | |
| 175 | 175 | ||
| ⋯ | |||
| 768 | 768 | | [`decline_repository_invitation`](/reference/api/access/decline-repo-invitation/) | Decline one. | `id` | `account:write` | | |
| 769 | 769 | ||
| 770 | 770 | ||
| 771 | + | ## `artifact` | |
| 772 | + | ||
| 773 | + | A workspace's artifacts: its docs, and later its slides, designs and | |
| 774 | + | dashboards. Each action runs as you: it finds and opens only what you can | |
| 775 | + | open, and changes only what your role on it allows, whatever the token's | |
| 776 | + | scope. Name one by its id (`fol_…`) or its link as `artifact_id`, and its | |
| 777 | + | space by slug or id. Not workflow runs' artifacts, which are the | |
| 778 | + | `workflow` tool's. Slides, designs and dashboards answer `422` saying they | |
| 779 | + | are not here yet. A workspace's own token cannot use this tool. See | |
| 780 | + | [artifacts for agents](/guides/bring-your-own-agent/#artifacts). | |
| 781 | + | ||
| 782 | + | | Action | What it does | Required | Scope | | |
| 783 | + | | --- | --- | --- | --- | | |
| 784 | + | | [`list`](/reference/api/artifacts/list-workspace-artifacts/) | The artifacts you can open, most recently edited first, with your role on each. Narrow with `tab` (`all`, `yours`, `shared`), `kind`, `space`, `project` and `q`; page with `cursor`. `state` `trashed` lists what you can restore. | `workspace` | `artifacts:read` | | |
| 785 | + | | [`search`](/reference/api/artifacts/search-workspace-artifacts/) | Search them by words and meaning; each hit has the passage that matched (`snippet`, `heading`). | `workspace`, `q` | `artifacts:read` | | |
| 786 | + | | [`get`](/reference/api/artifacts/get-workspace-artifact/) | One artifact: kind, title, space, owner, your `viewer_role`, general access, whether it is private or stale, and `html_url`. | `workspace`, `artifact_id` | `artifacts:read` | | |
| 787 | + | | [`read`](/reference/api/artifacts/get-workspace-artifact-content/) | Its content: a doc's Markdown, its top-level `blocks` with ids, and `can` (read, suggest, edit). | `workspace`, `artifact_id` | `artifacts:read` | | |
| 788 | + | | [`versions`](/reference/api/artifacts/list-workspace-artifact-versions/) | Its saved versions, newest first, with who made each. | `workspace`, `artifact_id` | `artifacts:read` | | |
| 789 | + | | [`access`](/reference/api/artifacts/get-workspace-artifact-access/) | Who can open it: its owner, who it is shared with and how, general access, and whether you may change it. | `workspace`, `artifact_id` | `artifacts:read` | | |
| 790 | + | | [`templates`](/reference/api/artifacts/list-workspace-artifact-templates/) | Templates to start one from, built-in and the workspace's; narrow with `kind`. | `workspace` | `artifacts:read` | | |
| 791 | + | | [`spaces`](/reference/api/artifacts/list-workspace-artifact-spaces/) | The spaces in your Artifacts sidebar, with your role in each. | `workspace` | `artifacts:read` | | |
| 792 | + | | [`query_data`](/reference/api/artifacts/query-workspace-dataset/) | Run a dataset `query` as you, over what you can read. Answers that dashboards are not here yet until they ship. | `workspace`, `query` | `artifacts:read` | | |
| 793 | + | | [`create`](/reference/api/artifacts/create-workspace-artifact/) | Make one from `markdown` or a `template_id`, in a `space`, under a `parent_id`, or in your Private. `kind` is `doc`; the others are not here yet. | `workspace` | `artifacts:write` | | |
| 794 | + | | [`update`](/reference/api/artifacts/update-workspace-artifact/) | Change its `title` or `icon`, or move it to a `space` (`private` for your Private) or under a `parent_id`. | `workspace`, `artifact_id` | `artifacts:write` | | |
| 795 | + | | [`edit`](/reference/api/artifacts/edit-workspace-artifact/) | Change its content: `markdown` with a `target` (`append`, `document`, a `section` by `heading`, or `blocks`). Made with the edit role; a suggestion with the comment role or `suggest_only`. | `workspace`, `artifact_id` | `artifacts:write` | | |
| 796 | + | | [`trash`](/reference/api/artifacts/trash-workspace-artifact/) | Move it, and what is under it, to the trash; deleted for good after 30 days. | `workspace`, `artifact_id` | `artifacts:write` | | |
| 797 | + | | [`restore`](/reference/api/artifacts/restore-workspace-artifact/) | Bring it back from the trash. | `workspace`, `artifact_id` | `artifacts:write` | | |
| 798 | + | | [`restore_version`](/reference/api/artifacts/restore-workspace-artifact-version/) | Make an earlier version its content again, as a new version. | `workspace`, `artifact_id`, `version_id` | `artifacts:write` | | |
| 799 | + | | [`share`](/reference/api/artifacts/set-workspace-artifact-access/) | Share it with a `username`, `team` or `agent` at a `role` (`view`, `comment`, `edit`, `manage`, or `none` to take access away); set `general_access` and `general_role`, `inherit` or `agent_mode`. Takes full access to it. | `workspace`, `artifact_id` | `artifacts:admin` | | |
| 800 | + | | [`purge`](/reference/api/artifacts/purge-workspace-artifact/) | Delete one in the trash for good. Takes full access to it. | `workspace`, `artifact_id` | `artifacts:admin` | | |
| 801 | + | ||
| 771 | 802 | ## What g1t can use | |
| 772 | 803 | ||
| 773 | 804 | g1t works with a [run credential](/guides/working-with-g1t/#credentials): | |
| ⋯ | |||
| 792 | 823 | reopens a security alert, or the `security` actions that decide about | |
| 793 | 824 | security: `update_secret_alert`, `bypass`, `review_bypass`, the pattern | |
| 794 | 825 | changes, `update_code_alert`, `update_vulnerability_alert`, `fix`, | |
| 795 | − | `update_settings` and `update_workspace_settings`. Every repository it | |
| 826 | + | `update_settings` and `update_workspace_settings`, or `artifact` `share` | |
| 827 | + | and `purge`. Every repository it | |
| 796 | 828 | names must be its own. `tools/list` shows such a token only the tools and | |
| 797 | 829 | actions it may use; a call to any other is refused with the rule that | |
| 798 | 830 | refused it, and recorded in the workspace's [audit log](/guides/audit-log/), | |
| 876 | 876 | - **"Editors can share."** `canShare` supports this per-space setting, but nothing sets it yet. | |
| 877 | 877 | - **Access requests.** `request_folio_access` sends to the owner and the people with full access, at most 20, with no limit on how often. Decide whether it needs one. | |
| 878 | 878 | - **Self-hosted rooms.** `deploy/self-host/configs.mjs` doesn't copy `durable_objects` into the self-hosted configs. That gap predates this phase and affects `PageRoom` too. Check it before relying on rooms self-hosted. | |
| 879 | + | ||
| 880 | + | --- | |
| 881 | + | ||
| 882 | + | ## 13. Decided in Phase 3 | |
| 883 | + | ||
| 884 | + | Phase 3 shipped the external API in `apps/api` (`src/folios.rs`, the `artifact` tool, 17 routes) over a `DOCS` binding to `g1t-docs-service`, and made the `artifacts:*` scopes real. Where the plan was open, the build settled these: | |
| 885 | + | ||
| 886 | + | - **Operation names.** GitHub's names for workflow runs' artifacts (`list_artifacts`, `get_artifact`, `delete_artifact`) are taken, so every artifact operation says `workspace_artifact`: `list_workspace_artifacts`, `get_workspace_artifact_content`, `set_workspace_artifact_access`, and so on. Dataset queries are `query_workspace_dataset`. The OpenAPI section is "Artifacts"; workflow runs' artifacts stay under "Actions". | |
| 887 | + | - **Scopes.** | |
| 888 | + | - Every resource is offered now, so `Resource::offered()` is true for all; the mechanism stays for the next resource built ahead of its API. `UPCOMING_SCOPES` and `UPCOMING_RESOURCES` are empty, and the Artifacts rows are at the end of `SCOPES`, `SCOPE_RESOURCES` and `OPERATION_SCOPES`. `SCOPE_GROUPS` has an Artifacts group. | |
| 889 | + | - Read only and Agent get `artifacts:read` (Rust adds it because both take every offered read). No preset writes or shares artifacts. | |
| 890 | + | - Read: list, search, get, content, versions, access, templates, spaces, dataset query. Write: create, update (rename and move), edit (applied or suggested), trash, restore, restore a version. Admin: share (grants, general access, inherit, agent mode) and purge. | |
| 891 | + | - `set_workspace_artifact_access` and `purge_workspace_artifact` are in `NEVER`: g1t's own agents share only through the agents service, with people already in the conversation. | |
| 892 | + | - **The tool's actions** are `list`, `search`, `get`, `read`, `versions`, `access`, `templates`, `spaces`, `query_data`, `create`, `update`, `edit`, `trash`, `restore`, `restore_version`, `share` and `purge`. The plan's `get` (metadata and the agent form) is split into `get` (metadata, `GET …/artifacts/{id}`) and `read` (content, `GET …/content`), because each action is one operation and one route. `share` and `purge` make the tool's `destructiveHint` true. | |
| 893 | + | - **REST.** `DELETE /workspaces/{ws}/artifacts/{id}` moves an artifact to the trash, as `DELETE` of a package does, and `POST …/restore` and `POST …/purge` follow the repository routes. `GET …/artifacts/search` comes before `…/artifacts/{id}` in the table. Templates and spaces are at `/workspaces/{ws}/artifact-templates` and `/workspaces/{ws}/artifact-spaces`. `?state=trashed` on the list is the trash. | |
| 894 | + | - **Input.** | |
| 895 | + | - `artifact_id` is an id, an address segment (`q4-roadmap-fol_…`) or a whole link. | |
| 896 | + | - `space` is a slug or an id; a slug is looked up among the spaces in the person's sidebar (`folio_sidebar`), so an open space not yet joined needs its id. | |
| 897 | + | - An edit is a doc edit unless `kind` says otherwise. `target` may be a string (`append`, `document`) or the object, and defaults to `append`. | |
| 898 | + | - A share names `username` (looked up in identity and sent as `user:<id>`), `team`, `agent` or a raw `principal`. `role: none` revokes. One call can also change general access, `inherit` and `agent_mode`, sent to the service in that order. | |
| 899 | + | - Create takes no `share_with`: sharing is the admin scope's, so it is its own call. | |
| 900 | + | - **Output.** The API shapes every answer itself, in snake_case: people are `{ type, id, username | handle | slug, display_name }`; artifacts drop `workspace_id`, `position` and `preview`, and gain `html_url`; content drops `audience_can_read` (always true for a person); the access list's `rows` are `shared_with`, and `public_link` is left out until public links exist. | |
| 901 | + | - **Who.** A workspace's own token is refused (`403`): an artifact always has a person as its owner, and the docs service has no person for a workspace. A g1t agent's run token can call only what its run's scope lists, which names no artifact operation today. | |
| 902 | + | - **Trashed artifacts.** `get` of a trashed artifact answers with `trashed_at` set, to anyone who could open it, as the `folio` read does for the UI's restore banner; its content is refused. That is the service's rule, unchanged here. | |
| 903 | + | - **Checked** under `wrangler dev` with the API, the docs service and stand-in services: 55 checks over REST and MCP with scoped tokens, including that a Private artifact is not found, listed or searched for another member's admin token, that a revoked share closes it again, that a non-member and a workspace token are refused, and that `tools/list` hides write and admin actions from tokens without those scopes. | |
| 904 | + | ||
| 905 | + | Deploy order: the docs service is already deployed (Phase 1); the API's `DOCS` binding needs `g1t-docs-service` to exist before `g1t-api` deploys, which `stage: core` before `edge` already gives. | |
| 906 | + | ||
| 907 | + | Open: | |
| 908 | + | - **llms.txt.** `apps/web/public/llms.txt` should name the `artifact` tool; it is in `apps/web`, which Phase 2 owns, so it is left for that merge. | |
| 909 | + | - **Unjoined open spaces by slug.** Only sidebar spaces resolve by slug. A `list_spaces`-style RPC that returns every space the person can read would fix it, and the agents service's `list_spaces` tool (Phase 2) needs the same. |