Skip to content

Instantly share code, notes, and snippets.

@kinlane
Created April 20, 2026 19:22
Show Gist options
  • Select an option

  • Save kinlane/2e89e5c3c0cb48bcac13c841a4113026 to your computer and use it in GitHub Desktop.

Select an option

Save kinlane/2e89e5c3c0cb48bcac13c841a4113026 to your computer and use it in GitHub Desktop.
Naftiko Capability: API Change Discovery — Aggregate (GitLab + Jira + Confluence + Slack + Google Docs)
naftiko: "1.0.0-alpha1"
info:
label: "API Change Discovery — Aggregate"
description: "Unified capability for discovering current API details, potential API changes, and public API-impacting content across five enterprise tools: GitLab (branches, jobs), Jira (issues via JQL), Confluence (pages, spaces), Slack (message search, channel history), and Google Docs (document retrieval). A single governed surface for an AI agent to search all the places where API changes are discussed, tracked, documented, and announced."
tags:
- API Discovery
- Change Management
- GitLab
- Jira
- Confluence
- Slack
- Google Docs
- Multi-Source
created: "2026-04-20"
modified: "2026-04-20"
binds:
- namespace: env
keys:
GITLAB_TOKEN: GITLAB_TOKEN
JIRA_TOKEN: JIRA_TOKEN
JIRA_EMAIL: JIRA_EMAIL
JIRA_DOMAIN: JIRA_DOMAIN
CONFLUENCE_TOKEN: CONFLUENCE_TOKEN
CONFLUENCE_EMAIL: CONFLUENCE_EMAIL
CONFLUENCE_DOMAIN: CONFLUENCE_DOMAIN
SLACK_BOT_TOKEN: SLACK_BOT_TOKEN
GOOGLE_ACCESS_TOKEN: GOOGLE_ACCESS_TOKEN
capability:
consumes:
# ── GitLab ──
- type: http
namespace: gitlab
baseUri: https://gitlab.com/api/v4
description: "GitLab REST API v4 — branches, jobs, repository state."
authentication:
type: apikey
key: Private-Token
value: "{{GITLAB_TOKEN}}"
placement: header
resources:
- name: branches
path: /projects/{id}/repository/branches
operations:
- name: list-branches
method: GET
inputParameters:
- name: id
in: path
- name: search
in: query
outputParameters:
- name: branches
type: array
value: $
- name: branch
path: /projects/{id}/repository/branches/{branch}
operations:
- name: get-branch
method: GET
inputParameters:
- name: id
in: path
- name: branch
in: path
outputParameters:
- name: branch
type: object
value: $.
- name: jobs
path: /projects/{id}/jobs
operations:
- name: list-jobs
method: GET
inputParameters:
- name: id
in: path
outputParameters:
- name: jobs
type: array
value: $
# ── Jira ──
- type: http
namespace: jira
baseUri: "https://{{JIRA_DOMAIN}}.atlassian.net/rest/api/3"
description: "Jira Cloud REST API v3 — issue search, details, comments."
authentication:
type: basic
username: "{{JIRA_EMAIL}}"
password: "{{JIRA_TOKEN}}"
resources:
- name: search
path: /search
operations:
- name: search-issues
method: GET
inputParameters:
- name: jql
in: query
- name: maxResults
in: query
- name: fields
in: query
outputParameters:
- name: issues
type: array
value: $.issues
- name: total
type: integer
value: $.total
- name: issue
path: /issue/{issueIdOrKey}
operations:
- name: get-issue
method: GET
inputParameters:
- name: issueIdOrKey
in: path
outputParameters:
- name: issue
type: object
value: $.
- name: issue-comments
path: /issue/{issueIdOrKey}/comment
operations:
- name: get-issue-comments
method: GET
inputParameters:
- name: issueIdOrKey
in: path
outputParameters:
- name: comments
type: array
value: $.comments
# ── Confluence ──
- type: http
namespace: confluence
baseUri: "https://{{CONFLUENCE_DOMAIN}}.atlassian.net/wiki/api/v2"
description: "Confluence Cloud REST API v2 — spaces, pages, content."
authentication:
type: basic
username: "{{CONFLUENCE_EMAIL}}"
password: "{{CONFLUENCE_TOKEN}}"
resources:
- name: spaces
path: /spaces
operations:
- name: list-spaces
method: GET
inputParameters:
- name: labels
in: query
- name: type
in: query
- name: limit
in: query
outputParameters:
- name: results
type: array
value: $.results
- name: pages
path: /pages
operations:
- name: list-pages
method: GET
inputParameters:
- name: title
in: query
- name: spaceId
in: query
- name: limit
in: query
outputParameters:
- name: results
type: array
value: $.results
- name: page
path: /pages/{id}
operations:
- name: get-page
method: GET
inputParameters:
- name: id
in: path
outputParameters:
- name: page
type: object
value: $.
# ── Slack ──
- type: http
namespace: slack
baseUri: https://slack.com/api
description: "Slack Web API — message search, channel history."
authentication:
type: bearer
token: "{{SLACK_BOT_TOKEN}}"
resources:
- name: search-messages
path: /search.messages
operations:
- name: search-messages
method: GET
inputParameters:
- name: query
in: query
- name: count
in: query
- name: sort
in: query
outputParameters:
- name: messages
type: object
value: $.messages
- name: conversations-list
path: /conversations.list
operations:
- name: list-conversations
method: GET
inputParameters:
- name: types
in: query
- name: exclude_archived
in: query
- name: limit
in: query
outputParameters:
- name: channels
type: array
value: $.channels
- name: conversations-history
path: /conversations.history
operations:
- name: get-conversation-history
method: GET
inputParameters:
- name: channel
in: query
- name: oldest
in: query
- name: limit
in: query
outputParameters:
- name: messages
type: array
value: $.messages
# ── Google Docs ──
- type: http
namespace: google-docs
baseUri: https://docs.googleapis.com
description: "Google Docs API v1 — document retrieval."
authentication:
type: bearer
token: "{{GOOGLE_ACCESS_TOKEN}}"
resources:
- name: document
path: /v1/documents/{documentId}
operations:
- name: get-document
method: GET
inputParameters:
- name: documentId
in: path
outputParameters:
- name: document
type: object
value: $.
exposes:
- type: mcp
port: 3000
namespace: api-change-discovery
transport: http
description: "Unified MCP tools for discovering API changes, details, and impacting content across GitLab, Jira, Confluence, Slack, and Google Docs."
tools:
# ── GitLab Tools ──
- name: gitlab-list-branches
description: "List branches in a GitLab project to find active API development streams. Search by branch name pattern (e.g. 'api-', 'feature/v2')."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: projectId
type: string
description: "GitLab project ID or URL-encoded path"
required: true
- name: search
type: string
description: "Filter branches by name pattern"
required: false
call: gitlab.list-branches
with:
id: api-change-discovery.projectId
search: api-change-discovery.search
outputParameters:
- type: array
mapping: "$."
- name: gitlab-get-branch
description: "Get details for a specific GitLab branch including latest commit message and author — understand the most recent change."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: projectId
type: string
description: "GitLab project ID or URL-encoded path"
required: true
- name: branch
type: string
description: "Branch name"
required: true
call: gitlab.get-branch
with:
id: api-change-discovery.projectId
branch: api-change-discovery.branch
outputParameters:
- type: object
mapping: "$."
- name: gitlab-list-jobs
description: "List CI/CD jobs for a GitLab project — identify builds, tests, and deployments that indicate API changes in progress."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: projectId
type: string
description: "GitLab project ID or URL-encoded path"
required: true
call: gitlab.list-jobs
with:
id: api-change-discovery.projectId
outputParameters:
- type: array
mapping: "$."
# ── Jira Tools ──
- name: jira-search-issues
description: "Search Jira issues using JQL for API changes, breaking changes, deprecations, and releases. Example: 'labels = api-change AND status != Done ORDER BY updated DESC'"
hints:
readOnly: true
idempotent: true
inputParameters:
- name: jql
type: string
description: "JQL query string"
required: true
- name: maxResults
type: integer
description: "Max results (default 50)"
required: false
call: jira.search-issues
with:
jql: api-change-discovery.jql
maxResults: api-change-discovery.maxResults
outputParameters:
- type: object
mapping: "$."
- name: jira-get-issue
description: "Get full details for a Jira issue — summary, description, status, labels, assignee, and the context behind an API change."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: issueKey
type: string
description: "Issue key (e.g. API-1234)"
required: true
call: jira.get-issue
with:
issueIdOrKey: api-change-discovery.issueKey
outputParameters:
- type: object
mapping: "$."
- name: jira-get-comments
description: "Get comments on a Jira issue — discussion about API design decisions, migration notes, and change rationale."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: issueKey
type: string
description: "Issue key (e.g. API-1234)"
required: true
call: jira.get-issue-comments
with:
issueIdOrKey: api-change-discovery.issueKey
outputParameters:
- type: object
mapping: "$."
# ── Confluence Tools ──
- name: confluence-list-spaces
description: "List Confluence spaces — find API documentation spaces and knowledge bases. Filter by label (e.g. 'api', 'platform')."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: labels
type: string
description: "Comma-separated labels to filter"
required: false
call: confluence.list-spaces
with:
labels: api-change-discovery.labels
outputParameters:
- type: array
mapping: "$.results"
- name: confluence-search-pages
description: "Search Confluence pages by title — find API specs, changelogs, migration guides, and design documents."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: title
type: string
description: "Page title to search for"
required: true
- name: spaceId
type: string
description: "Limit to a specific space ID"
required: false
call: confluence.list-pages
with:
title: api-change-discovery.title
spaceId: api-change-discovery.spaceId
outputParameters:
- type: array
mapping: "$.results"
- name: confluence-get-page
description: "Get a Confluence page with full content — read API documentation, changelogs, and design decisions."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: pageId
type: string
description: "Confluence page ID"
required: true
call: confluence.get-page
with:
id: api-change-discovery.pageId
outputParameters:
- type: object
mapping: "$."
# ── Slack Tools ──
- name: slack-search-messages
description: "Search Slack messages for API-related content — find change announcements, breaking change discussions, and team decisions about APIs."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: query
type: string
description: "Search query (e.g. 'API breaking change', 'deprecation')"
required: true
- name: count
type: integer
description: "Number of results (default 20)"
required: false
call: slack.search-messages
with:
query: api-change-discovery.query
count: api-change-discovery.count
outputParameters:
- type: object
mapping: "$."
- name: slack-list-channels
description: "List Slack channels — find channels where API changes are discussed (e.g. #api-changes, #platform-updates)."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: types
type: string
description: "Channel types: public_channel, private_channel"
required: false
call: slack.list-conversations
with:
types: api-change-discovery.types
outputParameters:
- type: array
mapping: "$.channels"
- name: slack-get-channel-history
description: "Get recent messages from a Slack channel — read the latest API announcements and discussions."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: channel
type: string
description: "Slack channel ID"
required: true
- name: limit
type: integer
description: "Number of messages (default 100)"
required: false
- name: oldest
type: string
description: "Unix timestamp — only messages after this time"
required: false
call: slack.get-conversation-history
with:
channel: api-change-discovery.channel
limit: api-change-discovery.limit
oldest: api-change-discovery.oldest
outputParameters:
- type: array
mapping: "$.messages"
# ── Google Docs Tools ──
- name: google-docs-get-document
description: "Retrieve a Google Doc by ID — read API design documents, specifications, changelogs, and decision records stored in Google Docs."
hints:
readOnly: true
idempotent: true
inputParameters:
- name: documentId
type: string
description: "Google Docs document ID (from URL)"
required: true
call: google-docs.get-document
with:
documentId: api-change-discovery.documentId
outputParameters:
- type: object
mapping: "$."
- type: rest
port: 8080
namespace: api-change-discovery-rest
description: "Unified REST API for API change discovery across all five sources."
resources:
- path: /gitlab/branches
name: gitlab-branches
description: "List GitLab project branches."
inputParameters:
- name: projectId
in: query
type: string
- name: search
in: query
type: string
operations:
- method: GET
call: gitlab.list-branches
with:
id: api-change-discovery-rest.projectId
search: api-change-discovery-rest.search
outputParameters:
- type: array
mapping: "$."
- path: /jira/search
name: jira-search
description: "Search Jira issues with JQL."
inputParameters:
- name: jql
in: query
type: string
operations:
- method: GET
call: jira.search-issues
with:
jql: api-change-discovery-rest.jql
outputParameters:
- type: object
mapping: "$."
- path: /confluence/pages
name: confluence-pages
description: "Search Confluence pages by title."
inputParameters:
- name: title
in: query
type: string
- name: spaceId
in: query
type: string
operations:
- method: GET
call: confluence.list-pages
with:
title: api-change-discovery-rest.title
spaceId: api-change-discovery-rest.spaceId
outputParameters:
- type: array
mapping: "$.results"
- path: /slack/search
name: slack-search
description: "Search Slack messages."
inputParameters:
- name: query
in: query
type: string
operations:
- method: GET
call: slack.search-messages
with:
query: api-change-discovery-rest.query
outputParameters:
- type: object
mapping: "$."
- path: /google-docs/{documentId}
name: google-doc
description: "Get a Google Doc."
inputParameters:
- name: documentId
in: path
type: string
operations:
- method: GET
call: google-docs.get-document
with:
documentId: api-change-discovery-rest.documentId
outputParameters:
- type: object
mapping: "$."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment