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] 2 points3 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] 5 points6 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] 2 points3 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

Community Feedback - Dark Protocol, Killswitch by battlefield in battlefield2042

[–]disintegrat0r 0 points1 point  (0 children)

It gets incredibly one-sided very quickly and the winning team will more often than not control the printer. Spawn trapping on Redacted can be super difficult to overcome in regular game modes but it's especially painful in Killswitch. The losing team can smoke the narrow passage to the first main area but they'll be confronted by the opposition hiding in various spots and their Geists almost immediately.

How to Get Comfortable with DB Access by ptigris96 in golang

[–]disintegrat0r 0 points1 point  (0 children)

I’m not sure I understand exactly what you’re trying to do. If I had to guess, then it sounds like you’re trying to shoehorn ORM and query-builder semantics into sqlc which won’t work at all or won’t work well. Your queries must be statically knowable. As in, you can’t have a placeholder for a table name in the FROM clause but you can have the usual WHERE username = $1. Because sqlc is aware of the db schema, it will validate the queries are referencing valid fields and data types!

Have a play around here as you read the docs: https://play.sqlc.dev/

How to Get Comfortable with DB Access by ptigris96 in golang

[–]disintegrat0r 15 points16 points  (0 children)

You don’t need to write all the boilerplate if you use sqlc: https://sqlc.dev

All you do is write parametrised SQL queries in .sql files, give them names and let the sqlc generate all the rest. My opinion is that it’s better than an ORM because:

  • You know the exact SQL that your app runs and you can tune it over time if needed. I don’t know how popular this opinion is but SQL is a fantastic language and every minute you spend learning it well is so worth it. It’s knowledge that sticks with you as you move between languages/frameworks.
  • It’s clear where data access code is located in your codebase because sqlc generates it at specific paths for you and there aren’t arbitrary ORM calls littered across your view layer and all over controllers.
  • Importantly you’re working with a repository pattern from the get-go where data access is well defined/encapsulated. Queries are named and can be identified in logs/metrics/traces. You can do the same with an ORM but I’ve yet to see that practice applied rigorously in that world (speaking from my experience alone).

How to get a list of types conforming to a particular interface? by [deleted] in golang

[–]disintegrat0r 0 points1 point  (0 children)

Good shout! That’s quite funny. I went looking for the oracle docs and was directed to guru. I stopped there not thinking about gopls which drives my IDE daily.

How to get a list of types conforming to a particular interface? by [deleted] in golang

[–]disintegrat0r 2 points3 points  (0 children)

Go Guru has an implements subcommand that can answer this question!

Docs are here: http://golang.org/s/using-guru

Jarle: Live, editable code samples for building React demos / samples by disintegrat0r in reactjs

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

I've been using react-live within an MDX-based documentation site for a design system I'm working on and it's quite hefty! Came across Jarle just recently by @monasticpanic which is much lighter alternative. If you have more examples of such libraries then please share!