3import { Context } from 'npm:hono';
4import { SSETransport } from 'npm:hono-mcp-server-sse-transport';
5import { extractGetEndpoints, extractMutationEndpoints, fetchOpenApiSpec, proxyRequest } from "./livestormApi.ts";
6
7const MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024; // 4MB
38
39 try {
40 console.log("Fetching Livestorm API OpenAPI spec...");
41 // Fetch the OpenAPI spec
42 const openApiSpec = await fetchOpenApiSpec();
43 console.log("Successfully fetched OpenAPI spec");
44
45 // Extract GET endpoints (Resources)
59
60/**
61 * Fetches the Livestorm API OpenAPI definition
62 */
63export async function fetchOpenApiSpec(): Promise<OpenApiSchema> {
64 try {
65 console.log(`Fetching OpenAPI spec from ${LIVESTORM_API_SPEC_URL}...`);
66 const response = await fetch(LIVESTORM_API_SPEC_URL);
67
68 if (!response.ok) {
69 const errorText = await response.text();
70 console.error(`Failed to fetch OpenAPI spec: ${response.status} ${response.statusText}`);
71 console.error(`Response body: ${errorText}`);
72 throw new Error(`Failed to fetch OpenAPI spec: ${response.status} ${response.statusText}`);
73 }
74
75 const yamlText = await response.text();
76 console.log(`Successfully fetched OpenAPI spec (${yamlText.length} bytes)`);
77
78 try {
92 }
93 } catch (error) {
94 console.error('Error fetching OpenAPI spec:', error);
95 throw error;
96 }
220 try {
221 // Make the request to Livestorm API
222 const response = await fetch(url, requestOptions);
223
224 // Log response status
13 "apis.coda.io"
14 ],
15 "reasoning": "This plugin needs to connect to Notion and Coda APIs to fetch variable data"
16 },
17 "permissions": [
8 const [error, setError] = useState(null);
9
10 const fetchData = async () => {
11 try {
12 const userEndpoint = new URL(USER_ENDPOINT, window.location.origin);
13
14 const res = await fetch(userEndpoint);
15 const data = await res.json();
16 if (!res.ok) {
33
34 useEffect(() => {
35 fetchData();
36 }, []);
37
38 return { data, loading, error, refetch: fetchData };
39}
40
9 const [error, setError] = useState(null);
10
11 const fetchData = async () => {
12 try {
13 const projectEndpoint = new URL(PROJECT_ENDPOINT, window.location.origin);
17 if (branchId) filesEndpoint.searchParams.append("branchId", branchId);
18
19 const { project } = await fetch(projectEndpoint).then((res) =>
20 res.json()
21 );
22 const { files } = await fetch(filesEndpoint).then((res) => res.json());
23
24 setData({ project, files });
34 useEffect(() => {
35 if (!projectId) return;
36 fetchData();
37 }, [projectId, branchId]);
38
39 return { data, loading, error, refetch: fetchData };
40}
41
8 const [error, setError] = useState(null);
9
10 const fetchData = async () => {
11 try {
12 const res = await fetch(ENDPOINT);
13 const data = await res.json();
14 if (!res.ok) {
32
33 useEffect(() => {
34 fetchData();
35 }, []);
36
37 return { data, loading, error, refetch: fetchData };
38}
39
19 setError(null);
20 try {
21 const res = await fetch(ENDPOINT, {
22 method: "POST",
23 headers: {
12 setData(null);
13 setError(null);
14 const res = await fetch(ENDPOINT, {
15 method: "POST",
16 body: JSON.stringify({
7 const [loading, setLoading] = useState(true);
8
9 const fetchData = async () => {
10 const endpoint = new URL(ENDPOINT, window.location.origin);
11 endpoint.searchParams.append("projectId", projectId);
12
13 const res = await fetch(endpoint)
14 .then(res => res.json());
15 setData(res.branches);
19 useEffect(() => {
20 if (!projectId) return;
21 fetchData();
22 }, [projectId]);
23
24 return { data, loading, refetch: fetchData };
25}
47<!--
48
49- [x] refetch project data on create/etc
50- [x] Loading favicon
51- [x] Ensure main branch is default selected