mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
feat(self-hosted): implement queryLogs for the MCP debugging tools (#48900)
> [!IMPORTANT] > > Only merge this when (https://github.com/supabase/platform/pull/36804) is merged, as the AI assistant will not have access to the `query_logs` tool for the remote MCP server ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Feature (self-hosted / CLI Studio MCP server). ## What is the current behavior? Self-hosted `getDebuggingOperations` (`apps/studio/lib/api/self-hosted/mcp.ts`) implements only `getLogs`, so the MCP `debugging` group exposes `get_logs` — a fixed per-service log dump built by `getLogQuery`. Logs are served by Logflare, which speaks BigQuery SQL. ## What is the new behavior? Bumps `@supabase/mcp-server-supabase` to `^0.10.0` (adds `query_logs` + `logsDialect`, and hides `get_logs` wherever a platform declares `queryLogs`) and moves logs over to it. - **Self-hosted `query_logs`:** declares `logsDialect: 'bigquery'` and implements `queryLogs`, passing the model's SQL straight through to the same Logflare `logs.all` endpoint (arbitrary `sql` param) — no new endpoint, no dialect translation. - **Drops `get_logs` from self-hosted:** `getLogs` throws (the server hides it once `queryLogs` exists) and the per-service `getLogQuery` builder is deleted; the model now writes its own BigQuery SQL, guided by the dialect schema hint. - **Honors no-logs mode:** `query_logs` throws when `logs:all` is disabled — the self-hosted default, enabled via the `docker-compose.logs.yml` override. - **Assistant:** switches the dashboard assistant from `get_logs` to `query_logs` (allowlist, drift guard, prompt, mocks, evals). Refs AI-1046 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * AI debugging can query recent project logs using read-only SQL. * Log queries support optional time-range filters, filtering, aggregation, and joins. * Self-hosted debugging checks whether logging is enabled before running queries. * **Bug Fixes** * Updated debugging workflows and validation to consistently use the new log-query capability. * Removed reliance on legacy service-specific log filtering and query behavior. * **Documentation** * Updated MCP debugging tool guidance to describe SQL-based log queries. * **Tests** * Expanded coverage for enabled, disabled, and unsupported logging scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b5462a9609
commit
47595f8ac7
14 files changed
+134
-157
No files matched your search
@@ -56,7 +56,7 @@ The Supabase MCP server provides tools organized into feature groups. All groups
|
||||
|
||||
### Debugging
|
||||
|
||||
- `get_logs` - Retrieve service logs (API, Postgres, Edge Functions, Auth, Storage, Realtime)
|
||||
- `query_logs` - Run a read-only SQL query against project logs to filter, aggregate, or join across log fields
|
||||
- `get_advisors` - Get security and performance advisors
|
||||
|
||||
### Development
|
||||
|
||||
@@ -11,7 +11,7 @@ export const dataset: AssistantEvalCase[] = [
|
||||
prompt: 'Check if my project is having issues right now and tell me what to fix first.',
|
||||
},
|
||||
expected: {
|
||||
requiredTools: ['get_advisors', 'get_logs'],
|
||||
requiredTools: ['get_advisors', 'query_logs'],
|
||||
},
|
||||
metadata: { category: ['debugging', 'rls_policies'] },
|
||||
},
|
||||
|
||||
@@ -741,7 +741,7 @@ export const CHAT_PROMPT = `
|
||||
- Use \`deploy_edge_function\` solely for deployment, not for presenting example code.
|
||||
## Project Health Checks
|
||||
- Use \`get_advisors\` to identify project issues; if unavailable, suggest the user use the Supabase dashboard.
|
||||
- Use \`get_logs\` to access recent project logs.
|
||||
- Use \`query_logs\` to access recent project logs by running a read-only SQL query against them.
|
||||
## Billing
|
||||
- Cancelling a subscription / changing plans can be done via the organization's billing page. Link directly to https://supabase.com/dashboard/org/_/billing.
|
||||
- To check organization usage, use the organization's usage page. Link directly to https://supabase.com/dashboard/org/_/usage.
|
||||
|
||||
@@ -34,7 +34,7 @@ describe('tool allowance by opt-in level', () => {
|
||||
list_policies: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
// Log tools
|
||||
get_advisors: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
get_logs: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
query_logs: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
} as unknown as ToolSet
|
||||
|
||||
const filtered = filterToolsByOptInLevel(mockTools, optInLevel as any)
|
||||
@@ -61,7 +61,7 @@ describe('tool allowance by opt-in level', () => {
|
||||
expect(tools).not.toContain('list_extensions')
|
||||
expect(tools).not.toContain('list_edge_functions')
|
||||
expect(tools).not.toContain('list_branches')
|
||||
expect(tools).not.toContain('get_logs')
|
||||
expect(tools).not.toContain('query_logs')
|
||||
expect(tools).not.toContain('get_advisors')
|
||||
})
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('tool allowance by opt-in level', () => {
|
||||
expect(tools).toContain('list_policies')
|
||||
expect(tools).toContain('search_docs')
|
||||
expect(tools).not.toContain('get_advisors')
|
||||
expect(tools).not.toContain('get_logs')
|
||||
expect(tools).not.toContain('query_logs')
|
||||
})
|
||||
|
||||
it('should return UI, schema and log tools for schema_and_log opt-in level', () => {
|
||||
@@ -92,7 +92,7 @@ describe('tool allowance by opt-in level', () => {
|
||||
expect(tools).toContain('list_policies')
|
||||
expect(tools).toContain('search_docs')
|
||||
expect(tools).toContain('get_advisors')
|
||||
expect(tools).toContain('get_logs')
|
||||
expect(tools).toContain('query_logs')
|
||||
})
|
||||
|
||||
it('should return all tools for schema_and_log_and_data opt-in level', () => {
|
||||
@@ -107,7 +107,7 @@ describe('tool allowance by opt-in level', () => {
|
||||
expect(tools).toContain('list_policies')
|
||||
expect(tools).toContain('search_docs')
|
||||
expect(tools).toContain('get_advisors')
|
||||
expect(tools).toContain('get_logs')
|
||||
expect(tools).toContain('query_logs')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -126,7 +126,7 @@ describe('filterToolsByOptInLevel', () => {
|
||||
search_docs: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
// Log tools
|
||||
get_advisors: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
get_logs: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
query_logs: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
// Unknown tool - should be filtered out entirely
|
||||
some_other_tool: { execute: vitest.fn().mockResolvedValue({ status: 'success' }) },
|
||||
} as unknown as ToolSet
|
||||
@@ -182,7 +182,7 @@ describe('filterToolsByOptInLevel', () => {
|
||||
'list_branches',
|
||||
'list_policies',
|
||||
'get_advisors',
|
||||
'get_logs',
|
||||
'query_logs',
|
||||
])
|
||||
})
|
||||
|
||||
@@ -196,14 +196,14 @@ describe('filterToolsByOptInLevel', () => {
|
||||
'list_branches',
|
||||
'list_policies',
|
||||
'get_advisors',
|
||||
'get_logs',
|
||||
'query_logs',
|
||||
])
|
||||
})
|
||||
|
||||
it('should stub log tools for schema opt-in level', async () => {
|
||||
const tools = filterToolsByOptInLevel(mockTools, 'schema')
|
||||
|
||||
await expectStubsFor(tools, ['get_advisors', 'get_logs'])
|
||||
await expectStubsFor(tools, ['get_advisors', 'query_logs'])
|
||||
})
|
||||
|
||||
// No execute_sql tool, so nothing additional to stub for schema_and_log opt-in level
|
||||
@@ -276,7 +276,7 @@ describe('toolSetValidationSchema', () => {
|
||||
execute_sql: { inputSchema: z.object({}), execute: vitest.fn() },
|
||||
deploy_edge_function: { inputSchema: z.object({}), execute: vitest.fn() },
|
||||
rename_chat: { inputSchema: z.object({}), execute: vitest.fn() },
|
||||
get_logs: { inputSchema: z.object({}), execute: vitest.fn() },
|
||||
query_logs: { inputSchema: z.object({}), execute: vitest.fn() },
|
||||
}
|
||||
|
||||
const validationResult = toolSetValidationSchema.safeParse(allExpectedTools)
|
||||
|
||||
@@ -26,7 +26,7 @@ export const toolSetValidationSchema = z.record(
|
||||
'list_branches',
|
||||
'search_docs',
|
||||
'get_advisors',
|
||||
'get_logs',
|
||||
'query_logs',
|
||||
|
||||
// Local tools
|
||||
'execute_sql',
|
||||
@@ -101,7 +101,7 @@ export const TOOL_CATEGORY_MAP: Record<string, ToolCategory> = {
|
||||
|
||||
// Log tools - MCP and local
|
||||
get_advisors: TOOL_CATEGORIES.LOG,
|
||||
get_logs: TOOL_CATEGORIES.LOG,
|
||||
query_logs: TOOL_CATEGORIES.LOG,
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@ const FULL_REMOTE_TOOLS = {
|
||||
list_edge_functions: { description: 'edge functions' },
|
||||
list_branches: { description: 'branches' },
|
||||
get_advisors: { description: 'advisors' },
|
||||
get_logs: { description: 'get logs' },
|
||||
query_logs: { description: 'query logs' },
|
||||
execute_sql: { description: 'execute sql' },
|
||||
deploy_edge_function: { description: 'deploy' },
|
||||
}
|
||||
@@ -53,7 +53,7 @@ describe('ai/tools/mcp-tools getMcpTools', () => {
|
||||
const result = await getMcpTools(BASE_PARAMS)
|
||||
|
||||
expect(result).toHaveProperty('list_tables')
|
||||
expect(result).toHaveProperty('get_logs')
|
||||
expect(result).toHaveProperty('query_logs')
|
||||
expect(result).not.toHaveProperty('execute_sql')
|
||||
expect(result).not.toHaveProperty('deploy_edge_function')
|
||||
})
|
||||
|
||||
@@ -34,7 +34,7 @@ const EXPECTED_MCP_TOOLS = [
|
||||
'list_edge_functions',
|
||||
'list_branches',
|
||||
'get_advisors',
|
||||
'get_logs',
|
||||
'query_logs',
|
||||
] as const satisfies readonly SupabaseMcpToolName[]
|
||||
|
||||
export const getMcpTools = async ({
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('ai/tools/mock-tools getMockTools', () => {
|
||||
expect(result).toHaveProperty('search_docs', SEARCH_DOCS)
|
||||
// A couple of the deterministic mocks, to confirm the merge
|
||||
expect(result).toHaveProperty('list_tables')
|
||||
expect(result).toHaveProperty('get_logs')
|
||||
expect(result).toHaveProperty('query_logs')
|
||||
})
|
||||
|
||||
// This is the regression guard: if the eval's MCP wiring breaks (contract
|
||||
|
||||
@@ -13,11 +13,10 @@ const getAdvisorsInputSchema = z.object({
|
||||
type: z.enum(['security', 'performance']).optional(),
|
||||
})
|
||||
|
||||
const getLogsInputSchema = z.object({
|
||||
limit: z.number().min(1).max(100).optional(),
|
||||
level: z.enum(['debug', 'info', 'warning', 'error']).optional(),
|
||||
source: z.enum(['postgres', 'auth', 'storage', 'edge_function']).optional(),
|
||||
search: z.string().optional(),
|
||||
const queryLogsInputSchema = z.object({
|
||||
sql: z.string().min(1),
|
||||
iso_timestamp_start: z.string().optional(),
|
||||
iso_timestamp_end: z.string().optional(),
|
||||
})
|
||||
|
||||
const listPoliciesInputSchema = z.object({
|
||||
@@ -218,40 +217,13 @@ function createMockGetAdvisorsTool() {
|
||||
})
|
||||
}
|
||||
|
||||
function createMockGetLogsTool() {
|
||||
function createMockQueryLogsTool() {
|
||||
return tool({
|
||||
description: 'Fetches recent project logs for debugging or health checks (mocked).',
|
||||
inputSchema: getLogsInputSchema,
|
||||
execute: async ({
|
||||
limit = 10,
|
||||
level,
|
||||
source,
|
||||
search,
|
||||
}: {
|
||||
limit?: number
|
||||
level?: 'debug' | 'info' | 'warning' | 'error'
|
||||
source?: 'postgres' | 'auth' | 'storage' | 'edge_function'
|
||||
search?: string
|
||||
}) => {
|
||||
let filtered = MOCK_LOGS_DATA
|
||||
|
||||
if (level) {
|
||||
filtered = filtered.filter((entry) => entry.level === level)
|
||||
}
|
||||
|
||||
if (source) {
|
||||
filtered = filtered.filter((entry) => entry.source === source)
|
||||
}
|
||||
|
||||
if (search) {
|
||||
const needle = search.toLowerCase()
|
||||
filtered = filtered.filter((entry) =>
|
||||
`${entry.message} ${entry.target}`.toLowerCase().includes(needle)
|
||||
)
|
||||
}
|
||||
|
||||
return filtered.slice(0, limit)
|
||||
},
|
||||
description:
|
||||
'Runs a read-only SQL query against recent project logs for debugging or health checks (mocked).',
|
||||
inputSchema: queryLogsInputSchema,
|
||||
// Deterministic mock: returns static log data regardless of the SQL passed.
|
||||
execute: async () => MOCK_LOGS_DATA,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -335,7 +307,7 @@ export async function getMockTools(overrides: MockToolOverrides | undefined, sig
|
||||
list_extensions: createMockListExtensionsTool(),
|
||||
list_edge_functions: createMockListEdgeFunctionsTool(),
|
||||
get_advisors: createMockGetAdvisorsTool(),
|
||||
get_logs: createMockGetLogsTool(),
|
||||
query_logs: createMockQueryLogsTool(),
|
||||
list_policies: createMockListPoliciesTool(),
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import assert from 'node:assert'
|
||||
import { LogsService } from '@supabase/mcp-server-supabase/platform'
|
||||
import { stripIndent } from 'common-tags'
|
||||
|
||||
import { WrappedResult } from './types'
|
||||
import { assertSelfHosted } from './util'
|
||||
@@ -71,67 +69,3 @@ export async function retrieveAnalyticsData({
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export function getLogQuery(service: LogsService, limit: number = 100): string {
|
||||
assertSelfHosted()
|
||||
|
||||
switch (service) {
|
||||
case 'api': {
|
||||
return stripIndent`
|
||||
select id, edge_logs.timestamp, event_message, request.method, request.path, request.search, response.status_code
|
||||
from edge_logs
|
||||
cross join unnest(metadata) as m
|
||||
cross join unnest(m.request) as request
|
||||
cross join unnest(m.response) as response
|
||||
order by timestamp desc
|
||||
limit ${limit};
|
||||
`
|
||||
}
|
||||
case 'branch-action': {
|
||||
throw new Error('Branching is only supported in the hosted Supabase platform')
|
||||
}
|
||||
case 'postgres': {
|
||||
return stripIndent`
|
||||
select postgres_logs.timestamp, id, event_message, parsed.error_severity, parsed.detail, parsed.hint
|
||||
from postgres_logs
|
||||
cross join unnest(metadata) as m
|
||||
cross join unnest(m.parsed) as parsed
|
||||
order by timestamp desc
|
||||
limit ${limit};
|
||||
`
|
||||
}
|
||||
case 'edge-function': {
|
||||
return stripIndent`
|
||||
select id, function_edge_logs.timestamp, event_message
|
||||
from function_edge_logs
|
||||
order by timestamp desc
|
||||
limit ${limit}
|
||||
`
|
||||
}
|
||||
case 'auth': {
|
||||
return stripIndent`
|
||||
select id, auth_logs.timestamp, event_message, metadata.level, metadata.status, metadata.path, metadata.msg as msg, metadata.error from auth_logs
|
||||
cross join unnest(metadata) as metadata
|
||||
order by timestamp desc
|
||||
limit ${limit};
|
||||
`
|
||||
}
|
||||
case 'storage': {
|
||||
return stripIndent`
|
||||
select id, storage_logs.timestamp, event_message from storage_logs
|
||||
order by timestamp desc
|
||||
limit ${limit};
|
||||
`
|
||||
}
|
||||
case 'realtime': {
|
||||
return stripIndent`
|
||||
select id, realtime_logs.timestamp, event_message from realtime_logs
|
||||
order by timestamp desc
|
||||
limit ${limit};
|
||||
`
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unsupported log service: ${service}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { getDevelopmentOperations } from './mcp'
|
||||
import { getDebuggingOperations, getDevelopmentOperations } from './mcp'
|
||||
|
||||
vi.mock('./settings', () => ({
|
||||
getProjectSettings: vi.fn(),
|
||||
@@ -10,6 +10,14 @@ vi.mock('./generate-types', () => ({
|
||||
generateTypescriptTypes: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('./logs', () => ({
|
||||
retrieveAnalyticsData: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('./lints', () => ({
|
||||
getLints: vi.fn(),
|
||||
}))
|
||||
|
||||
describe('api/self-hosted/mcp', () => {
|
||||
describe('getDevelopmentOperations.getPublishableKeys', () => {
|
||||
let getProjectSettingsMock: ReturnType<typeof vi.fn>
|
||||
@@ -78,4 +86,55 @@ describe('api/self-hosted/mcp', () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDebuggingOperations', () => {
|
||||
let retrieveAnalyticsDataMock: ReturnType<typeof vi.fn>
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks()
|
||||
vi.unstubAllEnvs()
|
||||
const logs = await import('./logs')
|
||||
retrieveAnalyticsDataMock = vi.mocked(logs.retrieveAnalyticsData)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs()
|
||||
})
|
||||
|
||||
it('getLogs is not supported on self-hosted (query_logs supersedes it)', async () => {
|
||||
const ops = getDebuggingOperations({})
|
||||
|
||||
// `get_logs` is hidden by the MCP server whenever `queryLogs` is present,
|
||||
// so this method is unreachable over MCP and throws defensively.
|
||||
await expect(ops.getLogs('default', { service: 'api' })).rejects.toThrow(
|
||||
'get_logs is not supported on self-hosted'
|
||||
)
|
||||
expect(retrieveAnalyticsDataMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('queryLogs throws when logs are disabled (self-hosted default)', async () => {
|
||||
vi.stubEnv('ENABLED_FEATURES_LOGS_ALL', 'false')
|
||||
|
||||
const ops = getDebuggingOperations({})
|
||||
|
||||
await expect(ops.queryLogs!('default', { sql: 'select 1' })).rejects.toThrow(
|
||||
'Logs are disabled on this instance'
|
||||
)
|
||||
expect(retrieveAnalyticsDataMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('queryLogs passes the model-provided SQL straight through when logs are enabled', async () => {
|
||||
vi.stubEnv('ENABLED_FEATURES_LOGS_ALL', 'true')
|
||||
retrieveAnalyticsDataMock.mockResolvedValue({ data: ['log entry'], error: null })
|
||||
|
||||
const ops = getDebuggingOperations({})
|
||||
await ops.queryLogs!('default', { sql: 'select * from edge_logs' })
|
||||
|
||||
expect(retrieveAnalyticsDataMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
params: expect.objectContaining({ sql: 'select * from edge_logs' }),
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -6,13 +6,15 @@ import {
|
||||
DebuggingOperations,
|
||||
DevelopmentOperations,
|
||||
ExecuteSqlOptions,
|
||||
GetLogsOptions,
|
||||
QueryLogsOptions,
|
||||
} from '@supabase/mcp-server-supabase/platform'
|
||||
import { isFeatureEnabled, type Feature } from 'common/enabled-features'
|
||||
import { getEnabledFeaturesOverrideDisabledList } from 'common/enabled-features/overrides'
|
||||
|
||||
import { DEFAULT_EXPOSED_SCHEMAS } from './constants'
|
||||
import { generateTypescriptTypes } from './generate-types'
|
||||
import { getLints } from './lints'
|
||||
import { getLogQuery, retrieveAnalyticsData } from './logs'
|
||||
import { retrieveAnalyticsData } from './logs'
|
||||
import { applyAndTrackMigrations, listMigrationVersions } from './migrations'
|
||||
import { executeQuery } from './query'
|
||||
import { getProjectSettings } from './settings'
|
||||
@@ -113,18 +115,42 @@ export function getDevelopmentOperations({
|
||||
}
|
||||
}
|
||||
|
||||
// Logs are disabled by default for self-hosted; enabled via the
|
||||
// `docker-compose.logs.yml` override, which sets ENABLED_FEATURES_LOGS_ALL=true.
|
||||
function assertLogsEnabled() {
|
||||
const disabledFeatures = getEnabledFeaturesOverrideDisabledList(process.env) as Feature[]
|
||||
|
||||
if (!isFeatureEnabled('logs:all', disabledFeatures)) {
|
||||
throw new Error(
|
||||
'Logs are disabled on this instance. Enable the `docker-compose.logs.yml` override to query logs.'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function getDebuggingOperations({
|
||||
headers,
|
||||
}: GetDebuggingOperationsOptions): DebuggingOperations {
|
||||
return {
|
||||
async getLogs(projectRef: string, options: GetLogsOptions) {
|
||||
const sql = getLogQuery(options.service)
|
||||
// Self-hosted logs are served by Logflare, which speaks BigQuery SQL.
|
||||
logsDialect: 'bigquery',
|
||||
// `query_logs` replaces `get_logs` on self-hosted. Declaring `queryLogs`
|
||||
// makes the MCP server hide `get_logs` from clients (see `getDebuggingTools`
|
||||
// in @supabase/mcp-server-supabase), so this method is never reached over
|
||||
// MCP. The `DebuggingOperations` interface still requires it, so it throws
|
||||
// defensively rather than serving logs.
|
||||
async getLogs() {
|
||||
throw new Error('get_logs is not supported on self-hosted; use query_logs instead.')
|
||||
},
|
||||
async queryLogs(projectRef: string, options: QueryLogsOptions) {
|
||||
assertLogsEnabled()
|
||||
|
||||
// Pass the model's SQL straight through to the Logflare `logs.all`
|
||||
// endpoint, which accepts an arbitrary `sql` param.
|
||||
const { data, error } = await retrieveAnalyticsData({
|
||||
name: 'logs.all',
|
||||
projectRef,
|
||||
params: {
|
||||
sql,
|
||||
sql: options.sql,
|
||||
iso_timestamp_start: options.iso_timestamp_start,
|
||||
iso_timestamp_end: options.iso_timestamp_end,
|
||||
},
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"@stripe/stripe-js": "9.1.0",
|
||||
"@stripe/sync-engine": "1.0.32",
|
||||
"@supabase/auth-js": "catalog:",
|
||||
"@supabase/mcp-server-supabase": "^0.7.0",
|
||||
"@supabase/mcp-server-supabase": "^0.10.0",
|
||||
"@supabase/pg-meta": "workspace:*",
|
||||
"@supabase/realtime-js": "catalog:",
|
||||
"@supabase/shared-types": "0.1.91",
|
||||
|
||||
Generated
+12
-26
@@ -985,8 +985,8 @@ importers:
|
||||
specifier: 'catalog:'
|
||||
version: 2.112.3
|
||||
'@supabase/mcp-server-supabase':
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)
|
||||
specifier: ^0.10.0
|
||||
version: 0.10.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)
|
||||
'@supabase/pg-meta':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/pg-meta
|
||||
@@ -3864,10 +3864,6 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
|
||||
'@eslint-community/regexpp@4.12.1':
|
||||
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
|
||||
'@eslint-community/regexpp@4.12.2':
|
||||
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
@@ -7719,15 +7715,15 @@ packages:
|
||||
resolution: {integrity: sha512-gfv481mTOVWtZIJgXupxZpni2V2UWPf6jeF/jOK7HdMHdH+mt6sU0sHHwf0POsPip8ltlulu9OUHgwVzl5ddRw==}
|
||||
engines: {node: '>=22.0.0'}
|
||||
|
||||
'@supabase/mcp-server-supabase@0.7.0':
|
||||
resolution: {integrity: sha512-t0sOS27T5mDxp6jUYSh3zuyjWhYZarbXCPUO7HTVSyPq2smY6d5UM4Lko81eawYCSRDE8qwDZOKnVkXwCS4RSg==}
|
||||
'@supabase/mcp-server-supabase@0.10.0':
|
||||
resolution: {integrity: sha512-CVnB+4wBFsQeYwr5phNZyG33nNPUVBAJFB99vn55Z5Zn5+sxopybBPeYtrz8J9rqLkXad/xb7Xow4sz0JMq/XQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@modelcontextprotocol/sdk': ^1.25.2
|
||||
zod: ^3.25.0 || ^4.0.0
|
||||
|
||||
'@supabase/mcp-utils@0.4.0':
|
||||
resolution: {integrity: sha512-mJ06GYLLZGW4zfz4yl08P2wrx0ORqW5iIAFyqvWJAInIjoa3w7EfJs/h+RbvCE+x7UYuSQeDUXpLJc4lJWDBKA==}
|
||||
'@supabase/mcp-utils@0.6.0':
|
||||
resolution: {integrity: sha512-4r7RTEMZgFw4VqTgsQrM0KUWXdEOASPHEjIfuBaGb0SXPHIIe6W8xBnocidjtfQnKagxMJb0RXY4rqwwShJ2zw==}
|
||||
peerDependencies:
|
||||
'@modelcontextprotocol/sdk': ^1.25.2
|
||||
zod: ^3.25.0 || ^4.0.0
|
||||
@@ -11303,10 +11299,6 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
esquery@1.5.0:
|
||||
resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
esquery@1.7.0:
|
||||
resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
|
||||
engines: {node: '>=0.10'}
|
||||
@@ -19382,8 +19374,6 @@ snapshots:
|
||||
eslint: 9.37.0(jiti@2.7.0)(supports-color@8.1.1)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/regexpp@4.12.1': {}
|
||||
|
||||
'@eslint-community/regexpp@4.12.2': {}
|
||||
|
||||
'@eslint/compat@2.1.0(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))':
|
||||
@@ -23731,18 +23721,18 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@supabase/mcp-server-supabase@0.7.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)':
|
||||
'@supabase/mcp-server-supabase@0.10.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@mjackson/multipart-parser': 0.10.1
|
||||
'@modelcontextprotocol/sdk': 1.29.0(supports-color@8.1.1)(zod@3.25.76)
|
||||
'@supabase/mcp-utils': 0.4.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)
|
||||
'@supabase/mcp-utils': 0.6.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)
|
||||
common-tags: 1.8.2
|
||||
gqlmin: 0.3.1
|
||||
graphql: 16.11.0
|
||||
openapi-fetch: 0.13.8
|
||||
zod: 3.25.76
|
||||
|
||||
'@supabase/mcp-utils@0.4.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)':
|
||||
'@supabase/mcp-utils@0.6.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@modelcontextprotocol/sdk': 1.29.0(supports-color@8.1.1)(zod@3.25.76)
|
||||
zod: 3.25.76
|
||||
@@ -27722,8 +27712,8 @@ snapshots:
|
||||
|
||||
eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint-community/eslint-utils': 4.10.1(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@eslint/config-array': 0.21.0(supports-color@8.1.1)
|
||||
'@eslint/config-helpers': 0.4.0
|
||||
'@eslint/core': 0.16.0
|
||||
@@ -27743,7 +27733,7 @@ snapshots:
|
||||
eslint-scope: 8.4.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
espree: 10.4.0
|
||||
esquery: 1.5.0
|
||||
esquery: 1.7.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
file-entry-cache: 8.0.0
|
||||
@@ -27777,10 +27767,6 @@ snapshots:
|
||||
|
||||
esprima@4.0.1: {}
|
||||
|
||||
esquery@1.5.0:
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
|
||||
esquery@1.7.0:
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
|
||||
Reference in new issue
Block a user