Anthropic & OpenAI APIs, MCP SDKs, curl
Use Forkmate from your own code
Forkmate is a standard remote MCP server, so anything that speaks MCP can use it. Your code authenticates with a personal key you make in Forkmate’s settings, sent as a Bearer header. Listing the tools is open; every tool call acts on the diary of the account that made the key.
Needs a key. Developers runs on your computer, so it connects with a personal key instead of a sign-in. Make a key in Forkmate · How keys work
No Forkmate account yet? Create one free first. It takes under a minute. You make your key there.
Set up Forkmate in Developers
https://mcp.forkmate.ai/- Make a keyIn Forkmate, open Settings → Keys for local apps (
https://app.forkmate.ai/#keys), name the key after your script, pick when it expires and click Make key. Copy it: Forkmate shows it once. How keys work: forkmate.ai/connect/keys/. - Send it as a Bearer headerEvery request carries
Authorization: Bearer fmk_…. Keep the key in an environment variable such as FORKMATE_KEY, never in your code or your repo. The examples below read it from there. - Call the toolsList the tools, then call log_meal, get_day, search_foods and the rest. Each call acts on the key owner’s diary only.
- Using a hosted API? Pass the keyThe Anthropic and OpenAI APIs call Forkmate from their own servers. Give them the key as the MCP server’s authorization token on each request.
Python, official MCP SDK (mcp 2.2)
# pip install "mcp>=2.2"
import asyncio, os
import httpx2
from mcp import Client
from mcp.client.streamable_http import streamable_http_client
SERVER = "https://mcp.forkmate.ai/"
KEY = os.environ["FORKMATE_KEY"] # fmk_…, from Settings → Keys for local apps
async def main():
async with httpx2.AsyncClient(headers={"Authorization": f"Bearer {KEY}"}) as http:
async with Client(streamable_http_client(SERVER, http_client=http)) as client:
tools = await client.list_tools()
print([t.name for t in tools.tools])
print((await client.call_tool("get_day", {})).content)
asyncio.run(main())TypeScript, official MCP SDK (@modelcontextprotocol/client 2.2)
// npm i @modelcontextprotocol/client (Node 20+, an ES module: save as forkmate.mts)
import { Client, StreamableHTTPClientTransport, type AuthProvider } from "@modelcontextprotocol/client";
// fmk_…, from Settings → Keys for local apps. The SDK sends it as Authorization: Bearer.
const authProvider: AuthProvider = { token: async () => process.env.FORKMATE_KEY! };
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://mcp.forkmate.ai/"), { authProvider }));
try {
console.log((await client.listTools()).tools.map((t) => t.name));
console.log((await client.callTool({ name: "get_day", arguments: {} })).content);
} finally {
await client.close();
}Run it with npx tsx forkmate.mts. Written for SDK v2; the v1 package (@modelcontextprotocol/sdk) passes headers through requestInit instead.
Go, official SDK (github.com/modelcontextprotocol/go-sdk v1.8)
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
// bearer adds the Forkmate key to every request.
type bearer struct{ key string }
func (b bearer) RoundTrip(r *http.Request) (*http.Response, error) {
r = r.Clone(r.Context())
r.Header.Set("Authorization", "Bearer "+b.key)
return http.DefaultTransport.RoundTrip(r)
}
func main() {
ctx := context.Background()
transport := &mcp.StreamableClientTransport{
Endpoint: "https://mcp.forkmate.ai/",
HTTPClient: &http.Client{Transport: bearer{os.Getenv("FORKMATE_KEY")}},
}
client := mcp.NewClient(&mcp.Implementation{Name: "my-app", Version: "v1.0.0"}, nil)
session, err := client.Connect(ctx, transport, nil)
if err != nil {
log.Fatal(err)
}
defer session.Close()
tools, err := session.ListTools(ctx, nil)
if err != nil {
log.Fatal(err)
}
for _, t := range tools.Tools {
fmt.Println(t.Name)
}
res, err := session.CallTool(ctx, &mcp.CallToolParams{Name: "get_day", Arguments: map[string]any{}})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Content)
}Anthropic API, MCP connector (Python, anthropic 1.11)
import os
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
betas=["mcp-client-2025-11-20"],
mcp_servers=[{
"type": "url",
"url": "https://mcp.forkmate.ai/",
"name": "forkmate",
"authorization_token": os.environ["FORKMATE_KEY"],
}],
tools=[{"type": "mcp_toolset", "mcp_server_name": "forkmate"}],
messages=[{"role": "user", "content": "Log 2 eggs and a slice of toast for breakfast."}],
)
print(response.content)Pass the raw key, without “Bearer ”. Every server in mcp_servers needs exactly one mcp_toolset entry in tools.
OpenAI Responses API, remote MCP tool (Python, openai 3.22)
import os
from openai import OpenAI
client = OpenAI()
resp = client.responses.create(
model="gpt-6-astra",
input="What did I eat today?",
tools=[{
"type": "mcp",
"server_label": "forkmate",
"server_url": "https://mcp.forkmate.ai/",
"authorization": os.environ["FORKMATE_KEY"],
"require_approval": "never",
}],
)
print(resp.output_text)OpenAI doesn’t store the authorization value, so send it on every request.
curl: list the tools, then call one with your key
curl -s https://mcp.forkmate.ai/ \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-06-18" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s https://mcp.forkmate.ai/ \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "Authorization: Bearer $FORKMATE_KEY" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"whoami","arguments":{}}}'The server is stateless: it sends no Mcp-Session-Id, and answers in plain JSON. Without a key, a tool call gets a 401.
What you need
- A free Forkmate account (sign up). There is no paid plan.
- Every tool call needs a personal key from Settings → Keys for local apps, sent as Authorization: Bearer fmk_…. A key acts on its owner’s diary only, until it expires or is revoked.
- Logging a meal needs the key owner’s one-time health-data consent. Until then log_meal and update_meal return “Nothing was saved” with the consent summary: the owner agrees in the chat (give_consent, with their own words) or in the web app, and a refused log_meal is kept for 30 minutes and saved when they agree.
- Writes are limited to 60 a minute per user, and requests with a key to 120 a minute per IP address.
Checked against these sources: MCP Python SDK: streamable HTTP client, MCP TypeScript SDK: bring your own bearer token, MCP Go SDK: StreamableClientTransport, Anthropic: MCP connector, OpenAI: MCP and connectors. SDKs move fast; check the version you install.
What to say first
Your users talk to your app the way they’d tell a friend:
- “Log 2 eggs and a slice of toast for breakfast.”
- “How many calories have I had today?”
- “Make the toast two slices.”
- “What did I eat this week?”
It logs the meal with calories, protein, carbs and fat to your diary at app.forkmate.ai.
Build on a free food diary
Create your free account, connect once, and your next meal is one sentence away. No card, no paid plan.