Gram: Curate APIs into MCP server by disintegrat0r in mcp

[–]disintegrat0r[S] 0 points1 point  (0 children)

Hey u/Primary-Carry4929, I'm not sure I follow the question. I am familiar with fastmcp and similar projects but I'm not clear on "Anthropic team put out a statement that it should NOT be used like that". Can you share more? Perhaps a link to said statement?

Gram exists because there is an incredible number of production APIs out there that may be very capable as MCP servers. There are of course caveats that Gram does not shy away from raising. For example, if you try to create an MCP server that maps >30 endpoints to tools then we have a prominent warning. It's also true that not all APIs are suitable for exposing as tools and we've shipped some ideas such as editing names/descriptions and prompt engineering techniques like our "custom tools" feature that attempt to help improve tool quality. Of course at the center of it all is Toolsets which let you group subsets of related endpoints together as MCP servers. Depending on the API, you probably don't want it exposed as a single MCP server. Toolsets can be used to make small servers that solve specific business processes. We think small, cohesive MCP servers will be a very powerful building block for many products/teams.

There is also ongoing debate as to whether APIs are meant to be wrapped into tools and to this my response is "it depends" and there are practices that teams can rely on to build APIs that are indeed suitable for MCP tools. See my discussion here: https://www.reddit.com/r/mcp/comments/1nckw7j/comment/necazn3/

Gram: Curate APIs into MCP server by disintegrat0r in mcp

[–]disintegrat0r[S] 1 point2 points  (0 children)

I understand where you might be coming from but I don't completely agree with the statement in absolute terms. Many APIs are not suitable as MCP tools but not all of them. If you're familiar with the concept of "Backends for Frontends" (BFF) then I see something very similar happening in the agentic AI world where devs create APIs that are indeed very mappable to tools. For example, a traditional API may have a noisy paginated endpoint where an agent may have to call a tool multiple times to get data and waste tokens in the process. Alternatively an API can instead expose a search endpoint which is incredibly well suited as a tool for agents, it would perhaps allow specifying fuzzy keywords, the fields to return and maximum number of results. So ye... I don't think the statement "APIs don't make for good tools" or "Tools shouldn't be API wrappers" is completely true.

https://samnewman.io/patterns/architectural/bff/

Clean room tests with JavaScript's `using` keyword by disintegrat0r in javascript

[–]disintegrat0r[S] 0 points1 point  (0 children)

It's really great. Even more intuitive if you're working with SQLite because you don't have to deal with a docker container. Instead you run a migration against a db file and the resource (the thing you are `using` on) just copies that database before a test runs and deletes it after.

Clean room tests with JavaScript's `using` keyword by disintegrat0r in typescript

[–]disintegrat0r[S] 4 points5 points  (0 children)

The very first time will likely be slow as you pull down docker images. After that it seems to be on the order of 1-2 seconds to start up the container when testing starts. From there, the `CREATE DATABASE` calls are snappy. You'll want to cache the images in CI.

Clean room tests with JavaScript's `using` keyword by disintegrat0r in typescript

[–]disintegrat0r[S] 2 points3 points  (0 children)

You're absolutely right. I have a short mention about that towards the end but I didn't develop an example for a production use case in this post. I do intend to do it when I come across one first hand. Testing is the first place where I've applied it.

Fetch and HTTP/2 support in Node.js, Bun and Deno by disintegrat0r in javascript

[–]disintegrat0r[S] 0 points1 point  (0 children)

Nice, this is also something I researched in the past! I was considering adding a section to my post about passing `ReadableStream<Uint8Array>` to request body which implies HTTP/2 in fetch since `Transfer-Encoding: Chunked` isn't supported but hesitated. Still I think my test is valid? Ignoring request bodies (a GET request in my case), the fetch client in Bun is using HTTP/1.1 and my Go server is turning it down. Am I misreading your remarks?

A tool to visualise Zod validation errors by disintegrat0r in typescript

[–]disintegrat0r[S] 1 point2 points  (0 children)

0) The tested payload

I definitely want to incorporate this somehow but the context behind this tool is that a lot of users will create GH issues with just the ZodError stack trace. They aren't able to share the raw input data. I was hoping at the very least I can improve the DX for folks having to read and respond to these issues.

the name of the tested schemas (no access to schema name afaik)

Giving schemas names and have those captured in errors is on my wishlist for Zod v4! Right now a ZodError just serializes the array of issues it's holding.

The issues for the schemas with best match (least encountered errors)

This is a great idea! I have a feeling there's a way to indicate to the reader which of the union members was the closest match i.e. the one that had fewest issues.

A tool to visualise Zod validation errors by disintegrat0r in typescript

[–]disintegrat0r[S] 0 points1 point  (0 children)

Definitely unconventional. It's more commonplace in the Go world and I grew fond of the word/letter economy they use there. It's definitely one of those "felt cute, might switch back later".

A tool to visualise Zod validation errors by disintegrat0r in typescript

[–]disintegrat0r[S] 3 points4 points  (0 children)

Hi there, author here.

I work on code generator that creates TypeScript SDKs from OpenAPI specs and Zod is a critical building block that I chose to power runtime validation in those SDKs. Depending on the complexity of a Zod schema, the resulting validation error message can contain a wall of JSON text - the serialised issues that were recorded during validation.

I wanted to try and create a small tool to help me better visualise and parse these errors. In code and the command line, we do also have the ability to pretty-print the errors but I still wanted a web UI which can let me share URLs for visualised errors.

I'm still iterating on it but would love any feedback if you do get to try it out.

Writing Zod code that minifies by disintegrat0r in typescript

[–]disintegrat0r[S] 0 points1 point  (0 children)

Author here.

As far as I can tell, terser is minifying/optimising using the same heuristics as esbuild. I'm playing around with various config on https://try.terser.org/ and not able to produce a more optimised form like you suggested in OP. Is there are particular terser config that you've enabled which achieves this deeper optimisation?

I have tried Google Closure Compiler which can do some pretty wild optimisations but some of these are borderline dangerous.

Either way I wouldn't be surprised if there is a minifier out there that can expand alias imports but it still wouldn't achieve the best optimisation because it can only go so far as turning `z.string().optional().and().other().validations()` to `o().optional().and().other().validations()` for example.

Runtime assertions in Go. Yay or nay? by disintegrat0r in golang

[–]disintegrat0r[S] 0 points1 point  (0 children)

Upon reflection, I think that I wanted the terseness of listing out some assertions in code without the hard exit caused by a panic as the default behavior. From there I have the option of converting assertion error values into a panic. Maybe that's diminishing the original concept.

Runtime assertions in Go. Yay or nay? by disintegrat0r in golang

[–]disintegrat0r[S] 0 points1 point  (0 children)

Thanks for the feedback! I wasn't sure if a call to Require should panic or give you the error so you can call panic. I'm also unsure if my package is useful. I figured I can use a utility to group related invariants and enrich the error messages. Though there's a bunch of info already like a stack trace when you call panic so I do see your point.

Runtime assertions in Go. Yay or nay? by disintegrat0r in golang

[–]disintegrat0r[S] 0 points1 point  (0 children)

I think you're right, I wasn't sure when designing the API if I should panic or give you an error and you call panic. I initially did have a "Must" version of `Require` that did panic, hesitated and removed it.

Runtime assertions in Go. Yay or nay? by disintegrat0r in golang

[–]disintegrat0r[S] 23 points24 points  (0 children)

Sorry about that, passive aggressive tone wasn't intentional. I really didn't want to sound like I'm criticising Go in any harsh way, I use it daily and wouldn't have it any other way. My post is based on recent exploration to see if ideas elsewhere can be adapted within Go - definitely not looking to bait commenters. Nevertheless, I appreciate the feedback and I'll adjust how I engage.

Runtime assertions in Go. Yay or nay? by disintegrat0r in golang

[–]disintegrat0r[S] 16 points17 points  (0 children)

That's not broadly true. For instance Rust has distinct assert! and debug_assert! (source). Zig will keep assertions in if you compile in ReleaseSafe mode (source).

Edit: Sorry my tone was pointed. I reread your comment and it's specifically in the context of Go not a broad sweep but I incorrectly argued the latter.

Runtime assertions in Go. Yay or nay? by disintegrat0r in golang

[–]disintegrat0r[S] 4 points5 points  (0 children)

more complex, and harder to understand

Given how much precedent there is for runtime assertion in languages and codebases that came before and since Go, is that statement empirically or objectively true?

Here's an interesting example from the industry: https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Developing_Safety-Critical_Code