leaf: mcp + agent
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -22,7 +22,7 @@ supabase.sh
|
||||
tests/
|
||||
!server/tests
|
||||
!packages/mcp/tests
|
||||
!apps/chat/tests
|
||||
!apps/leaf/tests
|
||||
!vite/tests
|
||||
.secrets
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Hono } from "hono";
|
||||
import { chatAdapterNames } from "./bot.js";
|
||||
import { env } from "./lib/env.js";
|
||||
import { slackRoutes } from "./providers/slack/routes.js";
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
app.get("/health", (c) => c.json({ ok: true }));
|
||||
app.route("/slack", slackRoutes);
|
||||
|
||||
Bun.serve({
|
||||
port: env.PORT,
|
||||
fetch: app.fetch,
|
||||
});
|
||||
|
||||
console.log("Chat listening", { port: env.PORT, adapters: chatAdapterNames });
|
||||
@@ -1,4 +1,6 @@
|
||||
# Autumn Chat
|
||||
# Autumn Leaf
|
||||
|
||||
Autumn's AI service: the Slack chat bot plus the hosted MCP routes (`src/mcp/http.ts`).
|
||||
|
||||
Local Slack testing uses a normal Slack app in a development workspace. Keep the app undistributed while testing.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@autumn/chat",
|
||||
"name": "@autumn/leaf",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -14,6 +14,7 @@
|
||||
"@autumn/shared": "workspace:*",
|
||||
"@chat-adapter/slack": "^4.29.0",
|
||||
"@chat-adapter/state-pg": "^4.29.0",
|
||||
"@hono/node-server": "^1.19.5",
|
||||
"@mastra/core": "^1.36.0",
|
||||
"@mastra/mcp": "^1.8.0",
|
||||
"@mendable/firecrawl-js": "^4.25.1",
|
||||
@@ -17,6 +17,8 @@ const envSchema = z
|
||||
DATABASE_URL: z.string().min(1),
|
||||
ENCRYPTION_PASSWORD: z.string().min(1),
|
||||
FIRECRAWL_API_KEY: z.string().min(1),
|
||||
MCP_OAUTH_ENVIRONMENT: z.enum(["live", "sandbox"]).default("sandbox"),
|
||||
MCP_SERVER_URL: optionalString,
|
||||
PORT: z.coerce.number().int().positive().default(3099),
|
||||
SLACK_CLIENT_ID: z.string().min(1),
|
||||
SLACK_CLIENT_SECRET: z.string().min(1),
|
||||
@@ -30,6 +32,11 @@ const envSchema = z
|
||||
|
||||
return {
|
||||
...values,
|
||||
MCP_SERVER_URL:
|
||||
values.MCP_SERVER_URL ??
|
||||
(process.env.NODE_ENV === "production"
|
||||
? "https://api.useautumn.com"
|
||||
: "http://localhost:8080"),
|
||||
CHAT_STATE_DATABASE_URL:
|
||||
values.CHAT_STATE_DATABASE_URL ?? databaseUrl.toString(),
|
||||
CHAT_STATE_SECRET:
|
||||
42
apps/leaf/src/main.ts
Normal file
42
apps/leaf/src/main.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { createConsoleLogger } from "@autumn/mcp";
|
||||
import type { HttpBindings } from "@hono/node-server";
|
||||
import { serve } from "@hono/node-server";
|
||||
import { Hono } from "hono";
|
||||
import { chatAdapterNames } from "./bot.js";
|
||||
import { env } from "./lib/env.js";
|
||||
import { registerMcpRoutes } from "./mcp/http.js";
|
||||
import { slackRoutes } from "./providers/slack/routes.js";
|
||||
|
||||
const app = new Hono<{ Bindings: HttpBindings }>();
|
||||
|
||||
app.use("*", async (c, next) => {
|
||||
c.header("Access-Control-Allow-Origin", "*");
|
||||
c.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
c.header("Access-Control-Allow-Headers", "*");
|
||||
return c.req.method === "OPTIONS" ? c.body(null, 204) : next();
|
||||
});
|
||||
|
||||
app.get("/health", (c) => c.json({ ok: true }));
|
||||
|
||||
registerMcpRoutes(app, {
|
||||
"oauth-enabled": true,
|
||||
"oauth-environment": env.MCP_OAUTH_ENVIRONMENT,
|
||||
"server-url": env.MCP_SERVER_URL,
|
||||
logger: createConsoleLogger("info"),
|
||||
});
|
||||
|
||||
app.route("/slack", slackRoutes);
|
||||
|
||||
serve(
|
||||
{
|
||||
fetch: app.fetch,
|
||||
hostname: "0.0.0.0",
|
||||
port: env.PORT,
|
||||
},
|
||||
({ address, port }) => {
|
||||
console.log("Chat listening", {
|
||||
host: `${address}:${port}`,
|
||||
adapters: chatAdapterNames,
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -1,20 +1,19 @@
|
||||
import type { HttpBindings } from "@hono/node-server";
|
||||
import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
|
||||
import {
|
||||
buildAuthForRequest,
|
||||
type ConsoleLogger,
|
||||
createAskAutumnMCPServer,
|
||||
createAutumnOperationsMCPServer,
|
||||
getAuthorizationServerMetadata,
|
||||
getProtectedResourceMetadata,
|
||||
type ConsoleLogger,
|
||||
type MCPServerFlags,
|
||||
type OAuthEnvironment,
|
||||
OAuthHttpError,
|
||||
} from "@autumn/mcp";
|
||||
import type { Context } from "hono";
|
||||
import { Hono } from "hono";
|
||||
import type { HttpBindings } from "@hono/node-server";
|
||||
import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
|
||||
import type { Context, Hono } from "hono";
|
||||
|
||||
export interface CreateMcpHttpAppOptions extends MCPServerFlags {
|
||||
export interface McpRouteOptions extends MCPServerFlags {
|
||||
readonly "oauth-enabled": boolean;
|
||||
readonly "oauth-environment": OAuthEnvironment;
|
||||
readonly logger: ConsoleLogger;
|
||||
@@ -22,30 +21,16 @@ export interface CreateMcpHttpAppOptions extends MCPServerFlags {
|
||||
|
||||
type AppContext = Context<{ Bindings: HttpBindings }>;
|
||||
type McpPath = "/mcp" | "/internal/mcp";
|
||||
type McpApp = Hono<{ Bindings: HttpBindings }>;
|
||||
|
||||
export function createMcpHttpApp(options: CreateMcpHttpAppOptions) {
|
||||
const app = new Hono<{ Bindings: HttpBindings }>();
|
||||
|
||||
app.use("*", async (c, next) => {
|
||||
c.header("Access-Control-Allow-Origin", "*");
|
||||
c.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
c.header("Access-Control-Allow-Headers", "*");
|
||||
return c.req.method === "OPTIONS" ? c.body(null, 204) : next();
|
||||
});
|
||||
|
||||
app.get("/health", (c) => c.json({ ok: true }));
|
||||
|
||||
export function registerMcpRoutes(app: McpApp, options: McpRouteOptions) {
|
||||
app.get("/.well-known/oauth-protected-resource/mcp", (c) =>
|
||||
c.json(getProtectedResourceMetadata(c.req.raw.headers, options, "/mcp")),
|
||||
);
|
||||
|
||||
app.get("/.well-known/oauth-protected-resource/internal/mcp", (c) =>
|
||||
c.json(
|
||||
getProtectedResourceMetadata(
|
||||
c.req.raw.headers,
|
||||
options,
|
||||
"/internal/mcp",
|
||||
),
|
||||
getProtectedResourceMetadata(c.req.raw.headers, options, "/internal/mcp"),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
FROM oven/bun:1.3.10 AS pruner
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
RUN bunx turbo@2.9.14 prune @autumn/mcp-server --docker
|
||||
|
||||
FROM oven/bun:1.3.10
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=pruner /app/out/json/ .
|
||||
RUN mkdir -p scripts && touch scripts/preload-env.ts
|
||||
RUN bun -e 'const fs = require("fs"); const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); pkg.workspaces.packages = ["shared", "apps/mcp-server", "packages/ksuid", "packages/mcp"]; delete pkg.dependencies; delete pkg.devDependencies; delete pkg.scripts; fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2));'
|
||||
RUN rm bun.lock && bun install --production --ignore-scripts
|
||||
|
||||
COPY --from=pruner /app/out/full/ .
|
||||
|
||||
ENV NODE_ENV=production
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["bun", "-F", "@autumn/mcp-server", "start"]
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "@autumn/mcp-server",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun --watch src/index.ts",
|
||||
"start": "bun src/index.ts",
|
||||
"ts": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@autumn/mcp": "workspace:*",
|
||||
"@autumn/shared": "workspace:*",
|
||||
"@hono/node-server": "^1.19.5",
|
||||
"hono": "4.12.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.13",
|
||||
"@types/node": "^18.19.3",
|
||||
"typescript": "~5.8.3"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { initInfisical } from "@autumn/shared/utils/infisical";
|
||||
|
||||
await initInfisical();
|
||||
await import("./main.js");
|
||||
@@ -1,30 +0,0 @@
|
||||
import { serve } from "@hono/node-server";
|
||||
import {
|
||||
createConsoleLogger,
|
||||
type OAuthEnvironment,
|
||||
} from "@autumn/mcp";
|
||||
import { createMcpHttpApp } from "./http.js";
|
||||
|
||||
const port = Number.parseInt(process.env.PORT ?? process.env.MCP_PORT ?? "2718", 10);
|
||||
const serverURL =
|
||||
process.env.MCP_SERVER_URL ??
|
||||
(process.env.NODE_ENV === "production"
|
||||
? "https://api.useautumn.com"
|
||||
: "http://localhost:8080");
|
||||
const oauthEnvironment: OAuthEnvironment =
|
||||
process.env.MCP_OAUTH_ENVIRONMENT === "live" ? "live" : "sandbox";
|
||||
const logger = createConsoleLogger("info");
|
||||
const app = createMcpHttpApp({
|
||||
"oauth-enabled": true,
|
||||
"oauth-environment": oauthEnvironment,
|
||||
"server-url": serverURL,
|
||||
logger,
|
||||
});
|
||||
|
||||
serve({
|
||||
fetch: app.fetch,
|
||||
hostname: "0.0.0.0",
|
||||
port,
|
||||
}, ({ address, port }) => {
|
||||
logger.info("MCP server started", { host: `${address}:${port}` });
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["es2024"],
|
||||
"module": "Preserve",
|
||||
"moduleResolution": "bundler",
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "es2022",
|
||||
"types": ["bun"],
|
||||
"paths": {
|
||||
"@api/*": ["../../shared/api/*"],
|
||||
"@models/*": ["../../shared/models/*"],
|
||||
"@utils/*": ["../../shared/utils/*"],
|
||||
"@autumn/ksuid": ["../../packages/ksuid/src/index.ts"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
61
bun.lock
61
bun.lock
@@ -33,30 +33,6 @@
|
||||
"turbo": "^2.9.6",
|
||||
},
|
||||
},
|
||||
"apps/chat": {
|
||||
"name": "@autumn/chat",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@autumn/mcp": "workspace:*",
|
||||
"@autumn/shared": "workspace:*",
|
||||
"@chat-adapter/slack": "^4.29.0",
|
||||
"@chat-adapter/state-pg": "^4.29.0",
|
||||
"@mastra/core": "^1.36.0",
|
||||
"@mastra/mcp": "^1.8.0",
|
||||
"@mendable/firecrawl-js": "^4.25.1",
|
||||
"chat": "^4.29.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"drizzle-orm": "catalog:",
|
||||
"hono": "4.12.7",
|
||||
"postgres": "catalog:",
|
||||
"zod": "^3.25.23",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.3.1",
|
||||
"@types/node": "^25.0.7",
|
||||
"typescript": "^5.7.3",
|
||||
},
|
||||
},
|
||||
"apps/checkout": {
|
||||
"name": "checkout",
|
||||
"version": "0.0.0",
|
||||
@@ -108,18 +84,29 @@
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
"apps/mcp-server": {
|
||||
"name": "@autumn/mcp-server",
|
||||
"apps/leaf": {
|
||||
"name": "@autumn/leaf",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@autumn/mcp": "workspace:*",
|
||||
"@autumn/shared": "workspace:*",
|
||||
"@chat-adapter/slack": "^4.29.0",
|
||||
"@chat-adapter/state-pg": "^4.29.0",
|
||||
"@hono/node-server": "^1.19.5",
|
||||
"@mastra/core": "^1.36.0",
|
||||
"@mastra/mcp": "^1.8.0",
|
||||
"@mendable/firecrawl-js": "^4.25.1",
|
||||
"chat": "^4.29.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"drizzle-orm": "catalog:",
|
||||
"hono": "4.12.7",
|
||||
"postgres": "catalog:",
|
||||
"zod": "^3.25.23",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.13",
|
||||
"@types/node": "^18.19.3",
|
||||
"typescript": "~5.8.3",
|
||||
"@types/bun": "^1.3.1",
|
||||
"@types/node": "^25.0.7",
|
||||
"typescript": "^5.7.3",
|
||||
},
|
||||
},
|
||||
"apps/sdk-test": {
|
||||
@@ -729,15 +716,13 @@
|
||||
|
||||
"@asyncapi/specs": ["@asyncapi/specs@6.8.1", "", { "dependencies": { "@types/json-schema": "^7.0.11" } }, "sha512-czHoAk3PeXTLR+X8IUaD+IpT+g+zUvkcgMDJVothBsan+oHN3jfcFcFUNdOPAAFoUCQN1hXF1dWuphWy05THlA=="],
|
||||
|
||||
"@autumn/chat": ["@autumn/chat@workspace:apps/chat"],
|
||||
|
||||
"@autumn/docs": ["@autumn/docs@workspace:apps/docs"],
|
||||
|
||||
"@autumn/ksuid": ["@autumn/ksuid@workspace:packages/ksuid"],
|
||||
|
||||
"@autumn/mcp": ["@autumn/mcp@workspace:packages/mcp"],
|
||||
"@autumn/leaf": ["@autumn/leaf@workspace:apps/leaf"],
|
||||
|
||||
"@autumn/mcp-server": ["@autumn/mcp-server@workspace:apps/mcp-server"],
|
||||
"@autumn/mcp": ["@autumn/mcp@workspace:packages/mcp"],
|
||||
|
||||
"@autumn/openapi": ["@autumn/openapi@workspace:packages/openapi"],
|
||||
|
||||
@@ -6013,16 +5998,12 @@
|
||||
|
||||
"@asyncapi/parser/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="],
|
||||
|
||||
"@autumn/chat/@types/node": ["@types/node@25.8.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
|
||||
"@autumn/leaf/@types/node": ["@types/node@25.8.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
|
||||
|
||||
"@autumn/mcp/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
|
||||
|
||||
"@autumn/mcp/typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"@autumn/mcp-server/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
|
||||
|
||||
"@autumn/mcp-server/typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"@autumn/openapi/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="],
|
||||
|
||||
"@autumn/server/@types/node": ["@types/node@25.8.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
|
||||
@@ -7787,9 +7768,7 @@
|
||||
|
||||
"@asyncapi/parser/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"@autumn/chat/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
|
||||
|
||||
"@autumn/mcp-server/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
"@autumn/leaf/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
|
||||
|
||||
"@autumn/mcp/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Shared runtime image for server + workers + cron + mcp + chat.
|
||||
# Shared runtime image for server + workers + cron + leaf.
|
||||
# Each FlightControl service runs the same image with a different command:
|
||||
# server -> bun start (cwd /app/server)
|
||||
# workers -> bun src/workers.ts (cwd /app/server)
|
||||
# cron -> bun src/cron.ts (cwd /app/server)
|
||||
# mcp -> cd /app/apps/mcp-server && bun start
|
||||
# chat -> cd /app/apps/chat && bun start
|
||||
# leaf -> cd /app/apps/leaf && bun start (also serves the MCP routes)
|
||||
FROM oven/bun:1.3.10 AS deps
|
||||
WORKDIR /app
|
||||
|
||||
@@ -21,10 +20,9 @@ COPY server/package.json server/
|
||||
COPY shared/package.json shared/
|
||||
COPY vite/package.json vite/
|
||||
COPY scripts/package.json scripts/
|
||||
COPY apps/chat/package.json apps/chat/
|
||||
COPY apps/leaf/package.json apps/leaf/
|
||||
COPY apps/checkout/package.json apps/checkout/
|
||||
COPY apps/docs/package.json apps/docs/
|
||||
COPY apps/mcp-server/package.json apps/mcp-server/
|
||||
COPY apps/sdk-test/package.json apps/sdk-test/
|
||||
COPY apps/website/package.json apps/website/
|
||||
COPY packages/atmn/package.json packages/atmn/
|
||||
@@ -46,8 +44,7 @@ RUN mkdir -p scripts && touch scripts/preload-env.ts
|
||||
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
||||
bun install --frozen-lockfile --ignore-scripts \
|
||||
--filter @autumn/server \
|
||||
--filter @autumn/mcp-server \
|
||||
--filter @autumn/chat
|
||||
--filter @autumn/leaf
|
||||
|
||||
FROM oven/bun:1.3.10
|
||||
WORKDIR /app
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
"project": ["src/**/*.{ts,tsx}"],
|
||||
"ignoreDependencies": ["shadcn", "tailwindcss", "tw-animate-css"]
|
||||
},
|
||||
"apps/chat": {
|
||||
"apps/leaf": {
|
||||
"entry": ["tests/**/*.ts"],
|
||||
"project": ["src/**/*.ts", "tests/**/*.ts"]
|
||||
},
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
"apps/checkout",
|
||||
"apps/docs",
|
||||
"apps/website",
|
||||
"apps/mcp-server",
|
||||
"apps/chat",
|
||||
"apps/leaf",
|
||||
"apps/sdk-test",
|
||||
"packages/atmn",
|
||||
"packages/atmn-tests",
|
||||
@@ -127,15 +126,14 @@
|
||||
"knip:fix-all": "knip --fix --allow-remove-files",
|
||||
"prepare": "husky",
|
||||
"api": "cd packages/openapi && bun generate",
|
||||
"mcp": "bun scripts/mcp.ts",
|
||||
"svix:push": "infisical run --env=dev --recursive -- bun packages/openapi/scripts/svixPush.ts",
|
||||
"svix:push:prod": "infisical run --env=prod --recursive -- bun packages/openapi/scripts/svixPush.ts",
|
||||
"docs:pull": "bun -F @autumn/docs pull",
|
||||
"chat": "bun -F @autumn/chat dev",
|
||||
"leaf": "bun -F @autumn/leaf dev",
|
||||
"site": "cd apps/website && bun dev && cd ../..",
|
||||
"docs": "bun -F @autumn/docs dev",
|
||||
"docs:build": "bun -F @autumn/docs build",
|
||||
"ts": "turbo run ts --filter=@autumn/server --filter=autumn-js --filter=@autumn/openapi --filter=atmn --filter=checkout --filter=@autumn/mcp --filter=@autumn/mcp-server --filter=@autumn/chat",
|
||||
"ts": "turbo run ts --filter=@autumn/server --filter=autumn-js --filter=@autumn/openapi --filter=atmn --filter=checkout --filter=@autumn/mcp --filter=@autumn/leaf",
|
||||
"kill:ts": "while pgrep -f tsgo > /dev/null; do pkill -9 -f tsgo; sleep 0.1; done",
|
||||
"atmn:build": "bun -F atmn build",
|
||||
"openapi:ts": "bun -F @autumn/openapi ts",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
Mastra-backed MCP library for Autumn operations.
|
||||
|
||||
The hosted runtime lives in `apps/mcp-server` and exposes two Streamable HTTP
|
||||
MCP routes:
|
||||
The hosted runtime lives in `apps/leaf` (see `src/mcp/http.ts`) and exposes two
|
||||
Streamable HTTP MCP routes:
|
||||
|
||||
- `/mcp` - public, API-shaped operational tools.
|
||||
- `/internal/mcp` - internal Autumn agent tool.
|
||||
@@ -71,5 +71,5 @@ OAuth uses the Autumn Better Auth issuer from `MCP_SERVER_URL`:
|
||||
For production-like local testing:
|
||||
|
||||
```sh
|
||||
MCP_SERVER_URL=https://api.useautumn.com bun -F @autumn/mcp-server start
|
||||
MCP_SERVER_URL=https://api.useautumn.com bun -F @autumn/leaf start
|
||||
```
|
||||
|
||||
@@ -169,8 +169,8 @@ async function startDev() {
|
||||
console.log(` vite: http://localhost:${VITE_PORT}`);
|
||||
console.log(` server: http://localhost:${SERVER_PORT}`);
|
||||
console.log(` checkout: http://localhost:${CHECKOUT_PORT}`);
|
||||
console.log(` mcp: http://localhost:${MCP_PORT}/mcp`);
|
||||
console.log(` chat: http://localhost:${CHAT_PORT}/health\n`);
|
||||
console.log(` leaf: http://localhost:${CHAT_PORT}/health`);
|
||||
console.log(` mcp: http://localhost:${CHAT_PORT}/mcp\n`);
|
||||
|
||||
// Use cmd on Windows, sh on Unix
|
||||
const isWindows = process.platform === "win32";
|
||||
@@ -239,17 +239,12 @@ async function startDev() {
|
||||
: `"cd apps/checkout && VITE_PORT=${CHECKOUT_PORT} bun dev"`,
|
||||
);
|
||||
|
||||
names.push("mcp");
|
||||
colors.push("white");
|
||||
const mcpServeCmd = "bun --watch apps/mcp-server/src/index.ts";
|
||||
cmds.push(isWindows ? `"${mcpServeCmd}"` : `"${mcpServeCmd}"`);
|
||||
|
||||
names.push("chat");
|
||||
names.push("leaf");
|
||||
colors.push("gray");
|
||||
cmds.push(
|
||||
isWindows
|
||||
? `"cd apps/chat && set PORT=${CHAT_PORT} && bun dev"`
|
||||
: `"cd apps/chat && PORT=${CHAT_PORT} bun dev"`,
|
||||
? `"cd apps/leaf && set PORT=${CHAT_PORT} && bun dev"`
|
||||
: `"cd apps/leaf && PORT=${CHAT_PORT} bun dev"`,
|
||||
);
|
||||
|
||||
// Stripe CLI webhook tunnel — silently skip if CLI absent.
|
||||
@@ -296,14 +291,13 @@ async function startDev() {
|
||||
CHECKOUT_PORT: CHECKOUT_PORT.toString(),
|
||||
MCP_PORT: MCP_PORT.toString(),
|
||||
CHAT_PORT: CHAT_PORT.toString(),
|
||||
MCP_DEBUG_PENDING_ACTIONS:
|
||||
process.env.MCP_DEBUG_PENDING_ACTIONS ?? "1",
|
||||
MCP_DEBUG_PENDING_ACTIONS: process.env.MCP_DEBUG_PENDING_ACTIONS ?? "1",
|
||||
MCP_SERVER_URL:
|
||||
process.env.MCP_SERVER_URL ?? `http://localhost:${SERVER_PORT}`,
|
||||
MCP_RESOURCE_URLS:
|
||||
process.env.MCP_RESOURCE_URLS ?? `http://localhost:${MCP_PORT}/mcp`,
|
||||
process.env.MCP_RESOURCE_URLS ?? `http://localhost:${CHAT_PORT}/mcp`,
|
||||
AUTUMN_MCP_URL:
|
||||
process.env.AUTUMN_MCP_URL ?? `http://localhost:${MCP_PORT}/mcp`,
|
||||
process.env.AUTUMN_MCP_URL ?? `http://localhost:${CHAT_PORT}/mcp`,
|
||||
AUTUMN_API_URL: process.env.AUTUMN_API_URL ?? LOCAL_SERVER_URL,
|
||||
CHAT_URL: process.env.CHAT_URL ?? LOCAL_CHAT_URL,
|
||||
CHAT_INTERNAL_URL: process.env.CHAT_INTERNAL_URL ?? LOCAL_CHAT_URL,
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { join } from "node:path";
|
||||
|
||||
const port = process.env.MCP_PORT ?? "2718";
|
||||
const serverUrl = process.env.MCP_SERVER_URL ?? "http://localhost:8080";
|
||||
|
||||
const child = Bun.spawn([
|
||||
"bun",
|
||||
"--watch",
|
||||
"apps/mcp-server/src/index.ts",
|
||||
], {
|
||||
cwd: join(import.meta.dir, ".."),
|
||||
env: {
|
||||
...process.env,
|
||||
MCP_DEBUG_PENDING_ACTIONS: process.env.MCP_DEBUG_PENDING_ACTIONS ?? "1",
|
||||
MCP_PORT: port,
|
||||
MCP_SERVER_URL: serverUrl,
|
||||
},
|
||||
stdin: "inherit",
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
});
|
||||
|
||||
process.exit(await child.exited);
|
||||
@@ -20,8 +20,7 @@
|
||||
"start": "bun src/index.ts",
|
||||
"workers": "bun src/workers.ts",
|
||||
"cron": "bun src/cron.ts",
|
||||
"mcp": "bun ../apps/mcp-server/src/index.ts",
|
||||
"chat": "bun ../apps/chat/src/index.ts",
|
||||
"leaf": "bun ../apps/leaf/src/index.ts",
|
||||
"check": "bun src/check.ts",
|
||||
"t": "cd ../ && bun t $* && cd ./server",
|
||||
"parallel-tests": "ENV_FILE=.env infisical run --env=dev --recursive -- bun tests/testRunner/runParallelGroupsV3.ts",
|
||||
|
||||
Reference in New Issue
Block a user