# GitHub Documentation Link Auditor (`thirdwatch/github-doc-link-auditor`) Actor

Read Markdown through a least-privilege GitHub MCP connector, validate public external links without cloning the repository, and create or update one review issue.

- **URL**: https://apify.com/thirdwatch/github-doc-link-auditor.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GitHub Documentation Link Auditor

Read selected Markdown files through an Apify GitHub MCP connector, validate their public external links, and create or update one evidence-rich GitHub issue without cloning the repository or handling a GitHub token.

### Why the connector matters

The Actor receives authorized connectors, not a personal access token. Dry runs need only a read connector exposing `get_file_contents`. Write mode adds a second connector exposing only `search_issues` and `issue_write`. Neither connector can edit repository files, create a branch, open a pull request, or merge code; the same Apify connector resource may be selected for both inputs when it has all three tools.

### Failure-aware classification

- `reachable`: final HTTP 2xx/3xx response.
- `observed_not_found`: one time-stamped HTTP 404 or 410 observation that still requires human confirmation.
- `needs_review`: authentication, rate limiting, DNS/network errors, 4xx other than 404/410, or 5xx.
- `unsafe_target`: rejected before a request because the URL contains credentials, uses a non-standard port, or resolves to loopback/private/link-local/reserved infrastructure.

Every redirect target is normalized, resolved, and checked again before it is requested. A custom resolver pins the actual connection to the public IP addresses that passed validation while preserving the original hostname for TLS verification. Environment proxies are disabled. The Actor streams response headers and does not download response bodies.

### Safe operating model

Dry run is the default. To post an issue, disable dry run and enter the exact `owner/repo` in `confirmWriteTarget`. The Actor writes at most one issue per run and updates only an issue containing its invisible ownership marker. A human-authored title collision is never overwritten. Human review remains mandatory before changing documentation.

# Actor input Schema

## `githubReadConnector` (type: `string`):

A read-only GitHub connector exposing only file reads.

## `githubWriteConnector` (type: `string`):

Required only when Dry run is off. Exposes issue search and issue write, but no repository-content mutation tools.

## `owner` (type: `string`):

GitHub organization or user that owns the authorized repository.

## `repo` (type: `string`):

Repository whose explicit Markdown paths will be audited.

## `ref` (type: `string`):

Optional branch, tag, or full ref. Leave empty for the default branch.

## `markdownPaths` (type: `array`):

Specific Markdown files to read through the connector. Missing or oversized files are reported without stopping the audit.

## `maxLinks` (type: `integer`):

Hard cap on distinct external links checked in one paid audit.

## `requestTimeoutSecs` (type: `integer`):

Total HTTP timeout for each public link check, from 3 to 15 seconds.

## `updateExistingIssue` (type: `boolean`):

Update the open Actor-owned issue for this repository/ref/path scope instead of creating another one.

## `issueLabels` (type: `array`):

Optional labels that must already exist in the repository.

## `dryRun` (type: `boolean`):

Read files and validate links without writing a GitHub issue.

## `confirmWriteTarget` (type: `string`):

Required when Dry run is off. Enter the exact owner/repo and write only to a repository you own or are explicitly authorized to modify.

## Actor input object example

```json
{
  "ref": "",
  "markdownPaths": [
    "README.md"
  ],
  "maxLinks": 100,
  "requestTimeoutSecs": 12,
  "updateExistingIssue": true,
  "issueLabels": [],
  "dryRun": true,
  "confirmWriteTarget": ""
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "markdownPaths": [
        "README.md"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/github-doc-link-auditor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "markdownPaths": ["README.md"] }

# Run the Actor and wait for it to finish
run = client.actor("thirdwatch/github-doc-link-auditor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "markdownPaths": [
    "README.md"
  ]
}' |
apify call thirdwatch/github-doc-link-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thirdwatch/github-doc-link-auditor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/jmhM0I8IIeJPDlrdJ/builds/7VVX5HLhsDMrgWrcI/openapi.json
