Skip to content

Orbit

Orbit exposes GitLab.com’s experimental Knowledge Graph API through six read-only MCP tools: status, schema, tools, dsl, query, and graph_status. It is available only when the server connects to https://gitlab.com and the resolved tier is Premium or Ultimate (GITLAB_MCP_TIER=premium or GITLAB_MCP_TIER=ultimate, --tier=premium or --tier=ultimate in HTTP mode, or the tier detected from the instance license, then the namespace plans, then the top-level groups the token is a member of). The GITLAB_ENTERPRISE environment variable was removed in 3.0.0 and is ignored. Orbit never writes: every tool inspects health, schema, or indexed data, or runs a read-only graph query.

Orbit registers only on GitLab.com connections with a Premium or Ultimate tier. It requires the https://gitlab.com host and a resolved tier of Premium or Ultimate. On the default dynamic surface its six actions are the orbit.* catalog entries reached through gitlab_find_action and gitlab_execute_action; with GITLAB_MCP_TOOL_SURFACE=meta it is the single gitlab_orbit tool with six actions; with GITLAB_MCP_TOOL_SURFACE=individual it is six gitlab_orbit_* tools. Every Orbit tool is read-only.

RequirementValue
GitLab hosthttps://gitlab.com
TierPremium or Ultimate
Dynamic surface (default)orbit.* actions via gitlab_execute_action
Meta-tool modegitlab_orbit with six actions
Individual modeSix gitlab_orbit_* tools
Write behaviorRead-only

Self-managed GitLab instances do not register Orbit tools, even on a Premium or Ultimate tier.

ActionCanonical IDIndividual toolPurpose
statusorbit.statusgitlab_orbit_statusCheck Orbit service health and component status
schemaorbit.schemagitlab_orbit_schemaInspect the graph ontology and optionally expand node definitions
toolsorbit.toolsgitlab_orbit_toolsList the MCP tool manifest Orbit serves
dslorbit.dslgitlab_orbit_dslRetrieve the Orbit query DSL schema or LLM grammar
queryorbit.querygitlab_orbit_queryExecute a read-only Knowledge Graph query object
graph_statusorbit.graph_statusgitlab_orbit_graph_statusInspect indexing status for a namespace, project, or full path

The action name is what the gitlab_orbit meta-tool takes in action; the canonical ID is what gitlab_execute_action takes on the default dynamic surface.

The typical Orbit flow learns the query language and the graph first and queries second, because the DSL and the ontology GitLab.com serves change during the beta. Confirm the service is up with status, read the query language with dsl and the graph with schema, then submit a query object to query.

  1. Run the status action (gitlab_execute_action with action: "orbit.status" on the default surface; gitlab_orbit with action: "status" when GITLAB_MCP_TOOL_SURFACE=meta) to confirm the service is available.
  2. Run dsl for the query language, as a JSON Schema (raw) or a compact grammar (llm).
  3. Run schema for the entities, their properties and the relationship types between them.
  4. (Optional) Run tools for the MCP tool manifest Orbit serves, with the parameter schema of each of its own tools.
  5. Pass a JSON query object to query with response_format set to raw or llm.

The query parameter on the query action is a query in version 12 of the Orbit query DSL (graph_query/v12, the schema dsl returns). Every query carries a query_type and a nodes list, even a query with one node, and the query_type decides what else it needs. The diagram summarizes the smallest shape GitLab.com runs for each type. A Mermaid graph TD fits because the four types share one discriminator and differ only in the keys beside it.

traversal

aggregation

neighbors

path_finding

query

query_type

nodes: 1 node, or 2 to 5 joined by relationships
+ node_ids or filters on a node
+ columns?, order_by?, limit?, cursor?

nodes + node_ids or filters on a node
+ aggregations: count, sum, avg, min, max, collect
+ relationships?, group_by?, aggregation_sort?

nodes: exactly 1, the center, bounded
+ neighbors: direction?, rel_types?

nodes: 2
+ path: type shortest, from, to,
max_depth 1 to 3, rel_types

The rules a model most often gets wrong. The first three refuse an older shape of the DSL, which this server also taught before it moved to version 12, and the aggregation keyed by its function is new in version 12:

  • No top-level node. The node selectors go in nodes, which GitLab requires, and a top-level node is refused.
  • A filter is a bare value or an object keyed by operators. {"full_path": "gitlab-org/gitlab"} matches one value, and {"full_path": {"starts_with": "gitlab-org/"}} or {"star_count": {"gte": 1, "lt": 9}} apply operators. The operators are eq, ne, gt, lt, gte, lte, in, contains, starts_with, ends_with, is_null, is_not_null, token_match, all_tokens and any_tokens. An {"op": ..., "value": ...} object is refused.
  • A neighbors query names no node inside neighbors. Its center is its one node, and neighbors holds only direction and rel_types. The direction defaults to outgoing, so a query wanting every relationship of the center passes "both": a project’s group, creator and labels are reached by incoming relationships.
  • A path query names its relationship types. rel_types is required, ["*"] for any type, each relationship is followed only in its defined direction, and shortest is the only path type.
  • Aggregations, grouping and ordering are compact. An aggregation is keyed by its function, {"count": "mr", "as": "mr_count"}. A group_by entry is a node id, or a node id and a property joined by a dot. order_by and aggregation_sort are strings, with a leading - for descending.
  • A traversal or aggregation is bounded. At least one node carries node_ids or filters, and a neighbors query bounds its center the same way. GitLab refuses an unbounded query rather than scan every edge.

The server checks only that a query was given and that it encodes as JSON; GitLab judges the rest. A query it cannot compile is answered with 400 and a message naming the fault, which reaches the model in the error text with a suggestion to correct the query from dsl and schema:

orbit_query: bad request: check your input parameters ({code: compile_error}, {message: schema violation: "nodes" is a required property at ; Additional properties are not allowed ('node' was unexpected) at }). Suggestion: correct the query where GitLab's message points. orbit.dsl serves the query language and orbit.schema the entities, properties and relationship types it accepts: POST https://gitlab.com/api/v4/orbit/query: 400 ...

A name GitLab does not know is answered with every name it does know, such as the full list of relationship types for a misspelled IN_PROJECT, so the correction is usually in the message itself.

The recommended pattern is to read the graph with schema and the query language with dsl first, then execute a query through query. A sequenceDiagram fits because the steps involve four distinct actors (AI client, MCP server, GitLab.com, the Orbit indexer) and the response boundaries matter: the LLM should not assume the DSL returned by dsl is stable, and a query GitLab cannot compile comes back with GitLab’s own account of why.

Orbit IndexerGitLab.com APIMCP ServerAI ClientOrbit IndexerGitLab.com APIMCP ServerAI Clientalt[GitLab compiles the query][GitLab cannot compile it]gitlab_orbit_schema (response_format=llm)GET /api/v4/orbit/schemaontology (nodes, edges, versions)schema textgitlab_orbit_dsl (response_format=llm)GET /api/v4/orbit/schema/dslquery DSL / LLM grammarDSL textgitlab_orbit_query (query={query_type, nodes, ...})POST /api/v4/orbit/queryresolve node_ids / filtersindexed rowsrows / aggregations / pathsresult + markdown400 compile_error + messageerror carrying GitLab's message

The examples below use the default dynamic surface; with GITLAB_MCP_TOOL_SURFACE=meta call gitlab_orbit instead of gitlab_execute_action and drop the orbit. prefix from action.

{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.status",
"params": {}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.schema",
"params": {
"expand": ["Project", "User"],
"response_format": "llm"
}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.tools",
"params": {}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.dsl",
"params": {
"response_format": "llm"
}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.query",
"params": {
"query": {
"query_type": "traversal",
"nodes": [
{
"id": "p",
"entity": "Project",
"filters": {
"full_path": { "starts_with": "gitlab-org/" }
},
"columns": ["id", "full_path"]
}
],
"limit": 20
},
"response_format": "llm"
}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.query",
"params": {
"query": {
"query_type": "aggregation",
"nodes": [
{
"id": "p",
"entity": "Project",
"filters": { "full_path": { "starts_with": "gitlab-org/" } }
},
{ "id": "mr", "entity": "MergeRequest" }
],
"relationships": [{ "type": "IN_PROJECT", "from": "mr", "to": "p" }],
"group_by": ["p"],
"aggregations": [{ "count": "mr", "as": "mr_count" }],
"aggregation_sort": "-mr_count"
}
}
}
}
Section titled “Example: Everything a project is related to”
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.query",
"params": {
"query": {
"query_type": "neighbors",
"nodes": [
{
"id": "p",
"entity": "Project",
"filters": { "full_path": "gitlab-org/gitlab" }
}
],
"neighbors": { "direction": "both" },
"limit": 50
}
}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.query",
"params": {
"query": {
"query_type": "path_finding",
"nodes": [
{ "id": "u", "entity": "User", "node_ids": [1] },
{ "id": "p", "entity": "Project", "node_ids": [278964] }
],
"path": {
"type": "shortest",
"from": "u",
"to": "p",
"max_depth": 3,
"rel_types": ["*"]
}
}
}
}
}
{
"tool": "gitlab_execute_action",
"arguments": {
"action": "orbit.graph_status",
"params": {
"project_id": 278964,
"response_format": "llm"
}
}
}

Returns cluster health and backend component status. Use to verify Orbit is available for your token and project.

Example: See above.

Returns the Orbit graph ontology, including schema version, domains, node summaries, and edges. Use expand to get detailed node definitions. Supports response_format (raw or llm).

Example: See above.

tools — Discover the Orbit tool manifest

Section titled “tools — Discover the Orbit tool manifest”

Returns the MCP tool manifest Orbit serves, with the parameter schema of each of its own tools. The query language itself is what dsl returns.

Example: See above.

dsl — Retrieve the Orbit query DSL schema or LLM grammar

Section titled “dsl — Retrieve the Orbit query DSL schema or LLM grammar”

Returns the Orbit query DSL as a JSON Schema (raw) or LLM grammar (llm). Useful for advanced query construction and LLM integration.

Example: See above.

Runs a read-only Knowledge Graph query. The query parameter is a query in the DSL dsl returns, version 12 today, naming entities, properties and relationship types schema lists. GitLab judges the query and answers one it cannot run with a message naming the fault, which the server passes on. Supports response_format (raw or llm).

Example: See above.

Returns graph indexing status for a namespace, project, or full path. Use to check if a project is indexed and ready for queries.

Example: See above.

On every surface, action parameter schemas are available through MCP resources, so you can learn the exact params shape of each Orbit action without expanding every schema in tools/list; on the dynamic surface gitlab_find_action returns the same schema inline. These resources remain available with GITLAB_MCP_CAPABILITY_SURFACE=full or minimal, regardless of GITLAB_MCP_META_PARAM_SCHEMA mode. The table lists the default-surface IDs; with GITLAB_MCP_TOOL_SURFACE=meta the entry is gitlab://tools/gitlab_orbit.<action>.

ResourcePurpose
gitlab://tools/orbit.statusParameters for service health checks
gitlab://tools/orbit.schemaParameters for ontology inspection
gitlab://tools/orbit.toolsParameters for tool manifest discovery
gitlab://tools/orbit.dslParameters for DSL schema/grammar
gitlab://tools/orbit.queryParameters for Knowledge Graph queries
gitlab://tools/orbit.graph_statusParameters for indexing status checks

Frequently asked questions

What are the four Orbit query_type variants?

The query action takes a query in version 12 of the Orbit query DSL, which every query writes as a query_type and a nodes list, even for one node. traversal reads one node, or several joined by relationships. aggregation counts, sums or averages over nodes, optionally grouped. neighbors returns the relationships of its one node, outgoing unless neighbors.direction says incoming or both. path_finding finds the shortest path between two nodes, max_depth 1 to 3, along the rel_types it names. GitLab compiles each query and answers one it cannot run with a message naming the fault, which the server passes on.

Is Orbit available on self-managed GitLab?

No. Orbit is available only when GitLab MCP Server connects to https://gitlab.com. Self-managed GitLab instances do not register Orbit tools, even on a Premium or Ultimate tier, because the underlying experimental Knowledge Graph API is hosted on GitLab.com. There is no flag that adds Orbit to a self-managed connection.

What license and configuration does Orbit require?

Orbit requires a Premium or Ultimate tier on a GitLab.com connection. Enable it with GITLAB_MCP_TIER=premium or GITLAB_MCP_TIER=ultimate in stdio mode, or --tier=premium / --tier=ultimate in HTTP mode; when neither is set the tier is detected from the instance license, then from the plans of the namespaces the token administers, then from the top-level groups the token is a member of, falling back to free, so a member of a group on a paid plan sees the Orbit actions without pinning the tier. A fine-grained token is the exception: GitLab answers the group step to no fine-grained token, so one that administers no paid namespace resolves to free and needs the tier pinned. The GITLAB_ENTERPRISE environment variable was removed in 3.0.0 and is ignored; HTTP mode reads GITLAB_MCP_TIER from its environment when --tier is not passed. When these conditions are met, Orbit's six actions are reachable as orbit.status, orbit.schema, orbit.tools, orbit.dsl, orbit.query and orbit.graph_status on the default dynamic surface, as the gitlab_orbit meta-tool with GITLAB_MCP_TOOL_SURFACE=meta, or as six gitlab_orbit_* tools with GITLAB_MCP_TOOL_SURFACE=individual.

Is Orbit read-only?

Yes. All six Orbit tools are read-only. status, schema, tools, dsl, and graph_status only inspect health, ontology, manifest, DSL, and indexing state, and query runs read-only Knowledge Graph query objects against the index. No Orbit action mutates GitLab data, so Orbit is safe to expose even in cautious deployments.

How do I learn the exact parameters for an Orbit action?

On the default dynamic surface, gitlab_find_action with a query such as "orbit query" returns the exact params schema inline; the same schema is readable as the gitlab://tools/orbit.query resource (gitlab://tools/gitlab_orbit.query with GITLAB_MCP_TOOL_SURFACE=meta). These resources stay available with GITLAB_MCP_CAPABILITY_SURFACE=full or minimal and in any GITLAB_MCP_META_PARAM_SCHEMA mode. Before constructing a query, run the dsl action for the query language GitLab.com compiles it against and the schema action for the entities and relationship types it can name.