Skip to content

Custom MCP Servers

Build custom integrations for Futurity using the Model Context Protocol (MCP). MCP allows you to create tools that Corint can use to interact with any external service.

MCP (Model Context Protocol) is a standardized way to:

  • Expose tools to AI assistants
  • Provide resources and data
  • Handle authentication
  • Manage sessions

When you build an MCP server, Corint can use your custom tools just like built-in capabilities.

Build MCP servers to:

  • Connect proprietary systems: Internal APIs, databases, services
  • Extend capabilities: Custom tools specific to your domain
  • Integrate third-party services: Any API that doesn’t have native integration
  • Automate workflows: Complex operations as single tools

Futurity provides futurity-mcp, a minimal MCP server library for Bun.

Terminal window
bun add futurity-mcp
import { z } from "zod";
import { mcp } from "futurity-mcp";
const app = mcp({
name: "my-server",
version: "1.0.0",
});
app.tool("greet", {
description: "Greet a user",
input: z.object({
name: z.string(),
}),
handler: async ({ name }) => {
return { message: `Hello, ${name}!` };
},
});
app.listen(3000);
3000/mcp
bun run server.ts
app.tool("add", {
description: "Add two numbers",
input: z.object({
a: z.number(),
b: z.number(),
}),
handler: async ({ a, b }) => {
return { sum: a + b };
},
});
app.tool("ping", {
description: "Health check",
handler: async () => {
return { status: "ok" };
},
});

Good descriptions help Corint understand when to use your tool:

app.tool("search_customers", {
description: `Search for customers by name or email.
Use this when the user asks to find a customer
or look up customer information.`,
input: z.object({
query: z.string().describe("Name or email to search for"),
limit: z.number().default(10).describe("Maximum results"),
}),
handler: async ({ query, limit }) => {
// ... implementation
},
});

Resources provide data that Corint can access:

app.resource("config://settings", {
description: "Application settings",
fetch: async () => {
return { theme: "dark", language: "en" };
},
});

Configure OAuth for user authentication:

const app = mcp({
name: "server",
version: "1.0.0",
oauth: {
issuer: "https://auth.example.com",
authorizationEndpoint: "https://auth.example.com/oauth/authorize",
tokenEndpoint: "https://auth.example.com/oauth/token",
jwksUri: "https://auth.example.com/.well-known/jwks.json",
scopesSupported: ["openid", "profile"],
},
});
const app = mcp({
name: "server",
version: "1.0.0",
auth: async (req) => {
const token = req.headers.get("authorization")?.replace("Bearer ", "");
if (!token) return false;
return await validateToken(token);
},
});
app.middleware(async (req, next) => {
console.log(`${req.method} ${req.url}`);
return next(req);
});
import { cors } from "futurity-mcp";
app.use(
cors({
allowOrigin: "*",
allowMethods: ["GET", "POST", "DELETE", "OPTIONS"],
allowHeaders: ["Content-Type", "Authorization", "Accept", "Mcp-Session-Id"],
exposeHeaders: ["Mcp-Session-Id"],
maxAge: 86400,
})
);
await app.listen(3000);
await app.listen(3000, "websocket");

Maintain state across requests:

const state = {
counter: 0,
items: new Map<string, string>(),
};
app.tool("increment", {
handler: async () => {
state.counter++;
return { counter: state.counter };
},
});
app.tool("set", {
input: z.object({ key: z.string(), value: z.string() }),
handler: async ({ key, value }) => {
state.items.set(key, value);
return { key, value };
},
});
app.tool("get", {
input: z.object({ key: z.string() }),
handler: async ({ key }) => {
return { value: state.items.get(key) ?? null };
},
});

The HTTP transport supports multiple concurrent client sessions:

const app = mcp({ name: "server", version: "1.0.0" });
app.tool("example", { handler: async () => ({ ok: true }) });
await app.listen(3000);
// Check active sessions
console.log(app.activeSessions);
// Stop server
await app.stop();
  1. Deploy your MCP server to a publicly accessible URL
  2. Ensure HTTPS is configured
  3. Contact support with your server URL and configuration
  4. We’ll validate and enable the integration

Test your MCP server before deploying:

Terminal window
bun run discover http://localhost:3000/mcp
  1. Single responsibility: Each tool does one thing well
  2. Clear descriptions: Help Corint understand when to use it
  3. Validate inputs: Use Zod schemas for type safety
  4. Handle errors: Return meaningful error messages
  1. Authenticate all requests: Don’t expose unprotected endpoints
  2. Validate tokens: Check signatures and expiration
  3. Rate limit: Prevent abuse
  4. Log access: Maintain audit trails
  1. Keep tools fast: Under 30 seconds ideally
  2. Cache when possible: Reduce external API calls
  3. Handle timeouts: Set reasonable timeouts for external calls

Find example MCP servers in the repository:

Terminal window
bun examples/cors.ts # CORS configuration
bun examples/oauth.ts # OAuth metadata
bun examples/stateful.ts # Counter, notes, key-value store
bun examples/todo-app.ts # Todo list with CRUD and filtering
bun examples/calculator.ts # Math operations and unit conversion
bun examples/filesystem.ts # Virtual filesystem
bun examples/weather-api.ts # Weather data API
bun examples/database.ts # Document database
bun examples/monday.ts # monday.com integration