Symbol Docs
Concepts

Referencing Resources

How to reference capsules, types, and projects using Symbol's shorthand syntax, also called mentions.

Symbol uses a consistent shorthand syntax for referencing capsules, types, and projects. These references work inside capsule content, AI conversations, and MCP tool calls.

These are also called mentions, and the two words mean the same thing throughout Symbol and its API.

Capsules

Capsules are referenced using the format @type-slug/refId, where type-slug is the URL-friendly version of the type name and refId is the capsule's sequential number within that type.

Format: @type-slug/refId

Examples:

  • @docker/3 - capsule #3 in the Docker type
  • @decisions/12 - capsule #12 in the Decisions type
  • @code-snippets/7 - capsule #7 in the Code Snippets type

When you are working within a specific type in the editor, the # typeahead helps you find a capsule in that same type. Type a number to match its ref id (e.g. #3), or type text to search the type's capsule titles:

  • #3 - capsule 3 in the current type context

Whichever way you find it, the editor inserts the canonical @type-slug/3 form when you accept a suggestion, so a # token is never stored in capsule content or parsed as a reference on its own. It is purely an editor search-and-insert convenience, and the stored capsule reference is always the numeric @type-slug/refId.

Where to use it: The # typeahead is for the editor only. To link capsules inside stored content, use the canonical @type-slug/refId form, which is also what MCP tool calls expect via the ref parameter of get_capsule_by_ref. In AI chat and MCP, a text #slug (e.g. #wifi-project) means a Project instead. See below.

Cross-Referencing

You can reference one capsule from another's content. This lets you build connected knowledge without duplicating information:

"I solved a similar problem in @docker/1, but this case was different because..."

Pointer references

By default, reading a capsule that references another delivers the target's full content alongside it. That suits a briefing note that wants the detail inlined. For an index or hub, it is usually the wrong choice: reading the hub would pull in everything it points at.

Put a single ~ immediately before a reference to make it pointer-only. It still resolves, still renders as a link, and still counts as an edge in the capsule graph (backlinks and "what points at this" are unchanged), but its target's body is not included when the capsule is read.

Format: ~@type-slug/refId

Examples:

  • @docker/3, inline: reading this capsule delivers Docker capsule #3's full content (the default).
  • ~@docker/3, pointer: reading this capsule delivers a link to Docker capsule #3, not its body.

The ~ lives in the stored markdown, so it survives editing and export, and any client can author it with no special API. A reference reports which kind it is when you read the capsule, and a pointer-only reference is shown with a link-out marker in the app so you can tell it apart from an inline one. Two details worth knowing:

  • If the same target is referenced both ways in one capsule, the inline form wins. Anything that inlines today keeps inlining.
  • Only a single leading ~ is the pointer marker. A ~~@type/slug~~ (strikethrough) reference is left inline, exactly as before.

The same ~ works in a reference or multi_reference field value (~@type-slug/refId).

Seeing what a read costs

Open a capsule and expand Read cost, below its references and backlinks, to see what an assistant's read of that capsule delivers to you: its own text, each capsule it inlines, each pointer, and each reference the read leaves out, with the number of characters each one adds. The numbers come from the same rules a real read follows, so they match what the assistant receives, not an estimate from the text.

A read leaves a reference out in three cases, and the section names which:

  • it is a pointer (~@), by your choice;
  • it is past the fifth inline reference, since a read inlines at most five;
  • the capsule and everything it inlines would exceed the read size limit, so the read delivers the capsule alone and names the rest.

Findings suggest changes, and never make them. An inlined capsule larger than the threshold you set (4,000 characters by default) is listed with the characters a pointer would save, measured by rebuilding the read with it as a pointer. That is more than its text alone, since its title and references leave the read too. When the slot it frees goes to a reference that was over the five-reference limit, the finding names that capsule: the saving is then smaller, the read can even grow, and if the linked capsules would then exceed the read size limit, it says none would be inlined. The finding says where the reference is written, in the text or in a field, exactly as you wrote it (an alias such as @docs/setup, or a bare value in a reference field), and a link opens the capsule's editor so you can add the ~ yourself. Some inlining is deliberate, so keep it where the reader needs the text. Text a read returns more than once in one response is flagged too.

Read together measures several capsules an assistant loads at once, such as an agent and the capsules its instructions name. Start from Add the capsules this one references, or add any capsule by title or ref. The section lists every capsule delivered more than once across the set and what the repeats cost. The set is kept in the page's address, so a reload keeps it and you can share the link with someone who can read the same capsules.

The counts are for your own read. Someone else, or an assistant using a different key, may be able to read a different set of linked capsules. An encrypted capsule's own text cannot be measured without your keys, so the section says so instead of showing a count.

Filtering a list by a reference field

When you list the capsules of a Type and filter on a reference field (eq) or a multi_reference field (contains), the filter matches by the capsule the stored value points to, not the exact text that was stored. You can name the target any way the field accepts, @type/refId, @type/alias, a bare alias, or the capsule's id, and they all return the same rows. Because the match is by capsule, renaming the target's alias does not change what the filter returns, and a filter still finds rows that stored an older spelling of the target.

An archived target is matched too: filtering by an archived capsule returns the active rows that reference it, and restoring the target does not change the result, so a capsule that auto-archives never silently breaks a working lookup. A value that names no capsule you can read (nonexistent, deleted, or outside your access) is refused rather than returning an empty list, so "no match" is never mistaken for "no record". A value that resolves to a real capsule you can read but that happens to sit outside the field's constrained Type returns the rows that point at it, or an empty list when none do.

A reference to a capsule that is later archived keeps showing in the references panel and in backlinks, labelled as archived, including after the citing capsule is edited; it is not dropped as a dangling reference.

A reference to a capsule that is later permanently deleted keeps meaning that capsule. It shows as the reference you wrote, labelled "no longer exists", in the app, on share pages and in AI assistant reads, even if another capsule later takes the same number or alias, and it never links to or brings in that newer capsule. Nothing about the deleted capsule is shown. To point at the newer capsule, cite it by its own number or by a different alias. A mention written before its target existed is not affected: it resolves once the target is created. In API reads these references are listed in deadCrossRefs, not resolvedCrossRefs.

A permanently deleted capsule's number is never given to another capsule, and its alias stays reserved too: a new capsule asking for that alias is saved without it, and renaming a capsule to it is refused. To reuse the alias on purpose, choose Reclaim beside the message in the app, ask your AI to reclaim it, or send reclaim_alias: true through the API. Reclaiming never changes what older references point to; they still show as no longer existing. Only an alias that no existing capsule answers to can be reclaimed: an alias a capsule was renamed away from keeps pointing at that capsule.

Types

Types are referenced using the format @type:slug, a plain slug, or a plain name. All three resolve to the same type.

Formats:

  • @type:code-snippets
  • code-snippets
  • Code Snippets

The slug is auto-generated from the type name: lowercased, with spaces and special characters replaced by hyphens.

Where to use it: In MCP tool calls via the type_name parameter (e.g. list_capsules, create_capsule).

Projects

Projects are referenced using the format @project:slug, the text form #slug, or a plain name.

Formats:

  • @project:wifi-project
  • #wifi-project
  • WiFi Project

The slug follows the same rules as type slugs: lowercased, spaces and special characters replaced by hyphens.

Where to use it: In MCP tool calls via the project_name parameter (e.g. get_project_context, create_capsule, update_capsule). The text form #slug is an AI-chat / MCP convention: when you write #wifi-project in a conversation, the assistant loads that project's context via get_project_context.

Note: In AI chat and MCP, the text form #slug (e.g. #wifi-project) is a project reference. Do not confuse it with the numeric form #N (e.g. #3), which the model treats as an editor-only current-type capsule shorthand (the editor rewrites it to @type-slug/N on insert), not a project. In that AI-chat / MCP context the two are disambiguated by shape: a number after # is the capsule shorthand; text after # is a project. (In the editor itself, the # typeahead also accepts title text to search for a capsule, but it always inserts the canonical @type-slug/N. It never produces a stored #slug token.)

Note: First-class parsing and resolution of the #slug → project form (alongside @type: and @project:) from message text is tracked in issue #599. Today the #slug project form is honored by the AI chat / MCP layer per the assistant's reference-syntax contract, rather than by the web content parser.

Organizations

Organizations cannot be referenced directly in conversations or tool calls. They are an organizational layer that controls who has access to capsules and projects. Context is always loaded through capsules and projects, not through organization membership.

Summary

ResourceTokenShapeContextResolves to
Capsule (cross-type)@type-slug/refIdn/acontent, chat, MCPcapsule refId in that type
Capsule (pointer-only)~@type-slug/refIdn/acontent, chat, MCPsame capsule, linked but not inlined on read
Capsule (current-type)#N (editor typeahead)number or title searcheditor onlyfinds capsule N in the current type and inserts @type-slug/N; never stored or parsed as a # token
Project#slugtext onlyAI chat / MCPa project → get_project_context
Type@type:slug; plain slug; plain namen/achat, MCPthe type
Project@project:slug; plain namen/achat, MCPthe project

How Slugs Are Generated

Slugs are derived automatically from names using the following rules:

  1. Convert to lowercase
  2. Replace any sequence of non-alphanumeric characters with a hyphen
  3. Strip leading and trailing hyphens

For example: "My Docker Setup" becomes my-docker-setup.

You can also set a custom slug when creating a type or project.

On this page