@selfhost.dev/mcp-server 0.7.0 → 0.9.0
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.
- package/README.md +118 -17
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/alerts.js +83 -12
- package/dist/tools/alerts.js.map +1 -1
- package/dist/tools/auth.js +13 -1
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/backups.js +197 -18
- package/dist/tools/backups.js.map +1 -1
- package/dist/tools/billing.js +5 -1
- package/dist/tools/billing.js.map +1 -1
- package/dist/tools/capacity.d.ts +2 -0
- package/dist/tools/capacity.js +253 -0
- package/dist/tools/capacity.js.map +1 -0
- package/dist/tools/database-users.js +33 -6
- package/dist/tools/database-users.js.map +1 -1
- package/dist/tools/deployments.js +14 -16
- package/dist/tools/deployments.js.map +1 -1
- package/dist/tools/env-vars.js +23 -0
- package/dist/tools/env-vars.js.map +1 -1
- package/dist/tools/github.js +65 -4
- package/dist/tools/github.js.map +1 -1
- package/dist/tools/instance-logs.d.ts +2 -0
- package/dist/tools/instance-logs.js +151 -0
- package/dist/tools/instance-logs.js.map +1 -0
- package/dist/tools/instances.js +251 -25
- package/dist/tools/instances.js.map +1 -1
- package/dist/tools/organizations.js +107 -13
- package/dist/tools/organizations.js.map +1 -1
- package/dist/tools/postgres-tls.d.ts +16 -0
- package/dist/tools/postgres-tls.js +64 -0
- package/dist/tools/postgres-tls.js.map +1 -0
- package/dist/tools/project-activities.d.ts +2 -0
- package/dist/tools/project-activities.js +52 -0
- package/dist/tools/project-activities.js.map +1 -0
- package/dist/tools/project-backups.d.ts +2 -0
- package/dist/tools/project-backups.js +159 -0
- package/dist/tools/project-backups.js.map +1 -0
- package/dist/tools/project-databases.js +26 -2
- package/dist/tools/project-databases.js.map +1 -1
- package/dist/tools/project-services.js +136 -25
- package/dist/tools/project-services.js.map +1 -1
- package/dist/tools/projects.js +151 -5
- package/dist/tools/projects.js.map +1 -1
- package/dist/tools/scaling.js +401 -36
- package/dist/tools/scaling.js.map +1 -1
- package/dist/tools/webhooks.d.ts +2 -0
- package/dist/tools/webhooks.js +195 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/types/models.d.ts +8 -1
- package/dist/types/tiers.js +5 -0
- package/dist/types/tiers.js.map +1 -1
- package/package.json +3 -2
package/dist/tools/github.js
CHANGED
|
@@ -6,10 +6,12 @@ import { session } from "../session.js";
|
|
|
6
6
|
* list branches, auto-detect a repo's build config, and get the install URL.
|
|
7
7
|
*
|
|
8
8
|
* Endpoints:
|
|
9
|
-
* - GET
|
|
10
|
-
* - GET
|
|
11
|
-
* - POST
|
|
12
|
-
* -
|
|
9
|
+
* - GET /api/v1/platform/github_installations
|
|
10
|
+
* - GET /api/v1/platform/github_installations/:installation_pid/branches?repo_full_name=
|
|
11
|
+
* - POST /api/v1/platform/github_installations/detect_repo_config
|
|
12
|
+
* - DELETE /api/v1/platform/github_installations/:installation_pid (one)
|
|
13
|
+
* - DELETE /api/v1/platform/github_installations/disconnect (all, this org)
|
|
14
|
+
* - GET /github/connect?organization_pid= (returns a browser install URL)
|
|
13
15
|
*
|
|
14
16
|
* NOTE: connecting a GitHub account is an interactive, browser-based GitHub App
|
|
15
17
|
* installation - it CANNOT be completed headlessly. `get_github_connect_url`
|
|
@@ -102,5 +104,64 @@ export function registerGithubTools(server) {
|
|
|
102
104
|
}],
|
|
103
105
|
};
|
|
104
106
|
});
|
|
107
|
+
// No `connected_accounts` tool. `GET /github_installations/connected_accounts` 500s:
|
|
108
|
+
// the action calls `current_user.organization_users`, an association that does not exist
|
|
109
|
+
// (it is `organization_memberships`), so it has never worked and the console never calls
|
|
110
|
+
// it. `list_github_installations` covers the useful case for the active org.
|
|
111
|
+
server.tool("disconnect_github_installation", "DESTRUCTIVE: disconnect one GitHub App installation from the active organization. Pushes for its repos stop triggering deploys immediately. The backend refuses while deployments are still using the installation - delete or repoint those first. This only detaches it on the SelfHost side; the response includes a GitHub URL the user must open to revoke the app on GitHub itself. Reconnecting later is a browser flow (`get_github_connect_url`).", {
|
|
112
|
+
installation_pid: z.string().min(1).describe("Installation pid (ghi_...), from `list_github_installations`"),
|
|
113
|
+
confirm: z.boolean().describe("Must be true to proceed."),
|
|
114
|
+
}, async ({ installation_pid, confirm }) => {
|
|
115
|
+
if (!orgId())
|
|
116
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
117
|
+
if (!confirm) {
|
|
118
|
+
return {
|
|
119
|
+
content: [{
|
|
120
|
+
type: "text",
|
|
121
|
+
text: `⚠️ About to DISCONNECT GitHub installation ${installation_pid}. Auto-deploys from its repositories stop immediately.\n\nCall again with confirm=true to proceed.`,
|
|
122
|
+
}],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const result = await apiRequest(`${INSTALLATIONS_BASE}/${installation_pid}`, {
|
|
126
|
+
method: "DELETE",
|
|
127
|
+
toolName: "disconnect_github_installation",
|
|
128
|
+
});
|
|
129
|
+
if (!result.success) {
|
|
130
|
+
return { content: [{ type: "text", text: `Failed to disconnect installation (${result.statusCode}): ${result.message}` }] };
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
content: [
|
|
134
|
+
{ type: "text", text: "Installation disconnected. Open the GitHub revoke URL below to remove the app on GitHub's side as well." },
|
|
135
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
server.tool("disconnect_all_github_installations", "DESTRUCTIVE: disconnect EVERY GitHub App installation from the active organization at once. All auto-deploys stop. Blocked by the backend while any deployment still uses one of them. Returns `disconnected_count` and a `github_revoke_urls` list the user must open to revoke the app on GitHub. Prefer `disconnect_github_installation` when only one account should go.", {
|
|
140
|
+
confirm: z.boolean().describe("Must be true to proceed."),
|
|
141
|
+
}, async ({ confirm }) => {
|
|
142
|
+
if (!orgId())
|
|
143
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
144
|
+
if (!confirm) {
|
|
145
|
+
return {
|
|
146
|
+
content: [{
|
|
147
|
+
type: "text",
|
|
148
|
+
text: "⚠️ About to disconnect ALL GitHub installations for this organization. Every repository's auto-deploys stop immediately.\n\nCall again with confirm=true to proceed.",
|
|
149
|
+
}],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const result = await apiRequest(`${INSTALLATIONS_BASE}/disconnect`, {
|
|
153
|
+
method: "DELETE",
|
|
154
|
+
toolName: "disconnect_all_github_installations",
|
|
155
|
+
});
|
|
156
|
+
if (!result.success) {
|
|
157
|
+
return { content: [{ type: "text", text: `Failed to disconnect installations (${result.statusCode}): ${result.message}` }] };
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
content: [
|
|
161
|
+
{ type: "text", text: "GitHub installations disconnected. Open each URL in `github_revoke_urls` to revoke the app on GitHub's side as well." },
|
|
162
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
});
|
|
105
166
|
}
|
|
106
167
|
//# sourceMappingURL=github.js.map
|
package/dist/tools/github.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiRequest } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* On-demand diagnostics for a managed database instance: engine/operation log
|
|
5
|
+
* output and a query-workload snapshot. No SSH involved - the platform agent on
|
|
6
|
+
* the box runs the fetch and posts the result back.
|
|
7
|
+
*
|
|
8
|
+
* Endpoints:
|
|
9
|
+
* - GET /aws/v1/instances/:pid/logs/sources
|
|
10
|
+
* - POST /aws/v1/instances/:pid/logs (request a fetch)
|
|
11
|
+
* - GET /aws/v1/instances/:pid/logs (last 20 fetches, with output)
|
|
12
|
+
* - POST /aws/v1/instances/:pid/db_stats (request a sample)
|
|
13
|
+
* - GET /aws/v1/instances/:pid/db_stats (last 20 samples, with stats)
|
|
14
|
+
*
|
|
15
|
+
* REQUEST-THEN-READ, not a stream. POST creates a pending fetch and returns it;
|
|
16
|
+
* the agent fills in `output`/`stats` asynchronously and you re-read with the GET.
|
|
17
|
+
* The console additionally has a websocket live-tail, which is not reachable from
|
|
18
|
+
* here - MCP gets snapshots only.
|
|
19
|
+
*
|
|
20
|
+
* Postgres, MySQL and ClickHouse only. Both surfaces need a positive wallet
|
|
21
|
+
* balance, and a POST needs `cloud_instances:update`. Replicas ARE allowed
|
|
22
|
+
* deliberately - a replica's own logs are just as useful.
|
|
23
|
+
*
|
|
24
|
+
* ORG INJECTION IS LEFT ON (no `skipOrgInjection`) because `DbStatsController`
|
|
25
|
+
* looks the instance up as `find_by(pid:, orgs_pid: @current_organization&.pid)`.
|
|
26
|
+
* Without `organization_id` on the request the backend picks a fallback org for
|
|
27
|
+
* the user, and a multi-org caller then gets "Instance not found" for an instance
|
|
28
|
+
* they own. `LogsController` scopes by ownership instead and works either way, but
|
|
29
|
+
* both are kept consistent so the next edit cannot get one of them wrong.
|
|
30
|
+
*/
|
|
31
|
+
const LOG_SOURCES_NOTE = "Log sources differ per engine and `list_log_sources` is the only authority - do not guess a name, an unknown one is a 422. Every engine has `engine` (the server's own log) and a `replication` view; Postgres and MySQL add backup/restore logs, and ClickHouse adds separate backup, native-restore, fork and upgrade logs. `replication` is a server-side FILTERED view of the engine log rather than a separate file on Postgres and MySQL, so it is the right source for a replication question and will look like a subset of `engine`.";
|
|
32
|
+
export function registerInstanceLogTools(server) {
|
|
33
|
+
server.tool("list_log_sources", `List the log sources available on a managed database instance. Call this before \`fetch_instance_logs\` - the valid \`log_source\` values are per engine and per instance.
|
|
34
|
+
|
|
35
|
+
${LOG_SOURCES_NOTE}
|
|
36
|
+
|
|
37
|
+
Returns \`{sources: [{key, label}]}\`. An EMPTY list means the engine does not support log tailing at all (only Postgres, MySQL and ClickHouse do) - it does not mean something went wrong.
|
|
38
|
+
|
|
39
|
+
A 422 saying to top up means the organization's wallet is empty. This endpoint is behind the same balance gate as the fetch itself, so an empty source list and a billing block are different answers: read the message.`, {
|
|
40
|
+
instance_id: z.string().min(1, "Instance PID is required"),
|
|
41
|
+
}, async ({ instance_id }) => {
|
|
42
|
+
const result = await apiRequest(`/aws/v1/instances/${instance_id}/logs/sources`, {
|
|
43
|
+
toolName: "list_log_sources",
|
|
44
|
+
});
|
|
45
|
+
if (!result.success) {
|
|
46
|
+
return { content: [{ type: "text", text: `Failed to list log sources (${result.statusCode}): ${result.message}` }] };
|
|
47
|
+
}
|
|
48
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
49
|
+
});
|
|
50
|
+
server.tool("fetch_instance_logs", `Ask the instance for the tail of one of its logs. This is how you actually look at a database that is misbehaving - no SSH needed.
|
|
51
|
+
|
|
52
|
+
TWO STEPS. This POST creates a PENDING fetch and returns immediately; the agent on the box collects the output and posts it back a moment later. Read it with \`list_instance_log_fetches\`. The response here almost never contains the log text.
|
|
53
|
+
|
|
54
|
+
${LOG_SOURCES_NOTE}
|
|
55
|
+
|
|
56
|
+
\`lines\` defaults to 200 and is clamped to 2000. Output is capped at 1 MB per fetch, so a very chatty log is truncated rather than refused - ask for fewer lines and a specific source if you are hunting something particular.
|
|
57
|
+
|
|
58
|
+
DEDUP AND COOLDOWN, both worth understanding before you loop:
|
|
59
|
+
- A pending fetch for the same source is returned as-is instead of a second one being started. So an immediate repeat call is a no-op, not progress.
|
|
60
|
+
- After a fetch completes or fails there is a ~10s cooldown per (instance, source) and a further request is rate-limited.
|
|
61
|
+
So: request once, wait, then read. Do not poll this endpoint.
|
|
62
|
+
|
|
63
|
+
Requires the instance to be \`running\` or \`provisioned\`, with a registered agent, and \`cloud_instances:update\` (a 403 means the caller's role is too low - reading the result needs only view access). Replicas are fine.`, {
|
|
64
|
+
instance_id: z.string().min(1, "Instance PID is required"),
|
|
65
|
+
log_source: z.string().min(1).describe("A `key` from `list_log_sources` for this instance. Guessing gets a 422."),
|
|
66
|
+
lines: z.number().int().min(1).max(2000).optional().describe("Tail length; defaults to 200, clamped to 2000"),
|
|
67
|
+
}, async ({ instance_id, log_source, lines }) => {
|
|
68
|
+
const body = { log_source };
|
|
69
|
+
if (lines !== undefined)
|
|
70
|
+
body.lines = lines;
|
|
71
|
+
const result = await apiRequest(`/aws/v1/instances/${instance_id}/logs`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
body,
|
|
74
|
+
toolName: "fetch_instance_logs",
|
|
75
|
+
});
|
|
76
|
+
if (!result.success) {
|
|
77
|
+
return { content: [{ type: "text", text: `Failed to request logs (${result.statusCode}): ${result.message}` }] };
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{ type: "text", text: `Log fetch requested for \`${log_source}\`. It is pending - the agent collects the output, then read it with \`list_instance_log_fetches\`. Give it a few seconds; do not re-request, a repeat just returns this same pending fetch.` },
|
|
82
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
server.tool("list_instance_log_fetches", `Read the results of log fetches on an instance - the last 20, newest first, WITH their output. This is where the log text you asked for with \`fetch_instance_logs\` actually shows up.
|
|
87
|
+
|
|
88
|
+
Each row: \`pid\`, \`log_source\`, \`lines_requested\`, \`status\`, \`output\`, \`error\`, and timestamps.
|
|
89
|
+
|
|
90
|
+
\`status\` is \`pending\` until the agent reports back, then \`completed\` (read \`output\`) or \`failed\` (read \`error\`). A fetch whose agent result was lost is flipped to \`failed\` when you read this endpoint rather than sitting pending forever - so reading is also how a stuck fetch gets cleared.
|
|
91
|
+
|
|
92
|
+
Because the backend keeps the last 20 per instance, previous fetches are already here: check them before requesting a new one, since a recent fetch of the same source may answer the question and avoid the cooldown entirely.
|
|
93
|
+
|
|
94
|
+
Output can be up to 1 MB. Summarise what matters to the user rather than replaying the whole tail.`, {
|
|
95
|
+
instance_id: z.string().min(1, "Instance PID is required"),
|
|
96
|
+
}, async ({ instance_id }) => {
|
|
97
|
+
const result = await apiRequest(`/aws/v1/instances/${instance_id}/logs`, {
|
|
98
|
+
toolName: "list_instance_log_fetches",
|
|
99
|
+
});
|
|
100
|
+
if (!result.success) {
|
|
101
|
+
return { content: [{ type: "text", text: `Failed to read log fetches (${result.statusCode}): ${result.message}` }] };
|
|
102
|
+
}
|
|
103
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
104
|
+
});
|
|
105
|
+
server.tool("capture_db_stats", `Take a query-workload snapshot of a database: what it is actually doing right now. Use this for "why is my database slow" before reaching for metrics - metrics say the CPU is busy, this says which queries are making it busy.
|
|
106
|
+
|
|
107
|
+
SAMPLES OVER TIME. The agent reads the engine's cumulative counters twice, \`sample_seconds\` apart, and reports the difference - so the result describes that window, not a single instant. Default 10s, allowed 5 to 60. A longer sample smooths out a spiky workload; a short one catches a burst.
|
|
108
|
+
|
|
109
|
+
Same two-step shape as the logs: this POST returns a PENDING sample, and you read the result with \`list_db_stats\`. Do not poll this endpoint - a pending sample is returned as-is instead of starting a second one, and there is a per-instance cooldown after one finishes.
|
|
110
|
+
|
|
111
|
+
Postgres, MySQL and ClickHouse. NOT available on a ClickHouse keeper-only node (a keeper runs clickhouse-keeper, not clickhouse-server, so there is no query log to sample) - that is a 422 and the answer is to target a data node instead. Instance must be \`running\` or \`provisioned\` with a registered agent, and this needs \`cloud_instances:update\`.`, {
|
|
112
|
+
instance_id: z.string().min(1, "Instance PID is required"),
|
|
113
|
+
sample_seconds: z.number().int().min(5).max(60).optional().describe("Sampling window in seconds; default 10, clamped to 5-60"),
|
|
114
|
+
}, async ({ instance_id, sample_seconds }) => {
|
|
115
|
+
const body = {};
|
|
116
|
+
if (sample_seconds !== undefined)
|
|
117
|
+
body.sample_seconds = sample_seconds;
|
|
118
|
+
const result = await apiRequest(`/aws/v1/instances/${instance_id}/db_stats`, {
|
|
119
|
+
method: "POST",
|
|
120
|
+
body,
|
|
121
|
+
toolName: "capture_db_stats",
|
|
122
|
+
});
|
|
123
|
+
if (!result.success) {
|
|
124
|
+
return { content: [{ type: "text", text: `Failed to request query stats (${result.statusCode}): ${result.message}` }] };
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
content: [
|
|
128
|
+
{ type: "text", text: `Query-stats sample requested over ${sample_seconds ?? 10}s. It is pending - wait for the window to pass plus a moment, then read it with \`list_db_stats\`.` },
|
|
129
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
server.tool("list_db_stats", `Read query-workload samples for an instance - the last 20, newest first, with their results. This is where a \`capture_db_stats\` sample lands.
|
|
134
|
+
|
|
135
|
+
Each row: \`pid\`, \`sample_seconds\`, \`status\`, \`stats\`, \`error\`, and timestamps. \`status\` is \`pending\` until the agent reports, then \`completed\` (read \`stats\`) or \`failed\` (read \`error\`).
|
|
136
|
+
|
|
137
|
+
Check here first: a recent sample may already answer the question, and reusing it avoids both the sampling wait and the cooldown.
|
|
138
|
+
|
|
139
|
+
Remember what the numbers are - a delta over the sample window, not lifetime totals - so "queries per second" figures are for that window only and a quiet moment will understate a workload the user is complaining about. If the numbers look implausibly calm, take a longer sample while the problem is happening rather than concluding the database is fine.`, {
|
|
140
|
+
instance_id: z.string().min(1, "Instance PID is required"),
|
|
141
|
+
}, async ({ instance_id }) => {
|
|
142
|
+
const result = await apiRequest(`/aws/v1/instances/${instance_id}/db_stats`, {
|
|
143
|
+
toolName: "list_db_stats",
|
|
144
|
+
});
|
|
145
|
+
if (!result.success) {
|
|
146
|
+
return { content: [{ type: "text", text: `Failed to read query stats (${result.statusCode}): ${result.message}` }] };
|
|
147
|
+
}
|
|
148
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=instance-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-logs.js","sourceRoot":"","sources":["../../src/tools/instance-logs.ts"],"names":[],"mappings":"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"}
|