/** * One WordPress install, over the REST API. * * Two namespaces are in play and the difference matters to the caller. `wp/v2` * is WordPress core and is present on every modern install. `wordpress-mcp/v1` * comes from the helper plugin in this repo, and a 404 there means the plugin * is missing rather than the request being wrong, so it is translated into an * error that says which file to copy. * * Authentication is Basic with an application password. That is WordPress's own * scheme since 5.6, and the reason this server needs no OAuth app, no callback * URL and no plugin just to sign in. */ import type { Config, Site } from "../config.js"; export type FetchLike = (input: string, init?: RequestInit) => Promise; export declare const CORE_NAMESPACE = "wp/v2"; export declare const HELPER_NAMESPACE = "wordpress-mcp/v1"; /** * A list response, with the counts WordPress puts in headers rather than the body. * * Without these a model has no idea whether it saw everything or the first ten * of four hundred, and will happily report "you have 10 posts". The headers are * the only place that number exists. */ export type Paged = { data: T; total?: number; total_pages?: number; }; export declare class WpClient { readonly site: Site; private readonly config; private readonly fetchImpl; constructor(site: Site, config: Config, fetchImpl?: FetchLike); get name(): string; private authHeader; private url; /** * One request, with a deadline and a bounded retry. * * Retries cover 429 and 5xx only. A 4xx is the caller's problem and repeating * it just burns time, and a retried POST on a flaky connection is how a post * gets published twice, so writes are never retried. */ private request; /** A core GET, with the pagination headers folded in when WordPress sends them. */ get(endpoint: string, params?: Record): Promise; post(endpoint: string, body?: Record): Promise; /** * WordPress accepts POST for updates as well as PUT, and some hosts and * security plugins drop PUT entirely. POST is the safer verb on an endpoint * that treats them identically. */ update(endpoint: string, body?: Record): Promise; delete(endpoint: string, params?: Record): Promise; helperGet(endpoint: string, params?: Record, tool?: string): Promise; helperPost(endpoint: string, body?: Record, tool?: string): Promise; helperDelete(endpoint: string, tool?: string): Promise; /** * Upload bytes to the media library. * * Media is the one endpoint that does not take JSON: WordPress wants the raw * file with the filename in Content-Disposition. Title, alt text and caption * cannot be sent in the same call, so they are applied in a follow-up PATCH, * which is why this returns the updated attachment rather than the created one. */ uploadMedia(input: { bytes: Buffer; filename: string; contentType: string; }): Promise; /** Whether the helper plugin is present, for `doctor` and `wp_list_sites`. */ hasHelperPlugin(): Promise; }