Skip to content

Commit 097294e

Browse files
committed
Create Generic get_viewer_permission Tool #7624
1 parent bf938c3 commit 097294e

4 files changed

Lines changed: 117 additions & 1 deletion

File tree

ai/mcp/server/github-workflow/openapi.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ tags:
2727
description: Operations related to repository labels
2828
- name: Issues
2929
description: Operations related to repository issues and pull requests
30+
- name: Repository
31+
description: Operations related to the repository itself
3032

3133
paths:
3234
/docs:
@@ -533,6 +535,39 @@ paths:
533535
schema:
534536
$ref: '#/components/schemas/ErrorResponse'
535537

538+
/repository/viewer-permission:
539+
get:
540+
summary: Get Viewer Permission
541+
operationId: get_viewer_permission
542+
x-annotations:
543+
readOnlyHint: true
544+
description: |
545+
Retrieves the permission level of the currently authenticated user (viewer) for the repository.
546+
547+
**When to Use:**
548+
Call this tool to determine your capabilities before attempting a restricted action (e.g., assigning an issue, merging a PR). The agent is responsible for interpreting the returned permission level.
549+
550+
**Permission Levels:**
551+
- `ADMIN`: Can read, write, and manage the repository.
552+
- `MAINTAIN`: Can read, write, and manage issues and pull requests.
553+
- `WRITE`: Can read and write to the repository.
554+
- `TRIAGE`: Can manage issues and pull requests.
555+
- `READ`: Can read the repository.
556+
tags: [Repository]
557+
responses:
558+
'200':
559+
description: The viewer's permission level for the repository.
560+
content:
561+
application/json:
562+
schema:
563+
$ref: '#/components/schemas/ViewerPermissionResponse'
564+
'500':
565+
description: Internal server error.
566+
content:
567+
application/json:
568+
schema:
569+
$ref: '#/components/schemas/ErrorResponse'
570+
536571
components:
537572
schemas:
538573
HealthCheckResponse:
@@ -816,3 +851,12 @@ components:
816851
content:
817852
type: string
818853
description: The full markdown content of the issue file.
854+
855+
ViewerPermissionResponse:
856+
type: object
857+
properties:
858+
permission:
859+
type: string
860+
description: The permission level of the viewer.
861+
enum: [ADMIN, MAINTAIN, WRITE, TRIAGE, READ]
862+
example: WRITE
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Base from '../../../../../src/core/Base.mjs';
2+
import GraphqlService from './GraphqlService.mjs';
3+
import aiConfig from '../config.mjs';
4+
import logger from '../logger.mjs';
5+
import { GET_VIEWER_PERMISSION } from './queries/repositoryQueries.mjs';
6+
7+
/**
8+
* Service for interacting with the GitHub repository itself.
9+
* @class Neo.ai.mcp.server.github-workflow.RepositoryService
10+
* @extends Neo.core.Base
11+
* @singleton
12+
*/
13+
class RepositoryService extends Base {
14+
static config = {
15+
className: 'Neo.ai.mcp.server.github-workflow.RepositoryService',
16+
singleton: true
17+
}
18+
19+
/**
20+
* Fetches the current user's permission level for the repository.
21+
* @returns {Promise<object>} A promise that resolves to an object containing the permission level or a structured error.
22+
*/
23+
async getViewerPermission() {
24+
const variables = {
25+
owner: aiConfig.owner,
26+
repo: aiConfig.repo
27+
};
28+
29+
try {
30+
const data = await GraphqlService.query(GET_VIEWER_PERMISSION, variables);
31+
const permission = data.repository.viewerPermission;
32+
logger.info(`Viewer permission for ${aiConfig.owner}/${aiConfig.repo}: ${permission}`);
33+
return { permission };
34+
} catch (error) {
35+
logger.error('Error fetching viewer permission via GraphQL:', error);
36+
return {
37+
error: 'GraphQL API request failed',
38+
message: error.message,
39+
code: 'GRAPHQL_API_ERROR'
40+
};
41+
}
42+
}
43+
}
44+
45+
export default Neo.setupClass(RepositoryService);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* GraphQL query definitions for GitHub repository data.
3+
*
4+
* @module Neo.ai.mcp.server.github-workflow.queries.repositoryQueries
5+
*/
6+
7+
/**
8+
* Query to fetch the viewer's permission level for the repository.
9+
*
10+
* This is used to determine the capabilities of the currently authenticated user.
11+
*
12+
* Variables required:
13+
* - $owner: String!
14+
* - $repo: String!
15+
*/
16+
export const GET_VIEWER_PERMISSION = `
17+
query GetViewerPermission(
18+
$owner: String!
19+
$repo: String!
20+
) {
21+
repository(owner: $owner, name: $repo) {
22+
viewerPermission
23+
}
24+
}
25+
`;

ai/mcp/server/github-workflow/services/toolService.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import {fileURLToPath} from 'url';
33
import HealthService from './HealthService.mjs';
44
import IssueService from './IssueService.mjs';
55
import LabelService from './LabelService.mjs';
6-
import LocalFileService from './LocalFileService.mjs';
6+
import LocalFileService from './LocalFileService.mjs';
77
import PullRequestService from './PullRequestService.mjs';
8+
import RepositoryService from './RepositoryService.mjs';
89
import SyncService from './SyncService.mjs';
910
import {initialize, listTools, callTool} from '../../toolService.mjs';
1011

@@ -20,6 +21,7 @@ const serviceMapping = {
2021
get_conversation : PullRequestService.getConversation.bind(PullRequestService),
2122
get_local_issue_by_id: LocalFileService.getIssueById.bind(LocalFileService),
2223
get_pull_request_diff: PullRequestService.getPullRequestDiff.bind(PullRequestService),
24+
get_viewer_permission: RepositoryService.getViewerPermission.bind(RepositoryService),
2325
healthcheck : HealthService.healthcheck.bind(HealthService),
2426
list_labels : LabelService.listLabels.bind(LabelService),
2527
list_pull_requests : PullRequestService.listPullRequests.bind(PullRequestService),

0 commit comments

Comments
 (0)