gitlab-api 27.3.9__tar.gz → 27.3.11__tar.gz
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.
- {gitlab_api-27.3.9/gitlab_api.egg-info → gitlab_api-27.3.11}/PKG-INFO +3 -5
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/README.md +0 -2
- gitlab_api-27.3.11/gitlab_api/__init__.py +15 -0
- gitlab_api-27.3.11/gitlab_api/__main__.py +4 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/connector_prep.py +2 -2
- gitlab_api-27.3.11/gitlab_api/connector_sources.py +147 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/kg_ingest.py +4 -58
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/mcp_server.py +1 -65
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/certification.json +6 -6
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/mappings/source.yaml +1 -1
- {gitlab_api-27.3.9 → gitlab_api-27.3.11/gitlab_api.egg-info}/PKG-INFO +3 -5
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api.egg-info/SOURCES.txt +0 -9
- gitlab_api-27.3.11/gitlab_api.egg-info/entry_points.txt +8 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api.egg-info/requires.txt +1 -1
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/pyproject.toml +16 -15
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_cq_paths.py +2 -2
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_fleet_name.py +1 -1
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_gitlab_api_brute_force_coverage.py +0 -100
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_ingest_sources.py +5 -5
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_kg_ingest.py +13 -13
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_mock_coverage.py +3 -23
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_tool_modes.py +2 -2
- gitlab_api-27.3.9/MANIFEST.in +0 -4
- gitlab_api-27.3.9/gitlab_api/__init__.py +0 -91
- gitlab_api-27.3.9/gitlab_api/__main__.py +0 -4
- gitlab_api-27.3.9/gitlab_api/connector_sources.py +0 -261
- gitlab_api-27.3.9/gitlab_api/prompts/__init__.py +0 -0
- gitlab_api-27.3.9/gitlab_api/skills/__init__.py +0 -0
- gitlab_api-27.3.9/gitlab_api.egg-info/entry_points.txt +0 -17
- gitlab_api-27.3.9/requirements.txt +0 -1
- gitlab_api-27.3.9/scripts/security_sanitizer.py +0 -326
- gitlab_api-27.3.9/scripts/verify_api_integration.py +0 -323
- gitlab_api-27.3.9/tests/__init__.py +0 -0
- gitlab_api-27.3.9/tests/test_default_content_surfaces.py +0 -43
- gitlab_api-27.3.9/tests/test_security_sanitizer.py +0 -30
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/LICENSE +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/__init__.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_base.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_environments.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_issues.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_merge_requests.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_other.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_pipelines.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_projects.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_repositories.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_system.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_users_groups.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api/api_client_vulnerabilities.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/api_client.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/auth.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/gitlab_gql.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/gitlab_input_models.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/gitlab_response_models.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/instances.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/mcp_config.json +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/__init__.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/fixtures/records.json +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/gitlab.ttl +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/migrations/manifest.json +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/ontology/shapes/connector.shacl.ttl +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/prompts/devops_specialist.json +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-api-operations/SKILL.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-api-operations/agents/openai.yaml +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-api-operations/references/catalog.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-issues/SKILL.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-issues/WORKFLOW.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-merge-request-create/SKILL.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-merge-request-create/WORKFLOW.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-merge-request-review/SKILL.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-merge-request-review/WORKFLOW.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-pipelines/SKILL.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-pipelines/WORKFLOW.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-vulnerabilities/SKILL.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api/skills/gitlab-vulnerabilities/WORKFLOW.md +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api.egg-info/dependency_links.txt +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/gitlab_api.egg-info/top_level.txt +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/scripts/check_import_safety.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/scripts/security_contract.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/setup.cfg +0 -0
- {gitlab_api-27.3.9/gitlab_api/connectors → gitlab_api-27.3.11/tests}/__init__.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/conftest.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_api_wrapper.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_auth.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_connector_prep.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_gitlab_a2a_validation.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_gitlab_gql.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_gitlab_mcp_validation.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_gitlab_models.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_identity_context_scoping.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_init_dynamics.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_instances.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_ontology_parent_link.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_startup.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/test_verify_agent.py +0 -0
- {gitlab_api-27.3.9 → gitlab_api-27.3.11}/tests/verify_a2a_queries.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlab-api
|
|
3
|
-
Version: 27.3.
|
|
3
|
+
Version: 27.3.11
|
|
4
4
|
Summary: GitLab API + MCP Server
|
|
5
|
-
Author-email:
|
|
5
|
+
Author-email: Repository Maintainers <maintainers@knuckles.team>
|
|
6
6
|
License: MIT
|
|
7
7
|
Classifier: Development Status :: 5 - Production/Stable
|
|
8
8
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Requires-Python: >=3.12
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: agent-connector-sdk[graphql,mcp]<
|
|
15
|
+
Requires-Dist: agent-connector-sdk[graphql,mcp]<0.6.0,>=0.5.2
|
|
16
16
|
Requires-Dist: python-dotenv>=1.2.4
|
|
17
17
|
Provides-Extra: mcp
|
|
18
18
|
Provides-Extra: all
|
|
@@ -45,8 +45,6 @@ Dynamic: license-file
|
|
|
45
45
|

|
|
46
46
|

|
|
47
47
|
|
|
48
|
-
*Version: 27.3.9*
|
|
49
|
-
|
|
50
48
|
> **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
|
|
51
49
|
> backing GitLab instance are maintained in the
|
|
52
50
|
> [official documentation](https://knuckles-team.github.io/gitlab-api/).
|
|
@@ -20,8 +20,6 @@
|
|
|
20
20
|

|
|
21
21
|

|
|
22
22
|
|
|
23
|
-
*Version: 27.3.9*
|
|
24
|
-
|
|
25
23
|
> **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
|
|
26
24
|
> backing GitLab instance are maintained in the
|
|
27
25
|
> [official documentation](https://knuckles-team.github.io/gitlab-api/).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
from agent_connector_sdk.connector import Connector
|
|
4
|
+
|
|
5
|
+
from gitlab_api.api_client import Api
|
|
6
|
+
from gitlab_api.auth import get_client
|
|
7
|
+
from gitlab_api.mcp_server import register_prompts
|
|
8
|
+
|
|
9
|
+
connector = Connector(
|
|
10
|
+
api=Api,
|
|
11
|
+
get_client=get_client,
|
|
12
|
+
tools="gitlab_api.mcp_server",
|
|
13
|
+
instructions="GitLab API MCP Server - Manage projects, issues, merge requests, branches, and more.",
|
|
14
|
+
extra_registrations=(register_prompts,),
|
|
15
|
+
)
|
|
@@ -708,7 +708,7 @@ class ExistingNativeCommitter:
|
|
|
708
708
|
# The import is lazy so model-only tooling does not resolve the engine.
|
|
709
709
|
import asyncio
|
|
710
710
|
|
|
711
|
-
from .kg_ingest import
|
|
711
|
+
from .kg_ingest import STREAM
|
|
712
712
|
|
|
713
713
|
# ``ingest_entities`` is the only connector write authority. Its SDK
|
|
714
714
|
# ingest facade is async; this adapter's ``commit`` contract (NE-110)
|
|
@@ -723,7 +723,7 @@ class ExistingNativeCommitter:
|
|
|
723
723
|
del client, graph, idempotency_key
|
|
724
724
|
try:
|
|
725
725
|
result = asyncio.run(
|
|
726
|
-
|
|
726
|
+
STREAM.entities(
|
|
727
727
|
[dict(entity) for entity in entities],
|
|
728
728
|
[dict(relationship) for relationship in relationships],
|
|
729
729
|
)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""Data sources of this connector, declared by tool name (generated by connector-ontology-map migrate).
|
|
2
|
+
|
|
3
|
+
Served live as ``connector://resources``. Regenerate by editing the declarations, not the tools.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# ruff: noqa: E501
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from agent_connector_sdk.ingest.live_declaration import source_meta
|
|
10
|
+
|
|
11
|
+
SOURCES = (
|
|
12
|
+
source_meta(
|
|
13
|
+
tool="gitlab_get_issues",
|
|
14
|
+
source_id="issues",
|
|
15
|
+
record_type="Issue",
|
|
16
|
+
id_field="id",
|
|
17
|
+
arguments={
|
|
18
|
+
"max_pages": 1,
|
|
19
|
+
"per_page": 50,
|
|
20
|
+
"state": "opened",
|
|
21
|
+
},
|
|
22
|
+
cursor_field="updated_at",
|
|
23
|
+
description="Open GitLab issues visible to the configured token (first 50).",
|
|
24
|
+
records_path="data",
|
|
25
|
+
text_field="description",
|
|
26
|
+
title_field="title",
|
|
27
|
+
),
|
|
28
|
+
source_meta(
|
|
29
|
+
tool="gitlab_get_projects",
|
|
30
|
+
source_id="projects",
|
|
31
|
+
record_type="Project",
|
|
32
|
+
id_field="id",
|
|
33
|
+
cursor_field="last_activity_at",
|
|
34
|
+
description="GitLab projects visible to the configured token.",
|
|
35
|
+
incremental=True,
|
|
36
|
+
page_param="page",
|
|
37
|
+
page_size_param="per_page",
|
|
38
|
+
pagination="page",
|
|
39
|
+
preset={
|
|
40
|
+
"doc_type": "repository",
|
|
41
|
+
"page_kind": "number",
|
|
42
|
+
"params_style": "args",
|
|
43
|
+
},
|
|
44
|
+
records_path="data",
|
|
45
|
+
server="gitlab-mcp",
|
|
46
|
+
text_field="description",
|
|
47
|
+
title_field="path_with_namespace",
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
SCHEMA_VERSION = 2
|
|
52
|
+
|
|
53
|
+
FIELD_SETS = {
|
|
54
|
+
"fields_1": {
|
|
55
|
+
"createdAt": "xsd:dateTime",
|
|
56
|
+
"duration": "xsd:decimal",
|
|
57
|
+
"failureReason": "xsd:string",
|
|
58
|
+
"finishedAt": "xsd:dateTime",
|
|
59
|
+
"iid": "xsd:string",
|
|
60
|
+
"logUrl": "xsd:string",
|
|
61
|
+
"pipelineStatus": "xsd:string",
|
|
62
|
+
"ref": "xsd:string",
|
|
63
|
+
"sha": "xsd:string",
|
|
64
|
+
"startedAt": "xsd:dateTime",
|
|
65
|
+
"state": "xsd:string",
|
|
66
|
+
"triggerSource": "xsd:string",
|
|
67
|
+
"webUrl": "xsd:string",
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
SCHEMA_MAPPINGS = {
|
|
72
|
+
"CheckRun": {
|
|
73
|
+
"field_sets": ["fields_1"],
|
|
74
|
+
"ontology_class": "PipelineRun",
|
|
75
|
+
},
|
|
76
|
+
"Epic": {
|
|
77
|
+
"field_sets": ["fields_1"],
|
|
78
|
+
"ontology_class": "WorkItem",
|
|
79
|
+
},
|
|
80
|
+
"GitLabGroup": {
|
|
81
|
+
"field_sets": ["fields_1"],
|
|
82
|
+
"ontology_class": "IdentityGroup",
|
|
83
|
+
},
|
|
84
|
+
"Issue": {
|
|
85
|
+
"field_sets": ["fields_1"],
|
|
86
|
+
"ontology_class": "WorkItem",
|
|
87
|
+
},
|
|
88
|
+
"Job": {
|
|
89
|
+
"field_sets": ["fields_1"],
|
|
90
|
+
"ontology_class": "Action",
|
|
91
|
+
},
|
|
92
|
+
"MergeRequest": {
|
|
93
|
+
"field_sets": ["fields_1"],
|
|
94
|
+
"ontology_class": "PullRequest",
|
|
95
|
+
},
|
|
96
|
+
"Pipeline": {
|
|
97
|
+
"field_sets": ["fields_1"],
|
|
98
|
+
"ontology_class": "PipelineRun",
|
|
99
|
+
},
|
|
100
|
+
"Project": {
|
|
101
|
+
"field_sets": ["fields_1"],
|
|
102
|
+
"ontology_class": "SoftwareProject",
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
RESOURCES = (
|
|
107
|
+
{
|
|
108
|
+
"id_prefix": "checkrun",
|
|
109
|
+
"label": "Check Run",
|
|
110
|
+
"name": "CheckRun",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id_prefix": "epic",
|
|
114
|
+
"label": "Epic",
|
|
115
|
+
"name": "Epic",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id_prefix": "gitlabgroup",
|
|
119
|
+
"label": "GitLab Group",
|
|
120
|
+
"name": "GitLabGroup",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"id_prefix": "issue",
|
|
124
|
+
"label": "Issue",
|
|
125
|
+
"name": "Issue",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id_prefix": "job",
|
|
129
|
+
"label": "Job",
|
|
130
|
+
"name": "Job",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id_prefix": "mergerequest",
|
|
134
|
+
"label": "Merge Request",
|
|
135
|
+
"name": "MergeRequest",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id_prefix": "pipeline",
|
|
139
|
+
"label": "Pipeline",
|
|
140
|
+
"name": "Pipeline",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id_prefix": "project",
|
|
144
|
+
"label": "Project",
|
|
145
|
+
"name": "Project",
|
|
146
|
+
},
|
|
147
|
+
)
|
|
@@ -14,65 +14,11 @@ from __future__ import annotations
|
|
|
14
14
|
from typing import Any
|
|
15
15
|
|
|
16
16
|
from agent_connector_sdk.ingest import (
|
|
17
|
-
ChangeSet,
|
|
18
|
-
Entity,
|
|
19
|
-
IngestBinding,
|
|
20
|
-
IngestError,
|
|
21
17
|
KnowledgeIngest,
|
|
22
|
-
|
|
23
|
-
current_ingest,
|
|
18
|
+
SourceStream,
|
|
24
19
|
)
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
_ENTITY_RESERVED_KEYS = frozenset({"id", "node_type"})
|
|
29
|
-
_RELATIONSHIP_RESERVED_KEYS = frozenset({"source", "target", "relationship"})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def _to_entity(record: dict[str, Any]) -> Entity:
|
|
33
|
-
return Entity(
|
|
34
|
-
id=record.get("id"),
|
|
35
|
-
node_type=record.get("node_type"),
|
|
36
|
-
properties={
|
|
37
|
-
key: value
|
|
38
|
-
for key, value in record.items()
|
|
39
|
-
if key not in _ENTITY_RESERVED_KEYS
|
|
40
|
-
},
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def _to_relationship(record: dict[str, Any]) -> Relationship:
|
|
45
|
-
properties = {
|
|
46
|
-
key: value
|
|
47
|
-
for key, value in record.items()
|
|
48
|
-
if key not in _RELATIONSHIP_RESERVED_KEYS
|
|
49
|
-
}
|
|
50
|
-
return Relationship(
|
|
51
|
-
source=record["source"],
|
|
52
|
-
target=record["target"],
|
|
53
|
-
relationship=record["relationship"],
|
|
54
|
-
properties=properties or None,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
async def ingest_entities(
|
|
59
|
-
entities: list[dict[str, Any]],
|
|
60
|
-
relationships: list[dict[str, Any]] | None = None,
|
|
61
|
-
*,
|
|
62
|
-
ingest: KnowledgeIngest | None = None,
|
|
63
|
-
) -> dict[str, int]:
|
|
64
|
-
"""Write canonical typed nodes and relationships through the SDK ingest facade."""
|
|
65
|
-
if not entities:
|
|
66
|
-
raise IngestError("ingest_entities needs at least one entity")
|
|
67
|
-
change_set = ChangeSet(
|
|
68
|
-
entities=tuple(_to_entity(entity) for entity in entities),
|
|
69
|
-
relationships=tuple(
|
|
70
|
-
_to_relationship(relationship) for relationship in relationships or ()
|
|
71
|
-
),
|
|
72
|
-
)
|
|
73
|
-
service = ingest or current_ingest()
|
|
74
|
-
receipt = await service.submit(_BINDING, change_set)
|
|
75
|
-
return {"nodes": receipt.affected_count, "edges": receipt.relationship_count}
|
|
21
|
+
STREAM = SourceStream.for_package(__package__.split(".")[0], "gitlab")
|
|
76
22
|
|
|
77
23
|
|
|
78
24
|
async def ingest_projects(
|
|
@@ -116,7 +62,7 @@ async def ingest_projects(
|
|
|
116
62
|
"relationship": "partOfGroup",
|
|
117
63
|
}
|
|
118
64
|
)
|
|
119
|
-
return await
|
|
65
|
+
return await STREAM.entities(entities, relationships, ingest=ingest)
|
|
120
66
|
|
|
121
67
|
|
|
122
68
|
def _map_pipeline_run(
|
|
@@ -292,4 +238,4 @@ async def ingest_pipeline_runs(
|
|
|
292
238
|
entities.extend(job_entities)
|
|
293
239
|
relationships.extend(job_relationships)
|
|
294
240
|
|
|
295
|
-
return await
|
|
241
|
+
return await STREAM.entities(entities, relationships, ingest=ingest)
|
|
@@ -3,7 +3,6 @@ import warnings
|
|
|
3
3
|
|
|
4
4
|
from fastmcp import Context, FastMCP
|
|
5
5
|
from fastmcp.dependencies import Depends
|
|
6
|
-
from fastmcp.utilities.logging import get_logger
|
|
7
6
|
from pydantic import Field
|
|
8
7
|
|
|
9
8
|
# Filter RequestsDependencyWarning early to prevent log spam
|
|
@@ -20,27 +19,15 @@ with warnings.catch_warnings():
|
|
|
20
19
|
warnings.filterwarnings("ignore", message=".*urllib3.*or chardet.*")
|
|
21
20
|
warnings.filterwarnings("ignore", message=".*urllib3.*or charset_normalizer.*")
|
|
22
21
|
|
|
23
|
-
import logging
|
|
24
|
-
import os
|
|
25
|
-
import sys
|
|
26
22
|
from collections.abc import Callable
|
|
27
23
|
from typing import Any
|
|
28
24
|
|
|
29
|
-
from agent_connector_sdk.config import
|
|
25
|
+
from agent_connector_sdk.config import setting
|
|
30
26
|
from agent_connector_sdk.mcp.action_dispatch import resolve_action
|
|
31
27
|
from agent_connector_sdk.mcp.concurrency import run_blocking
|
|
32
|
-
from agent_connector_sdk.mcp.server import create_mcp_server
|
|
33
|
-
from agent_connector_sdk.mcp.tool_surface import register_tool_surface
|
|
34
28
|
|
|
35
|
-
from gitlab_api.api_client import Api
|
|
36
29
|
from gitlab_api.auth import get_client
|
|
37
30
|
|
|
38
|
-
__version__ = "27.3.9"
|
|
39
|
-
print(f"Gitlab MCP v{__version__}", file=sys.stderr)
|
|
40
|
-
|
|
41
|
-
logger = get_logger(name="mcp_server")
|
|
42
|
-
logger.setLevel(logging.DEBUG)
|
|
43
|
-
|
|
44
31
|
DEFAULT_GITLAB_URL = setting("GITLAB_URL", "https://gitlab.com")
|
|
45
32
|
DEFAULT_GITLAB_TOKEN = setting("GITLAB_TOKEN", None)
|
|
46
33
|
|
|
@@ -1329,54 +1316,3 @@ def register_graphql_ops_tools(mcp: FastMCP):
|
|
|
1329
1316
|
return await run_blocking(method, **kwargs)
|
|
1330
1317
|
except Exception as e:
|
|
1331
1318
|
return {"error": f"GraphQL operation '{action}' failed: {type(e).__name__}"}
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
def get_mcp_instance() -> tuple[Any, Any, Any, Any]:
|
|
1335
|
-
"""Initialize and return the GitLab MCP instance, args, and middlewares."""
|
|
1336
|
-
load_config()
|
|
1337
|
-
os.environ["FASTMCP_LOG_LEVEL"] = "ERROR"
|
|
1338
|
-
os.environ["TERM"] = "dumb"
|
|
1339
|
-
os.environ["NO_COLOR"] = "1"
|
|
1340
|
-
|
|
1341
|
-
args, mcp, middlewares = create_mcp_server(
|
|
1342
|
-
name="GitLab",
|
|
1343
|
-
version=__version__,
|
|
1344
|
-
instructions="GitLab API MCP Server - Manage projects, issues, merge requests, branches, and more.",
|
|
1345
|
-
)
|
|
1346
|
-
|
|
1347
|
-
registered_tags = register_tool_surface(
|
|
1348
|
-
mcp,
|
|
1349
|
-
client_cls=Api,
|
|
1350
|
-
get_client=get_client,
|
|
1351
|
-
service="gitlab-api",
|
|
1352
|
-
tools_module=sys.modules[__name__],
|
|
1353
|
-
)
|
|
1354
|
-
register_prompts(mcp)
|
|
1355
|
-
|
|
1356
|
-
for mw in middlewares:
|
|
1357
|
-
mcp.add_middleware(mw)
|
|
1358
|
-
|
|
1359
|
-
return mcp, args, middlewares, registered_tags
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
def mcp_server() -> None:
|
|
1363
|
-
mcp, args, middlewares, registered_tags = get_mcp_instance()
|
|
1364
|
-
print(f"{'gitlab-api'} MCP v{__version__}", file=sys.stderr)
|
|
1365
|
-
print("\nStarting MCP Server", file=sys.stderr)
|
|
1366
|
-
print(f" Transport: {args.transport.upper()}", file=sys.stderr)
|
|
1367
|
-
print(f" Auth: {args.auth_type}", file=sys.stderr)
|
|
1368
|
-
print(f" Dynamic Tags Loaded: {len(set(registered_tags))}", file=sys.stderr)
|
|
1369
|
-
|
|
1370
|
-
if args.transport == "stdio":
|
|
1371
|
-
mcp.run(transport="stdio")
|
|
1372
|
-
elif args.transport == "streamable-http":
|
|
1373
|
-
mcp.run(transport="streamable-http", host=args.host, port=args.port)
|
|
1374
|
-
elif args.transport == "sse":
|
|
1375
|
-
mcp.run(transport="sse", host=args.host, port=args.port)
|
|
1376
|
-
else:
|
|
1377
|
-
logger.error("Invalid transport", extra={"transport": args.transport})
|
|
1378
|
-
sys.exit(1)
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
if __name__ == "__main__":
|
|
1382
|
-
mcp_server()
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"api_version": "
|
|
2
|
+
"api_version": "graphos.io/v1",
|
|
3
3
|
"artifacts": {
|
|
4
4
|
"gitlab_api/ontology/fixtures/records.json": "5f0417820053941933f15b3f459750753f4e8e34cf1e7853fd030c1143356b40",
|
|
5
|
-
"gitlab_api/ontology/gitlab.ttl": "
|
|
6
|
-
"gitlab_api/ontology/mappings/source.yaml": "
|
|
5
|
+
"gitlab_api/ontology/gitlab.ttl": "c7f170c5ba51d657be7bad3f27595c8d91639f46e3259efffd486cfb60969240",
|
|
6
|
+
"gitlab_api/ontology/mappings/source.yaml": "4d845dd7df9503ae3a5d133ff00a98191d11adf3af7f6868f45c22bcbf098bb5",
|
|
7
7
|
"gitlab_api/ontology/migrations/manifest.json": "442c3c53df0b42c866eef7255b1889b8ada6f9f9c5125cad65d6b50dc6362a3e",
|
|
8
8
|
"gitlab_api/ontology/shapes/connector.shacl.ttl": "20d2bfc3827fd6327a3b6f25828b41d9de3f855867c46264a7e0aa7f951c76fa"
|
|
9
9
|
},
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
"synthetic_fixture_contract": "passed"
|
|
16
16
|
},
|
|
17
17
|
"compatibility": {
|
|
18
|
-
"
|
|
18
|
+
"agent_utilities": ">=2.5.0,<3",
|
|
19
19
|
"bundle_schema": "2",
|
|
20
20
|
"epistemic_graph": ">=2.27.0,<3"
|
|
21
21
|
},
|
|
22
|
-
"connector": "gitlab-
|
|
22
|
+
"connector": "gitlab-api",
|
|
23
23
|
"kind": "ConnectorSourceAttestation",
|
|
24
24
|
"live_certified": false,
|
|
25
25
|
"mode": "offline-source",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"signer": "UNSIGNED-PREVIEW",
|
|
30
30
|
"signing_public_key": "",
|
|
31
31
|
"status": "source-validated",
|
|
32
|
-
"validated_at": "2026-
|
|
32
|
+
"validated_at": "2026-10-24T06:01:53Z"
|
|
33
33
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlab-api
|
|
3
|
-
Version: 27.3.
|
|
3
|
+
Version: 27.3.11
|
|
4
4
|
Summary: GitLab API + MCP Server
|
|
5
|
-
Author-email:
|
|
5
|
+
Author-email: Repository Maintainers <maintainers@knuckles.team>
|
|
6
6
|
License: MIT
|
|
7
7
|
Classifier: Development Status :: 5 - Production/Stable
|
|
8
8
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Requires-Python: >=3.12
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: agent-connector-sdk[graphql,mcp]<
|
|
15
|
+
Requires-Dist: agent-connector-sdk[graphql,mcp]<0.6.0,>=0.5.2
|
|
16
16
|
Requires-Dist: python-dotenv>=1.2.4
|
|
17
17
|
Provides-Extra: mcp
|
|
18
18
|
Provides-Extra: all
|
|
@@ -45,8 +45,6 @@ Dynamic: license-file
|
|
|
45
45
|

|
|
46
46
|

|
|
47
47
|
|
|
48
|
-
*Version: 27.3.9*
|
|
49
|
-
|
|
50
48
|
> **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
|
|
51
49
|
> backing GitLab instance are maintained in the
|
|
52
50
|
> [official documentation](https://knuckles-team.github.io/gitlab-api/).
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
LICENSE
|
|
2
|
-
MANIFEST.in
|
|
3
2
|
README.md
|
|
4
3
|
pyproject.toml
|
|
5
|
-
requirements.txt
|
|
6
4
|
gitlab_api/__init__.py
|
|
7
5
|
gitlab_api/__main__.py
|
|
8
6
|
gitlab_api/api_client.py
|
|
@@ -34,7 +32,6 @@ gitlab_api/api/api_client_repositories.py
|
|
|
34
32
|
gitlab_api/api/api_client_system.py
|
|
35
33
|
gitlab_api/api/api_client_users_groups.py
|
|
36
34
|
gitlab_api/api/api_client_vulnerabilities.py
|
|
37
|
-
gitlab_api/connectors/__init__.py
|
|
38
35
|
gitlab_api/ontology/__init__.py
|
|
39
36
|
gitlab_api/ontology/certification.json
|
|
40
37
|
gitlab_api/ontology/gitlab.ttl
|
|
@@ -42,9 +39,7 @@ gitlab_api/ontology/fixtures/records.json
|
|
|
42
39
|
gitlab_api/ontology/mappings/source.yaml
|
|
43
40
|
gitlab_api/ontology/migrations/manifest.json
|
|
44
41
|
gitlab_api/ontology/shapes/connector.shacl.ttl
|
|
45
|
-
gitlab_api/prompts/__init__.py
|
|
46
42
|
gitlab_api/prompts/devops_specialist.json
|
|
47
|
-
gitlab_api/skills/__init__.py
|
|
48
43
|
gitlab_api/skills/gitlab-api-operations/SKILL.md
|
|
49
44
|
gitlab_api/skills/gitlab-api-operations/agents/openai.yaml
|
|
50
45
|
gitlab_api/skills/gitlab-api-operations/references/catalog.md
|
|
@@ -60,15 +55,12 @@ gitlab_api/skills/gitlab-vulnerabilities/SKILL.md
|
|
|
60
55
|
gitlab_api/skills/gitlab-vulnerabilities/WORKFLOW.md
|
|
61
56
|
scripts/check_import_safety.py
|
|
62
57
|
scripts/security_contract.py
|
|
63
|
-
scripts/security_sanitizer.py
|
|
64
|
-
scripts/verify_api_integration.py
|
|
65
58
|
tests/__init__.py
|
|
66
59
|
tests/conftest.py
|
|
67
60
|
tests/test_api_wrapper.py
|
|
68
61
|
tests/test_auth.py
|
|
69
62
|
tests/test_connector_prep.py
|
|
70
63
|
tests/test_cq_paths.py
|
|
71
|
-
tests/test_default_content_surfaces.py
|
|
72
64
|
tests/test_fleet_name.py
|
|
73
65
|
tests/test_gitlab_a2a_validation.py
|
|
74
66
|
tests/test_gitlab_api_brute_force_coverage.py
|
|
@@ -82,7 +74,6 @@ tests/test_instances.py
|
|
|
82
74
|
tests/test_kg_ingest.py
|
|
83
75
|
tests/test_mock_coverage.py
|
|
84
76
|
tests/test_ontology_parent_link.py
|
|
85
|
-
tests/test_security_sanitizer.py
|
|
86
77
|
tests/test_startup.py
|
|
87
78
|
tests/test_tool_modes.py
|
|
88
79
|
tests/test_verify_agent.py
|
|
@@ -4,15 +4,15 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gitlab-api"
|
|
7
|
-
version = "27.3.
|
|
7
|
+
version = "27.3.11"
|
|
8
8
|
description = "GitLab API + MCP Server"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
classifiers = [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", "Environment :: Console", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3",]
|
|
11
11
|
requires-python = ">=3.12"
|
|
12
|
-
dependencies = [ "agent-connector-sdk[mcp
|
|
12
|
+
dependencies = [ "agent-connector-sdk[graphql,mcp]>=0.5.2,<0.6.0", "python-dotenv>=1.2.4",]
|
|
13
13
|
[[project.authors]]
|
|
14
|
-
name = "
|
|
15
|
-
email = "maintainers@
|
|
14
|
+
name = "Repository Maintainers"
|
|
15
|
+
email = "maintainers@knuckles.team"
|
|
16
16
|
|
|
17
17
|
[project.license]
|
|
18
18
|
text = "MIT"
|
|
@@ -24,23 +24,14 @@ test = [
|
|
|
24
24
|
"pytest-xdist>=3.8.0", "pytest>=9.1.1", "pytest-asyncio>=1.4.0", "pytest-cov>=7.1.0",]
|
|
25
25
|
|
|
26
26
|
[project.scripts]
|
|
27
|
-
gitlab-mcp = "
|
|
28
|
-
|
|
29
|
-
[project.entry-points."agent_connector_sdk.skill_providers"]
|
|
30
|
-
gitlab-api = "gitlab_api.skills"
|
|
31
|
-
|
|
32
|
-
[project.entry-points."agent_connector_sdk.ontology_providers"]
|
|
33
|
-
gitlab-api = "gitlab_api.ontology"
|
|
34
|
-
|
|
35
|
-
[project.entry-points."agent_connector_sdk.source_connector_providers"]
|
|
36
|
-
gitlab-api = "gitlab_api.connectors"
|
|
27
|
+
gitlab-mcp = "agent_connector_sdk.cli:serve"
|
|
37
28
|
|
|
38
29
|
[project.entry-points."agent_connector_sdk.prompt_providers"]
|
|
39
30
|
gitlab-api = "gitlab_api.prompts"
|
|
40
31
|
|
|
41
32
|
# The one declared connector identity: the fleet name (SDK-CONNECTOR-CONTROL-R071).
|
|
42
33
|
[project.entry-points."agent_connector_sdk.connector"]
|
|
43
|
-
gitlab-mcp = "gitlab_api"
|
|
34
|
+
gitlab-mcp = "gitlab_api:connector"
|
|
44
35
|
|
|
45
36
|
[tool.uv.workspace]
|
|
46
37
|
members = ["."]
|
|
@@ -55,6 +46,7 @@ override-dependencies = [
|
|
|
55
46
|
|
|
56
47
|
|
|
57
48
|
[tool.ruff]
|
|
49
|
+
extend-exclude = ["tests", "scripts"]
|
|
58
50
|
line-length = 88
|
|
59
51
|
target-version = "py312"
|
|
60
52
|
|
|
@@ -83,3 +75,12 @@ ignore_names = ["request", "config"]
|
|
|
83
75
|
|
|
84
76
|
[tool.pipelines_hooks.ste]
|
|
85
77
|
exempt = ["specs/*", "specs/**/*"]
|
|
78
|
+
|
|
79
|
+
[tool.pipelines.container]
|
|
80
|
+
debug_apt = ["default-jre", "ripgrep", "tree", "fd-find", "curl", "nano", "build-essential", "cmake", "libssl-dev", "libcurl4-openssl-dev", "pkg-config", "cargo", "rustc"]
|
|
81
|
+
|
|
82
|
+
[tool.pipelines.ontology]
|
|
83
|
+
shape_classes = ["Branch", "CheckRun", "Commit", "Epic", "GitLabGroup", "Issue", "Job", "MergeRequest", "Milestone", "Pipeline", "PipelineRun", "Project", "Release", "Runner"]
|
|
84
|
+
|
|
85
|
+
[tool.pipelines.api_integration]
|
|
86
|
+
baseline = 1.5
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from agent_connector_sdk.ingest import load_declaration
|
|
6
6
|
import re
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
@@ -43,7 +43,7 @@ def test_merge_request_and_check_run_extend_shared_classes() -> None:
|
|
|
43
43
|
def test_no_mapping_has_a_null_ontology_class() -> None:
|
|
44
44
|
unmapped = [
|
|
45
45
|
name
|
|
46
|
-
for name, mapping in
|
|
46
|
+
for name, mapping in load_declaration("gitlab_api").schema_mappings.items()
|
|
47
47
|
if not mapping.ontology_class
|
|
48
48
|
]
|
|
49
49
|
assert unmapped == []
|
|
@@ -35,7 +35,7 @@ def _call_connectors(path: Path) -> list[str]:
|
|
|
35
35
|
def test_connector_name_is_the_fleet_name() -> None:
|
|
36
36
|
pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
37
37
|
assert pyproject["project"]["entry-points"]["agent_connector_sdk.connector"] == {
|
|
38
|
-
FLEET: "gitlab_api"
|
|
38
|
+
FLEET: "gitlab_api:connector"
|
|
39
39
|
}
|
|
40
40
|
assert connector_name("gitlab_api") == FLEET
|
|
41
41
|
for module in sorted(PACKAGE.glob("*.py")):
|